00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00026 #pragma once
00027 #pragma warning( disable : 4355 )
00028 #endif
00029
00030 #ifndef VET_ASYNCH_SERIAL_H_INCLUDED
00031 #define VET_ASYNCH_SERIAL_H_INCLUDED
00032 #include "excepts.h"
00033 #include <string>
00034 #include <deque>
00035 #include <boost/bind.hpp>
00036 #include <boost/asio.hpp>
00037 #include <boost/asio/serial_port.hpp>
00038 #include <boost/lexical_cast.hpp>
00039 #include <boost/date_time/posix_time/posix_time_types.hpp>
00040 #include <boost/signals2.hpp>
00041
00049 namespace cornelluniversity {
00050
00056 namespace vetserial {
00057
00058
00059 #if defined(unix) || defined(__unix__) || defined(__unix) || defined(__linux__)
00060 const static std::string DFLT_DEVICE = "/dev/ttyS0";
00061 #elif defined(__APPLE__)
00062
00063 const static std::string DFLT_DEVICE = "/dev/ttyUSB0";
00064 #else
00065 const static std::string DFLT_DEVICE = "COM1";
00066 #endif
00067
00091 class asynch_serial {
00092
00093 typedef boost::signals2::signal<void (const std::string &)> Reader;
00094 typedef Reader::slot_type ReaderSlotType;
00096 public:
00108 asynch_serial( boost::asio::io_service& ios ) : active_(false), reading_(false), io_service_(ios), serial_port_(io_service_){;}
00109
00119 asynch_serial( boost::asio::io_service& io_service, unsigned int baud, const std::string& device );
00120
00125 inline boost::asio::io_service& ioservice(){ return(serial_port_.get_io_service()); }
00126
00130 virtual ~asynch_serial( void ){;}
00131
00142 void open( const std::string& device );
00143
00152 void open( unsigned int baud = 9600, const std::string& device = DFLT_DEVICE );
00153
00157 inline void close( void ) { this->serial_port_.get_io_service().post( boost::bind(&asynch_serial::do_close, this, boost::system::error_code()) ); }
00158
00163 inline bool active() const { return( this->active_ ); }
00164
00169 inline void active( const bool on_off ) { this->active_ = on_off; }
00170
00175 inline void write( const char msg ) { this->serial_port_.get_io_service().post( boost::bind(&asynch_serial::do_write, this, msg) ); }
00176
00182 inline boost::signals2::connection register_reader( const ReaderSlotType & slot ) { return(reader_.connect(slot)); }
00183
00189 template<typename SettableSerialPortOption>
00190 void setopt( const SettableSerialPortOption & opt ){ this->serial_port_.set_option( opt );}
00191
00200 inline void start_reading( void ){ if(serial_port_.is_open() && !reading_){this->read_start(); reading_ = true;} }
00201
00202 private:
00209 void do_close( const boost::system::error_code& error );
00210
00216 void do_write( const char msg );
00217
00221 void write_start( void );
00222
00227 void write_complete( const boost::system::error_code& error );
00228
00232 void read_start( void );
00233
00239 void read_complete( const boost::system::error_code& error, size_t bytes_transferred );
00240
00241 private:
00242 static const int max_read_length = 512;
00244 bool active_;
00245 bool reading_;
00246 boost::asio::io_service& io_service_;
00247 boost::asio::serial_port serial_port_;
00248 char read_msg_[max_read_length];
00249 std::deque<char> write_msgs_;
00250 Reader reader_;
00251 };
00252 }
00253 }
00254
00255 #endif
00256
00257
00258
00259
00260
00261
00262