AsyncSerial.h
Go to the documentation of this file.
00001 /**************************************************************************************************
00002  Software License Agreement (BSD License)
00003 
00004  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
00005  All rights reserved.
00006 
00007  Redistribution and use in source and binary forms, with or without modification, are permitted
00008  provided that the following conditions are met:
00009 
00010   *Redistributions of source code must retain the above copyright notice, this list of
00011    conditions and the following disclaimer.
00012   *Redistributions in binary form must reproduce the above copyright notice, this list of
00013    conditions and the following disclaimer in the documentation and/or other materials provided
00014    with the distribution.
00015   *Neither the name of the University of Aveiro nor the names of its contributors may be used to
00016    endorse or promote products derived from this software without specific prior written permission.
00017  
00018  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
00019  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
00021  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00024  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00025  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 ***************************************************************************************************/
00036 // ORIGINAL BELOW
00037 /*
00038  * File:   AsyncSerial.h
00039  * Author: Terraneo Federico
00040  * Distributed under the Boost Software License, Version 1.0.
00041  * Created on September 7, 2009, 10:46 AM
00042  */
00043 
00044 #ifndef ASYNCSERIAL_H
00045 #define ASYNCSERIAL_H
00046 
00047 #include <vector>
00048 #include <boost/asio.hpp>
00049 #include <boost/bind.hpp>
00050 #include <boost/thread.hpp>
00051 #include <boost/utility.hpp>
00052 #include <boost/function.hpp>
00053 #include <boost/shared_array.hpp>
00054 
00055 namespace serialcom
00056 {
00057     const unsigned int read_buffer_size=512;
00058 }
00059 
00060 #ifndef __APPLE__
00061 
00066 class AsyncSerialImpl:private boost::noncopyable
00067 {
00068     public:
00069         AsyncSerialImpl():
00070         io (  ),
00071         port ( io ),
00072         backgroundThread (  ),
00073         open ( false ),
00074         error ( false )
00075         {
00076         }
00077         
00078         boost::asio::io_service io;
00079 
00080         boost::asio::serial_port port;   
00081         boost::thread backgroundThread;  
00082         bool open;                   
00083 
00084         bool error;                  
00085 
00086         mutable boost::mutex errorMutex; 
00087 
00089         std::vector <char> writeQueue;
00090 
00091         boost::shared_array <char> writeBuffer;              
00092 
00093         size_t writeBufferSize;      
00094 
00095         boost::mutex writeQueueMutex;    
00096         
00097         char readBuffer[serialcom::read_buffer_size];   
00098 
00100         boost::function < void ( const char *, size_t ) > callback;
00101 };
00102 
00108 class AsyncSerial:private boost::noncopyable
00109 {
00110     public:
00111 
00112         AsyncSerial()   
00113         :pimpl ( new AsyncSerialImpl )
00114         {
00115         }
00116     
00128         AsyncSerial ( const std::string & devname, unsigned int baud_rate,
00129                         boost::asio::serial_port_base::parity opt_parity =
00130                         boost::asio::serial_port_base::parity ( boost::asio::
00131                                                                 serial_port_base::parity::none ),
00132                         boost::asio::serial_port_base::character_size opt_csize =
00133                         boost::asio::serial_port_base::character_size ( 8 ),
00134                         boost::asio::serial_port_base::flow_control opt_flow =
00135                         boost::asio::serial_port_base::flow_control ( boost::
00136                                                                     asio::serial_port_base::flow_control::
00137                                                                     none ),
00138                         boost::asio::serial_port_base::stop_bits opt_stop =
00139                         boost::asio::serial_port_base::stop_bits ( boost::asio::
00140                                                                     serial_port_base::stop_bits::
00141                                                                     one ) )
00142         :pimpl ( new AsyncSerialImpl )
00143         {
00144             open ( devname, baud_rate, opt_parity, opt_csize, opt_flow, opt_stop );
00145         }
00146 
00158         void open ( const std::string & devname, unsigned int baud_rate,
00159                     boost::asio::serial_port_base::parity opt_parity =
00160                     boost::asio::serial_port_base::parity ( boost::asio::serial_port_base::
00161                                                             parity::none ),
00162                     boost::asio::serial_port_base::character_size opt_csize =
00163                     boost::asio::serial_port_base::character_size ( 8 ),
00164                     boost::asio::serial_port_base::flow_control opt_flow =
00165                     boost::asio::serial_port_base::flow_control ( boost::asio::serial_port_base::flow_control::none ),
00166                     boost::asio::serial_port_base::stop_bits opt_stop =
00167                     boost::asio::serial_port_base::stop_bits ( boost::asio::serial_port_base::stop_bits::one ) )
00168         {
00169             if ( isOpen (  ) )
00170                 close (  );
00171 
00172             setErrorStatus ( true );     //If an exception is thrown, error_ remains true
00173             pimpl->port.open ( devname );
00174             pimpl->port.set_option ( boost::asio::serial_port_base::baud_rate ( baud_rate ) );
00175             pimpl->port.set_option ( opt_parity );
00176             pimpl->port.set_option ( opt_csize );
00177             pimpl->port.set_option ( opt_flow );
00178             pimpl->port.set_option ( opt_stop );
00179 
00180             //This gives some work to the io_service before it is started
00181             pimpl->io.post ( boost::bind ( &AsyncSerial::doRead, this ) );
00182 
00183             boost::thread t ( boost::bind ( &boost::asio::io_service::run, &pimpl->io ) );
00184 
00185             pimpl->backgroundThread.swap ( t );
00186             setErrorStatus ( false );    //If we get here, no error
00187             pimpl->open = true;          //Port is now open
00188         }
00189 
00193         bool isOpen (  ) const
00194         {
00195             return pimpl->open;
00196         }
00197 
00201         bool errorStatus (  ) const
00202         {
00203             boost::lock_guard < boost::mutex > l ( pimpl->errorMutex );
00204             return pimpl->error;
00205         }
00206 
00211         void close()
00212         {
00213             if ( !isOpen (  ) )
00214                 return;
00215 
00216             pimpl->open = false;
00217             pimpl->io.post ( boost::bind ( &AsyncSerial::doClose, this ) );
00218             pimpl->backgroundThread.join (  );
00219             pimpl->io.reset (  );
00220             if ( errorStatus (  ) )
00221             {
00222                 throw ( boost::system::system_error ( boost::system::error_code (  ),"Error while closing the device" ) );
00223             }
00224         }
00225 
00231         void write ( const char *data, size_t size )
00232         {
00233             {
00234                 boost::lock_guard < boost::mutex > l ( pimpl->writeQueueMutex );
00235                 pimpl->writeQueue.insert ( pimpl->writeQueue.end (  ), data, data + size );
00236             }
00237             
00238             pimpl->io.post ( boost::bind ( &AsyncSerial::doWrite, this ) );
00239         }
00240 
00245         void write ( const std::vector < char >&data )
00246         {
00247             {
00248                 boost::lock_guard < boost::mutex > l ( pimpl->writeQueueMutex );
00249                 pimpl->writeQueue.insert ( pimpl->writeQueue.end (  ), data.begin (  ),data.end (  ) );
00250             }
00251             
00252             pimpl->io.post ( boost::bind ( &AsyncSerial::doWrite, this ) );
00253         }
00254 
00261         void writeString ( const std::string & s )
00262         {
00263             {
00264                 boost::lock_guard < boost::mutex > l ( pimpl->writeQueueMutex );
00265                 pimpl->writeQueue.insert ( pimpl->writeQueue.end (  ), s.begin (  ), s.end (  ) );
00266             }
00267             
00268             pimpl->io.post ( boost::bind ( &AsyncSerial::doWrite, this ) );
00269         }
00270 
00271         virtual ~AsyncSerial (  )
00272         {
00273             if ( isOpen (  ) )
00274             {
00275                 try
00276                 {
00277                     close (  );
00278                 }
00279                 catch ( ... )
00280                 {
00281                     //Don't throw from a destructor
00282                 }
00283             }
00284         }
00288         static const int readBufferSize = 512;
00289     
00290     private:
00291 
00296         void doRead (  )
00297         {
00298             pimpl->port.async_read_some ( boost::asio::buffer ( pimpl->readBuffer, readBufferSize ),
00299                                  boost::bind ( &AsyncSerial::readEnd,
00300                                                this,
00301                                                boost::asio::placeholders::error,
00302                                                boost::asio::placeholders::bytes_transferred ) );
00303         }
00304 
00309         void readEnd ( const boost::system::error_code & error, size_t bytes_transferred )
00310         {
00311             if ( error )
00312             {
00313 #ifdef __APPLE__
00314                 if ( error.value (  ) == 45 )
00315                 {
00316                     //Bug on OS X, it might be necessary to repeat the setup
00317                     //http://osdir.com/ml/lib.boost.asio.user/2008-08/msg00004.html
00318                     doRead (  );
00319                     return;
00320                 }
00321 #endif //__APPLE__
00322 
00323                 //error can be true even because the serial port was closed.
00324                 //In this case it is not a real error, so ignore
00325                 if ( isOpen (  ) )
00326                 {
00327                     doClose (  );
00328                     setErrorStatus ( true );
00329                 }
00330             } else
00331             {
00332                 if ( pimpl->callback )
00333                 pimpl->callback ( pimpl->readBuffer, bytes_transferred );
00334                 doRead (  );
00335             }
00336         }
00337         
00343         void doWrite (  )
00344         {
00345             //If a write operation is already in progress, do nothing
00346             if ( pimpl->writeBuffer == 0 )
00347             {
00348                 boost::lock_guard < boost::mutex > l ( pimpl->writeQueueMutex );
00349                 pimpl->writeBufferSize = pimpl->writeQueue.size (  );
00350                 pimpl->writeBuffer.reset ( new char[pimpl->writeQueue.size (  )] );
00351 
00352                 copy ( pimpl->writeQueue.begin (  ), pimpl->writeQueue.end (  ),
00353                     pimpl->writeBuffer.get (  ) );
00354                 pimpl->writeQueue.clear (  );
00355                 async_write ( pimpl->port, boost::asio::buffer ( pimpl->writeBuffer.get (  ),
00356                                                         pimpl->writeBufferSize ),
00357                             boost::bind ( &AsyncSerial::writeEnd, this,
00358                                             boost::asio::placeholders::error ) );
00359             }
00360         }
00361 
00367         void writeEnd ( const boost::system::error_code & error )
00368         {
00369             if ( !error )
00370             {
00371                 boost::lock_guard < boost::mutex > l ( pimpl->writeQueueMutex );
00372                 if ( pimpl->writeQueue.empty (  ) )
00373                 {
00374                     pimpl->writeBuffer.reset (  );
00375                     pimpl->writeBufferSize = 0;
00376 
00377                     return;
00378                 }
00379                 pimpl->writeBufferSize = pimpl->writeQueue.size (  );
00380                 pimpl->writeBuffer.reset ( new char[pimpl->writeQueue.size (  )] );
00381                 copy ( pimpl->writeQueue.begin (  ), pimpl->writeQueue.end (  ),
00382                     pimpl->writeBuffer.get (  ) );
00383                 pimpl->writeQueue.clear (  );
00384                 async_write ( pimpl->port, boost::asio::buffer ( pimpl->writeBuffer.get (  ),
00385                                                         pimpl->writeBufferSize ),
00386                             boost::bind ( &AsyncSerial::writeEnd, this,
00387                                             boost::asio::placeholders::error ) );
00388             } else
00389             {
00390                 setErrorStatus ( true );
00391                 doClose (  );
00392             }
00393         }
00394 
00398         void doClose (  )
00399         {
00400             boost::system::error_code ec;
00401             pimpl->port.cancel ( ec );
00402             if ( ec )
00403                 setErrorStatus ( true );
00404             pimpl->port.close ( ec );
00405             if ( ec )
00406                 setErrorStatus ( true );
00407         }
00408 
00409         boost::shared_ptr <AsyncSerialImpl > pimpl;
00410 
00411     protected:
00412 
00417         void setErrorStatus ( bool e )
00418         {
00419             boost::lock_guard < boost::mutex > l ( pimpl->errorMutex );
00420             pimpl->error = e;
00421         }
00422 
00426         void setReadCallback ( const boost::function < void ( const char *, size_t ) > &callback )
00427         {
00428             pimpl->callback = callback;
00429         }
00430 
00431 
00437         void clearReadCallback (  )
00438         {
00439             pimpl->callback.clear (  );
00440         }
00441 
00442 };
00443 
00444 #else //__APPLE__
00445 
00446 #include <sys/types.h>
00447 #include <sys/stat.h>
00448 #include <fcntl.h>
00449 #include <termios.h>
00450 #include <unistd.h>
00451 
00452 class AsyncSerialImpl:private boost::noncopyable
00453 {
00454     public:
00455         AsyncSerialImpl():
00456         backgroundThread (  ),
00457         open ( false ),
00458         error ( false )
00459         {
00460         }
00461         
00462         boost::thread backgroundThread;         
00463 
00464         bool open;                   
00465 
00466         bool error;                  
00467 
00468         mutable boost::mutex errorMutex; 
00469 
00470         int fd;                        
00471 
00472         char readBuffer[AsyncSerial::readBufferSize];   
00473 
00475         boost::function < void ( const char *, size_t ) >callback;
00476 };
00477 
00483 class AsyncSerial:private boost::noncopyable
00484 {
00485     public:
00486 
00487         AsyncSerial()   
00488         :pimpl ( new AsyncSerialImpl )
00489         {
00490         }
00491     
00503         AsyncSerial ( const std::string & devname, unsigned int baud_rate,
00504                         boost::asio::serial_port_base::parity opt_parity =
00505                         boost::asio::serial_port_base::parity ( boost::asio::
00506                                                                 serial_port_base::parity::none ),
00507                         boost::asio::serial_port_base::character_size opt_csize =
00508                         boost::asio::serial_port_base::character_size ( 8 ),
00509                         boost::asio::serial_port_base::flow_control opt_flow =
00510                         boost::asio::serial_port_base::flow_control ( boost::
00511                                                                     asio::serial_port_base::flow_control::
00512                                                                     none ),
00513                         boost::asio::serial_port_base::stop_bits opt_stop =
00514                         boost::asio::serial_port_base::stop_bits ( boost::asio::
00515                                                                     serial_port_base::stop_bits::
00516                                                                     one ) )
00517         :pimpl ( new AsyncSerialImpl )
00518         {
00519             open ( devname, baud_rate, opt_parity, opt_csize, opt_flow, opt_stop );
00520         }
00521 
00522 
00534         void open ( const std::string & devname, unsigned int baud_rate,
00535                     boost::asio::serial_port_base::parity opt_parity =
00536                     boost::asio::serial_port_base::parity ( boost::asio::serial_port_base::
00537                                                             parity::none ),
00538                     boost::asio::serial_port_base::character_size opt_csize =
00539                     boost::asio::serial_port_base::character_size ( 8 ),
00540                     boost::asio::serial_port_base::flow_control opt_flow =
00541                     boost::asio::serial_port_base::flow_control ( boost::asio::
00542                                                                 serial_port_base::flow_control::
00543                                                                 none ),
00544                     boost::asio::serial_port_base::stop_bits opt_stop =
00545                     boost::asio::serial_port_base::stop_bits ( boost::asio::
00546                                                                 serial_port_base::stop_bits::
00547                                                                 one ) )
00548         {
00549             if ( isOpen (  ) )
00550                 close (  );
00551 
00552             setErrorStatus ( true );     //If an exception is thrown, error remains true
00553 
00554             struct termios new_attributes;
00555 
00556             speed_t speed;
00557 
00558             int status;
00559 
00560             // Open port
00561             pimpl->fd =::open ( devname.c_str (  ), O_RDWR | O_NOCTTY | O_NONBLOCK );
00562             if ( pimpl->fd < 0 )
00563                 throw ( boost::system::system_error ( boost::system::error_code (  ),"Failed to open port" ) );
00564 
00565             // Set Port parameters.
00566             status = tcgetattr ( pimpl->fd, &new_attributes );
00567             if ( status < 0 || !isatty ( pimpl->fd ) )
00568             {
00569                 ::close ( pimpl->fd );
00570                 throw ( boost::system::system_error ( boost::system::error_code (  ),"Device is not a tty" ) );
00571             }
00572             new_attributes.c_iflag = IGNBRK;
00573             new_attributes.c_oflag = 0;
00574             new_attributes.c_lflag = 0;
00575             new_attributes.c_cflag = ( CS8 | CREAD | CLOCAL );   //8 data bit,Enable receiver,Ignore modem
00576             /* In non canonical mode (Ctrl-C and other disabled, no echo,...) VMIN and VTIME work this way:
00577                 if the function read() has'nt read at least VMIN chars it waits until has read at least VMIN
00578                 chars (even if VTIME timeout expires); once it has read at least vmin chars, if subsequent
00579                 chars do not arrive before VTIME expires, it returns error; if a char arrives, it resets the
00580                 timeout, so the internal timer will again start from zero (for the nex char,if any) */
00581             new_attributes.c_cc[VMIN] = 1;   // Minimum number of characters to read before returning error
00582             new_attributes.c_cc[VTIME] = 1;  // Set timeouts in tenths of second
00583 
00584             // Set baud rate
00585             switch ( baud_rate )
00586             {
00587             case 50:
00588                 speed = B50;
00589                 break;
00590             case 75:
00591                 speed = B75;
00592                 break;
00593             case 110:
00594                 speed = B110;
00595                 break;
00596             case 134:
00597                 speed = B134;
00598                 break;
00599             case 150:
00600                 speed = B150;
00601                 break;
00602             case 200:
00603                 speed = B200;
00604                 break;
00605             case 300:
00606                 speed = B300;
00607                 break;
00608             case 600:
00609                 speed = B600;
00610                 break;
00611             case 1200:
00612                 speed = B1200;
00613                 break;
00614             case 1800:
00615                 speed = B1800;
00616                 break;
00617             case 2400:
00618                 speed = B2400;
00619                 break;
00620             case 4800:
00621                 speed = B4800;
00622                 break;
00623             case 9600:
00624                 speed = B9600;
00625                 break;
00626             case 19200:
00627                 speed = B19200;
00628                 break;
00629             case 38400:
00630                 speed = B38400;
00631                 break;
00632             case 57600:
00633                 speed = B57600;
00634                 break;
00635             case 115200:
00636                 speed = B115200;
00637                 break;
00638             case 230400:
00639                 speed = B230400;
00640                 break;
00641             default:
00642                 {
00643                     ::close ( pimpl->fd );
00644                     throw ( boost::system::system_error ( boost::system::error_code (  ),"Unsupported baud rate" ) );
00645                 }
00646             }
00647 
00648             cfsetospeed ( &new_attributes, speed );
00649             cfsetispeed ( &new_attributes, speed );
00650 
00651             //Make changes effective
00652             status = tcsetattr ( pimpl->fd, TCSANOW, &new_attributes );
00653             if ( status < 0 )
00654             {
00655                 ::close ( pimpl->fd );
00656                 throw ( boost::system::system_error ( boost::system::error_code (  ),"Can't set port attributes" ) );
00657             }
00658             //These 3 lines clear the O_NONBLOCK flag
00659             status = fcntl ( pimpl->fd, F_GETFL, 0 );
00660             if ( status != -1 )
00661                 fcntl ( pimpl->fd, F_SETFL, status & ~O_NONBLOCK );
00662 
00663             setErrorStatus ( false );    //If we get here, no error
00664             pimpl->open = true;          //Port is now open
00665 
00666             boost::thread t ( bind ( &AsyncSerial::doRead, this ) );
00667 
00668             pimpl->backgroundThread.swap ( t );
00669         }
00670 
00674         bool isOpen (  ) const
00675         {
00676             return pimpl->open;
00677         }
00678 
00682         bool errorStatus (  ) const
00683         {
00684             boost::lock_guard < boost::mutex > l ( pimpl->errorMutex );
00685             return pimpl->error;
00686         }
00687 
00692         void close()
00693         {
00694             if ( !isOpen (  ) )
00695                 return;
00696 
00697             pimpl->open = false;
00698 
00699             ::close ( pimpl->fd );       //The thread waiting on I/O should return
00700 
00701             pimpl->backgroundThread.join (  );
00702             if ( errorStatus (  ) )
00703             {
00704                 throw ( boost::system::system_error ( boost::system::error_code (  ),"Error while closing the device" ) );
00705             }
00706         }
00707 
00708 
00714         void write ( const char *data, size_t size )
00715         {
00716             if ( ::write ( pimpl->fd, data, size ) != size )
00717                 setErrorStatus ( true );
00718         }
00719         
00724         void write ( const std::vector < char >&data )
00725         {
00726             if ( ::write ( pimpl->fd, &data[0], data.size (  ) ) != data.size (  ) )
00727                 setErrorStatus ( true );
00728         }
00729 
00736         void writeString ( const std::string & s )
00737         {
00738             if ( ::write ( pimpl->fd, &s[0], s.size (  ) ) != s.size (  ) )
00739                 setErrorStatus ( true );
00740         }
00741 
00742         virtual ~AsyncSerial (  )
00743         {
00744             if ( isOpen (  ) )
00745             {
00746                 try
00747                 {
00748                     close (  );
00749                 }
00750                 catch ( ... )
00751                 {
00752                     //Don't throw from a destructor
00753                 }
00754             }
00755         }
00756 
00760         static const int readBufferSize = 512;
00761     
00762     private:
00763 
00768         void doRead (  )
00769         {
00770             //Read loop in spawned thread
00771             for ( ;; )
00772             {
00773                 int
00774                 received =::read ( pimpl->fd, pimpl->readBuffer, readBufferSize );
00775 
00776                 if ( received < 0 )
00777                 {
00778                     if ( isOpen (  ) == false )
00779                         return;         //Thread interrupted because port closed
00780                     else
00781                     {
00782                         setErrorStatus ( true );
00783                         continue;
00784                     }
00785                 }
00786                 
00787                 if ( pimpl->callback )
00788                     pimpl->callback ( pimpl->readBuffer, received );
00789             }
00790         }
00791 
00796         void readEnd ( const boost::system::error_code & error, size_t bytes_transferred )
00797         {
00798             //Not used
00799         }
00800         
00806         void doWrite (  )
00807         {
00808             //Not used
00809         }
00810 
00816         void writeEnd ( const boost::system::error_code & error )
00817         {
00818             //Not used
00819         }
00820 
00824         void doClose (  )
00825         {
00826             //Not used
00827         }
00828 
00829         boost::shared_ptr <AsyncSerialImpl > pimpl;
00830 
00831     protected:
00832 
00837         void setErrorStatus ( bool e )
00838         {
00839             boost::lock_guard < boost::mutex > l ( pimpl->errorMutex );
00840             pimpl->error = e;
00841         }
00842 
00846         void setReadCallback ( const boost::function < void ( const char *, size_t ) > &callback )
00847         {
00848             pimpl->callback = callback;
00849         }
00850 
00851 
00857         void clearReadCallback (  )
00858         {
00859             pimpl->callback.clear (  );
00860         }
00861 
00862 };
00863 
00864 #endif //__APPLE__
00865 
00872 class CallbackAsyncSerial: public AsyncSerial
00873 {
00874     public:
00875         CallbackAsyncSerial (  )
00876         :AsyncSerial (  )
00877         {
00878 
00879         }
00880 
00892         CallbackAsyncSerial ( const std::string & devname, unsigned int baud_rate,
00893                          boost::asio::serial_port_base::parity opt_parity =
00894                          boost::asio::serial_port_base::parity ( boost::asio::serial_port_base::parity::
00895                                                                  none ),
00896                          boost::asio::serial_port_base::character_size opt_csize =
00897                          boost::asio::serial_port_base::character_size ( 8 ),
00898                          boost::asio::serial_port_base::flow_control opt_flow =
00899                          boost::asio::serial_port_base::flow_control ( boost::asio::serial_port_base::flow_control::
00900                                                                        none ),
00901                          boost::asio::serial_port_base::stop_bits opt_stop =
00902                          boost::asio::serial_port_base::stop_bits ( boost::asio::serial_port_base::stop_bits::
00903                                                                     one ) )
00904         :AsyncSerial ( devname, baud_rate, opt_parity, opt_csize, opt_flow, opt_stop )
00905         {
00906 
00907         }
00908 
00915         void setCallback ( const boost::function < void ( const char *, size_t ) > &callback )
00916         {
00917             setReadCallback ( callback );
00918         }
00919 
00924         void clearCallback (  )
00925         {
00926             clearReadCallback (  );
00927         }
00928 
00929         virtual ~ CallbackAsyncSerial (  )
00930         {
00931             clearReadCallback (  );
00932         }
00933 };
00934 
00935 #endif //ASYNCSERIAL_H


serialcom
Author(s): Ricardo Pascoal
autogenerated on Thu Nov 20 2014 11:35:58