Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include <telekyb_serial/ThreadedSerialDevice.hpp>
00009 
00010 #include <ros/ros.h>
00011 
00012 #include <boost/foreach.hpp>
00013 
00014 #define READING_BUFFER_SIZE 256
00015 #define MAIN_BUFFER_SIZE 1024
00016 
00017 namespace TELEKYB_NAMESPACE {
00018 
00019 ThreadedSerialDevice::ThreadedSerialDevice()
00020         : SerialDevice(),
00021           readingThread(NULL),
00022           terminalChars("\r\n")
00023 {
00024 
00025 }
00026 
00027 
00028 ThreadedSerialDevice::ThreadedSerialDevice(const std::string& deviceName_, const std::string& terminalChars_, bool autoOpen, int oflag)
00029         : SerialDevice(deviceName_, autoOpen, oflag),
00030           readingThread(NULL),
00031           terminalChars(terminalChars_)
00032 {
00033 
00034 
00035 
00036 
00037         
00038         if ( isOpen() ) {
00039                 readingThreadStopRequest = false;
00040                 readingThread = new boost::thread(&ThreadedSerialDevice::readingThreadFcn, this);
00041         }
00042 }
00043 
00044 ThreadedSerialDevice::~ThreadedSerialDevice()
00045 {
00046         stopReadingThread();
00047 }
00048 
00049 std::string ThreadedSerialDevice::getTerminalChars() const
00050 {
00051         return terminalChars;
00052 }
00053 
00054 void ThreadedSerialDevice::setTerminalChars(const std::string& terminalChars_)
00055 {
00056         terminalChars = terminalChars_;
00057 }
00058 
00059 void ThreadedSerialDevice::readingThreadFcn()
00060 {
00061         
00062         
00063         std::vector<char> buffer;
00064         buffer.reserve(MAIN_BUFFER_SIZE);
00065         
00066         
00067         int bufferPosition = 0;
00068         char readingBuffer[READING_BUFFER_SIZE];
00069 
00070         
00071         timeval selectTimeOut;
00072         selectTimeOut.tv_sec = 1;
00073         selectTimeOut.tv_usec = 0;
00074 
00075         while(!readingThreadStopRequest && ros::ok()) {
00076                 
00077                 
00078 
00079                 size_t nBytesRead = 0;
00080                 if (readAvailable(selectTimeOut)) {
00081                         nBytesRead = readDevice(readingBuffer, READING_BUFFER_SIZE, terminalChars);
00082                 }
00083 
00084 
00085 
00086                 if (nBytesRead > 0) {
00087 
00088 
00089 
00090                         
00091                         for (unsigned int i = 0; i < nBytesRead; i++) {
00092                                 
00093                                 buffer.push_back(readingBuffer[i]);
00094                                 bufferPosition++;
00095 
00096 
00097 
00098                                 if (terminalChars.find(readingBuffer[i]) != terminalChars.npos) {
00099                                         
00100                                         
00101 
00102                                         
00103                                         std::vector<char> dataVector(bufferPosition);
00104                                         memcpy(&dataVector[0], &buffer[0], bufferPosition);
00105 
00106                                         
00107 
00108                                         
00109                                         informListeners(dataVector);
00110 
00111                                         
00112 
00113                                         
00114                                         bufferPosition = 0;
00115                                         buffer.resize(0);
00116                                 }
00117                         }
00118                 }
00119         }
00120 }
00121 
00122 void ThreadedSerialDevice::stopReadingThread()
00123 {
00124         if (readingThread) {
00125                 readingThreadStopRequest = true;
00126                 readingThread->join();
00127                 delete readingThread;
00128                 readingThread = NULL;
00129         }
00130 }
00131 
00132 void ThreadedSerialDevice::informListeners(const std::vector<char>& data)
00133 {
00134         BOOST_FOREACH(SerialDeviceListener* l, serialDeviceListenerSet) {
00135                 l->handleReadSerialData(data);
00136         }
00137 }
00138 
00139 
00140 void ThreadedSerialDevice::openDevice(int oflag)
00141 {
00142 
00143 
00144 
00145 
00146         
00147         SerialDevice::openDevice(oflag);
00148 
00149         
00150         if ( isOpen() && !readingThread ) {
00151                 readingThreadStopRequest = false;
00152                 readingThread = new boost::thread(&ThreadedSerialDevice::readingThreadFcn, this);
00153         }
00154 }
00155 
00156 void ThreadedSerialDevice::closeDevice()
00157 {
00158         stopReadingThread();
00159 
00160         SerialDevice::closeDevice();
00161 }
00162 
00163 void ThreadedSerialDevice::registerSerialDeviceListener(SerialDeviceListener* listener)
00164 {
00165         serialDeviceListenerSet.insert(listener);
00166 }
00167 
00168 void ThreadedSerialDevice::unRegisterSerialDeviceListener(SerialDeviceListener* listener)
00169 {
00170         serialDeviceListenerSet.erase(listener);
00171 }
00172 
00173 }