ThreadedSerialDevice.cpp
Go to the documentation of this file.
00001 /*
00002  * ThreadedSerialDevice.cpp
00003  *
00004  *  Created on: Nov 23, 2011
00005  *      Author: mriedel
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 // remove NONBLOCK
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 //      if (oflag & O_NONBLOCK) {
00034 //              ROS_WARN("Using ThreadedSerialDevice With O_NONBLOCK. This is not optimal.");
00035 //      }
00036 
00037         // if open start thread
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         //ROS_INFO("Starting Reading Thread!!");
00062         // this is only the inital size
00063         std::vector<char> buffer;
00064         buffer.reserve(MAIN_BUFFER_SIZE);
00065         // size should be 0
00066         //ROS_INFO("buffer.size() = %d", (int)buffer.size());
00067         int bufferPosition = 0;
00068         char readingBuffer[READING_BUFFER_SIZE];
00069 
00070         // select timeout
00071         timeval selectTimeOut;
00072         selectTimeOut.tv_sec = 1;
00073         selectTimeOut.tv_usec = 0;
00074 
00075         while(!readingThreadStopRequest && ros::ok()) {
00076                 //ROS_INFO("About to Read Bytes!");
00077                 // Check if Data is actually available
00078 
00079                 size_t nBytesRead = 0;
00080                 if (readAvailable(selectTimeOut)) {
00081                         nBytesRead = readDevice(readingBuffer, READING_BUFFER_SIZE, terminalChars);
00082                 }
00083 
00084 //              nBytesRead = readDevice(readingBuffer, READING_BUFFER_SIZE, terminalChars);
00085 
00086                 if (nBytesRead > 0) {
00087 //                      printf("\n");
00088 //                      ROS_INFO("Read %d Bytes", (int)nBytesRead);
00089 
00090                         // look for terminal chars
00091                         for (unsigned int i = 0; i < nBytesRead; i++) {
00092                                 // always push
00093                                 buffer.push_back(readingBuffer[i]);
00094                                 bufferPosition++;
00095 //                              std::cout << " ReadingBuffer: " << (int)readingBuffer[i] << std::endl;
00096 //                              std::cout << " Bufferposition: " << (int)bufferPosition << std::endl;
00097 
00098                                 if (terminalChars.find(readingBuffer[i]) != terminalChars.npos) {
00099                                         //std::cout << "I get here! 1" << std::endl;
00100                                         // found flush current
00101 
00102                                         // send to listeners
00103                                         std::vector<char> dataVector(bufferPosition);
00104                                         memcpy(&dataVector[0], &buffer[0], bufferPosition);
00105 
00106                                         //std::cout << "I get here! 2" << std::endl;
00107 
00108                                         // they should process in a fast manner.
00109                                         informListeners(dataVector);
00110 
00111                                         //std::cout << "I get here! 3" << std::endl;
00112 
00113                                         // reset
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 //      if (oflag & O_NONBLOCK) {
00143 //              ROS_WARN("Using ThreadedSerialDevice With O_NONBLOCK. This is not optimal.");
00144 //      }
00145 
00146         // throws on error
00147         SerialDevice::openDevice(oflag);
00148 
00149         // if open start thread
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


telekyb_serial
Author(s): Martin Riedel
autogenerated on Mon Nov 11 2013 11:14:08