libkni3/kni-3.9.2-ctor.patch

438 lines
10 KiB
Diff

diff -urN KNI_3.9.2/include/KNI/cdlCOM.h KNI_3.9.2.ctor/include/KNI/cdlCOM.h
--- KNI_3.9.2/include/KNI/cdlCOM.h 2007-04-12 14:52:06.000000000 +0200
+++ KNI_3.9.2.ctor/include/KNI/cdlCOM.h 2009-06-12 16:44:42.000000000 +0200
@@ -107,7 +107,7 @@
* describes the desired serial port. An attempt to open a connection
* to the desired device will be tried.
*/
- CCdlCOM(TCdlCOMDesc ccd);
+ CCdlCOM(TCdlCOMDesc ccd, const char *dev_name = 0);
/*! \brief Destructs the class
*/ virtual ~CCdlCOM();
diff -urN KNI_3.9.2/src/Base/cdlCOM.cpp KNI_3.9.2.ctor/src/Base/cdlCOM.cpp
--- KNI_3.9.2/src/Base/cdlCOM.cpp 2009-06-12 16:44:03.000000000 +0200
+++ KNI_3.9.2.ctor/src/Base/cdlCOM.cpp 2009-06-12 16:45:02.000000000 +0200
@@ -23,8 +23,9 @@
#include "common/Timer.h"
#include <cstring>
+#include <cstdio>
-
+#include <cstdlib>
#ifdef WIN32
CCdlCOM::CCdlCOM(TCdlCOMDesc ccd) : _deviceName(""), _ccd(), _prtHdl(INVALID_HANDLE_VALUE), _oto() {
@@ -160,21 +161,24 @@
#else //LINUX
-CCdlCOM::CCdlCOM(TCdlCOMDesc ccd) : _deviceName(""), _ccd(), _prtHdl(-1), _oto() {
+CCdlCOM::CCdlCOM(TCdlCOMDesc ccd, const char *dev_name) : _deviceName(""), _ccd(), _prtHdl(-1), _oto() {
int prtHdl = -1;
- std::string deviceName;
struct termios nto, oto;
- char name[11];
+ char *name;
errno = 0;
- strncpy(name, "/dev/ttyS ", 11);
- name[9] = digit(ccd.port);
+ if (dev_name) {
+ name = strdup(dev_name);
+ } else {
+ asprintf(&name, "/dev/ttyS%i", ccd.port);
+ }
prtHdl = ::open(name, O_RDWR | O_NOCTTY | O_NDELAY| O_NONBLOCK);
_deviceName = name;
+ free(name);
if (prtHdl < 0) {
throw CannotOpenPortException(_deviceName, strerror(errno));
@@ -290,7 +294,6 @@
}
_prtHdl = prtHdl;
- _deviceName = deviceName;
_ccd = ccd;
_oto = oto;
}
diff -urN KNI_3.9.2/src/Base/cdlCOM.cpp.orig KNI_3.9.2.ctor/src/Base/cdlCOM.cpp.orig
--- KNI_3.9.2/src/Base/cdlCOM.cpp.orig 1970-01-01 01:00:00.000000000 +0100
+++ KNI_3.9.2.ctor/src/Base/cdlCOM.cpp.orig 2009-06-12 16:44:42.000000000 +0200
@@ -0,0 +1,369 @@
+/*
+ * Katana Native Interface - A C++ interface to the robot arm Katana.
+ * Copyright (C) 2005 Neuronics AG
+ * Check out the AUTHORS file for detailed contact information.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "KNI/cdlCOM.h"
+
+#include "common/Timer.h"
+#include <cstring>
+
+
+#ifdef WIN32
+
+CCdlCOM::CCdlCOM(TCdlCOMDesc ccd) : _deviceName(""), _ccd(), _prtHdl(INVALID_HANDLE_VALUE), _oto() {
+
+ DCB commDCB; //COM port parameters
+ COMMTIMEOUTS nto; //new timeouts
+ char comX[5];
+ char dcb[35];
+ int i, d;
+
+ std::string deviceName;
+ HANDLE prtHdl;
+ COMMTIMEOUTS oto;
+
+ strncpy_s(comX, "COM ", 5);
+ comX[3] = digit(ccd.port);
+ deviceName = comX;
+ prtHdl = CreateFile(comX,
+ GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, 0
+ );
+
+ if (prtHdl == INVALID_HANDLE_VALUE) {
+ throw CannotOpenPortException(_deviceName, "info from win32-system not yet available");
+ }
+
+ FillMemory(&commDCB, sizeof(commDCB), 0);
+ commDCB.DCBlength = sizeof(commDCB);
+ strncpy_s(dcb, "baud= parity= data= stop= ", 35);
+ for(i=5,d=100000; d>=1; d=d/10) {
+ if(d <= ccd.baud) {
+ dcb[i++] = digit((ccd.baud/d) % 10);
+ }
+ }
+ dcb[19] = ccd.parity;
+ dcb[26] = digit(ccd.data);
+ dcb[33] = digit(ccd.stop);
+ if (!BuildCommDCB(dcb, &commDCB)) {
+ CloseHandle(prtHdl);
+ throw CannotGetSetPortAttributesException(_deviceName);
+ }
+
+ commDCB.fAbortOnError = false;
+ commDCB.fInX = false;
+ commDCB.fOutX = false;
+ commDCB.fOutxCtsFlow = false;
+ if (!SetCommState(prtHdl, &commDCB)) {
+ CloseHandle(prtHdl);
+ throw CannotGetSetPortAttributesException(_deviceName);
+ }
+
+ PurgeComm( prtHdl, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+
+ GetCommTimeouts(prtHdl, &oto);
+ nto.ReadIntervalTimeout = MAXDWORD;
+ nto.ReadTotalTimeoutMultiplier = 0;
+ nto.ReadTotalTimeoutConstant = 0;
+ nto.WriteTotalTimeoutMultiplier = 0;
+ nto.WriteTotalTimeoutConstant = 0;
+ if (!SetCommTimeouts(prtHdl, &nto)) {
+ CloseHandle(prtHdl);
+ throw CannotGetSetPortAttributesException(_deviceName);
+ }
+
+ // Everything done, now we can change the state
+ _prtHdl = prtHdl;
+ _deviceName = deviceName;
+ _ccd = ccd;
+ _oto = oto;
+}
+
+CCdlCOM::~CCdlCOM() {
+ if(_prtHdl == INVALID_HANDLE_VALUE)
+ return;
+
+ FlushFileBuffers(_prtHdl);
+ SetCommTimeouts(_prtHdl, &_oto);
+
+ CloseHandle(_prtHdl);
+
+}
+
+int CCdlCOM::send(const void* buf, int size) {
+
+ if (_prtHdl == INVALID_HANDLE_VALUE) {
+ throw PortNotOpenException(_deviceName);
+ }
+
+ if(PurgeComm(_prtHdl, PURGE_TXABORT | PURGE_TXCLEAR) == 0) {
+ throw DeviceWriteException(_deviceName, "PurgeComm failed");
+ }
+
+ unsigned long readsz;
+ if (WriteFile(_prtHdl, buf, size, &readsz, 0) == 0) {
+ throw DeviceWriteException(_deviceName, "WriteFile failed");
+ }
+
+ if(readsz != static_cast<long>(size)) {
+ throw WriteNotCompleteException(_deviceName);
+ }
+
+ return (int)readsz;
+}
+
+int CCdlCOM::recv(void* buf, int size) {
+
+ if (_prtHdl == INVALID_HANDLE_VALUE) {
+ throw PortNotOpenException(_deviceName);
+ }
+
+ unsigned char* tmp = static_cast<unsigned char*>(buf);
+ unsigned long readsz = 0, readsz_temp = 0;
+ KNI::Timer timeout(_ccd.rttc);
+ timeout.Start();
+ while (readsz<(unsigned long)size && !timeout.Elapsed()) {
+ if(ReadFile(_prtHdl, &tmp[readsz], size, &readsz_temp, 0) == 0) {
+ DeviceReadException( _deviceName, "ReadFile failed" );
+ } else {
+ readsz += readsz_temp;
+ }
+ }
+
+ if((unsigned)size != readsz) {
+ throw ReadNotCompleteException(_deviceName);
+ }
+
+ if(PurgeComm(_prtHdl, PURGE_RXABORT | PURGE_RXCLEAR) == 0) {
+ throw DeviceReadException(_deviceName, "PurgeComm failed");
+ }
+ return (int)readsz;
+}
+
+
+#else //LINUX
+
+CCdlCOM::CCdlCOM(TCdlCOMDesc ccd) : _deviceName(""), _ccd(), _prtHdl(-1), _oto() {
+
+ int prtHdl = -1;
+
+ std::string deviceName;
+ struct termios nto, oto;
+ char name[11];
+
+ errno = 0;
+
+ strncpy(name, "/dev/ttyS ", 11);
+ name[9] = digit(ccd.port);
+ prtHdl = ::open(name, O_RDWR | O_NOCTTY | O_NDELAY| O_NONBLOCK);
+
+ _deviceName = name;
+
+ if (prtHdl < 0) {
+ throw CannotOpenPortException(_deviceName, strerror(errno));
+ }
+
+ tcgetattr(prtHdl, &oto);
+ bzero(&nto, sizeof(nto));
+ nto.c_cc[VTIME] = 0;
+ nto.c_cc[VMIN] = 0;
+ nto.c_oflag = 0;
+ nto.c_lflag = 0;
+ nto.c_cflag = CLOCAL | CREAD;
+ nto.c_iflag = 0;
+
+ switch (ccd.baud) {
+ case 50:
+ nto.c_cflag |= B50;
+ break;
+ case 75:
+ nto.c_cflag |= B75;
+ break;
+ case 110:
+ nto.c_cflag |= B110;
+ break;
+ case 134:
+ nto.c_cflag |= B134;
+ break;
+ case 150:
+ nto.c_cflag |= B150;
+ break;
+ case 200:
+ nto.c_cflag |= B200;
+ break;
+ case 300:
+ nto.c_cflag |= B300;
+ break;
+ case 600:
+ nto.c_cflag |= B600;
+ break;
+ case 1200:
+ nto.c_cflag |= B1200;
+ break;
+ case 1800:
+ nto.c_cflag |= B1800;
+ break;
+ case 2400:
+ nto.c_cflag |= B2400;
+ break;
+ case 4800:
+ nto.c_cflag |= B4800;
+ break;
+ case 9600:
+ nto.c_cflag |= B9600;
+ break;
+ case 19200:
+ nto.c_cflag |= B19200;
+ break;
+ case 38400:
+ nto.c_cflag |= B38400;
+ break;
+ case 57600:
+ nto.c_cflag |= B57600;
+ break;
+ case 115200:
+ nto.c_cflag |= B115200;
+ break;
+ case 230400:
+ nto.c_cflag |= B230400;
+ break;
+ }
+
+ switch (ccd.data) {
+ case 5:
+ nto.c_cflag |= CS5;
+ break;
+ case 6:
+ nto.c_cflag |= CS6;
+ break;
+ case 7:
+ nto.c_cflag |= CS7;
+ break;
+ case 8:
+ nto.c_cflag |= CS8;
+ break;
+ }
+
+ switch (ccd.parity) {
+ case 'N':
+ case 'n':
+ break;
+ case 'O':
+ case 'o':
+ nto.c_cflag |= PARENB | PARODD;
+ break;
+ case 'E':
+ case 'e':
+ nto.c_cflag |= PARENB;
+ break;
+ }
+
+ switch (ccd.stop) {
+ case 1:
+ break;
+ case 2:
+ nto.c_cflag |= CSTOPB;
+ break;
+ }
+
+ tcflush(prtHdl,TCIFLUSH);
+ if (tcsetattr(prtHdl, TCSANOW, &nto) != 0) {
+ ::close(prtHdl);
+ throw CannotGetSetPortAttributesException(_deviceName);
+ }
+
+ _prtHdl = prtHdl;
+ _deviceName = deviceName;
+ _ccd = ccd;
+ _oto = oto;
+}
+
+CCdlCOM::~CCdlCOM() {
+
+ if (_prtHdl < 0) {
+ return;
+ }
+
+ tcflush(_prtHdl, TCIFLUSH);
+ tcsetattr(_prtHdl, TCSANOW, &_oto);
+
+ ::close(_prtHdl); // there's nothing we can do about failing
+
+}
+
+int CCdlCOM::send(const void* buf, int size) {
+
+ if (_prtHdl < 0)
+ throw PortNotOpenException(_deviceName);
+
+ errno = 0;
+
+ int tcflush_return = tcflush(_prtHdl,TCIFLUSH);
+ if(tcflush_return < 0)
+ throw DeviceWriteException( _deviceName, strerror(errno) );
+
+ int writesz = write(_prtHdl, buf, size);
+
+ if(writesz < 0)
+ throw DeviceWriteException( _deviceName, strerror(errno) );
+
+ if(writesz != size)
+ throw WriteNotCompleteException(_deviceName);
+
+ return writesz;
+}
+
+int CCdlCOM::recv(void* buf, int size) {
+ unsigned char* tmp = static_cast<unsigned char*>(buf);
+ register int readsz = 0;
+
+ if (_prtHdl < 0)
+ throw PortNotOpenException(_deviceName);
+
+ errno = 0;
+
+ int read_return;
+ KNI::Timer timeout(_ccd.rttc);
+ timeout.Start();
+ while (readsz<size && !timeout.Elapsed()) {
+ read_return = read(_prtHdl, &tmp[readsz], size-readsz);
+ if(read_return < 0) {
+ if(errno != EAGAIN)
+ throw DeviceReadException( _deviceName, strerror(errno));
+ } else {
+ readsz += read_return;
+ }
+ }
+
+ if (readsz != size)
+ throw ReadNotCompleteException(_deviceName);
+
+ int tcflush_return = tcflush(_prtHdl,TCIFLUSH);
+ if(tcflush_return < 0)
+ throw DeviceReadException( _deviceName, strerror(errno));
+
+ return readsz;
+
+}
+
+
+
+#endif //WIN32 else LINUX
+