TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/serial_port_base.cpp
Go to the documentation of this file.
00001 /*
00002     This file is part of the TOBI SignalServer.
00003 
00004     Commercial Usage
00005     Licensees holding valid Graz University of Technology Commercial
00006     licenses may use this file in accordance with the Graz University
00007     of Technology Commercial License Agreement provided with the
00008     Software or, alternatively, in accordance with the terms contained in
00009     a written agreement between you and Graz University of Technology.
00010 
00011     --------------------------------------------------
00012 
00013     GNU General Public License Usage
00014     Alternatively, this file may be used under the terms of the GNU
00015     General Public License version 3.0 as published by the Free Software
00016     Foundation and appearing in the file gpl.txt included in the
00017     packaging of this file.  Please review the following information to
00018     ensure the GNU General Public License version 3.0 requirements will be
00019     met: http://www.gnu.org/copyleft/gpl.html.
00020 
00021     In case of GNU General Public License Usage ,the TOBI SignalServer
00022     is distributed in the hope that it will be useful,
00023     but WITHOUT ANY WARRANTY; without even the implied warranty of
00024     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025     GNU General Public License for more details.
00026 
00027     You should have received a copy of the GNU General Public License
00028     along with the TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>.
00029 
00030     Copyright 2010 Graz University of Technology
00031     Contact: SignalServer@tobi-project.org
00032 */
00033 
00038 #include "hardware/serial_port_base.h"
00039 
00040 #include <iostream>
00041 #include <boost/bind.hpp>
00042 
00043 #define DEFAULT_BAUD_RATE 9600
00044 
00045 namespace tobiss
00046 {
00047 
00048 using std::string;
00049 using std::cout;
00050 using std::cerr;
00051 using std::endl;
00052 using std::flush;
00053 
00054 //-----------------------------------------------------------------------------
00055 
00056 std::map<unsigned int, std::string> SerialPortBase::AsioSerialPortTypeNames::flow_control_values_;
00057 std::map<unsigned int, std::string> SerialPortBase::AsioSerialPortTypeNames::stop_bit_values_;
00058 std::map<unsigned int, std::string> SerialPortBase::AsioSerialPortTypeNames::parity_values_;
00059 
00060 //-----------------------------------------------------------------------------
00061 
00062 SerialPortBase::AsioSerialPortTypeNames& SerialPortBase::AsioSerialPortTypeNames::getInstance()
00063 {
00064  static AsioSerialPortTypeNames instance;
00065  return instance;
00066 }
00067 
00068 //-----------------------------------------------------------------------------
00069 
00070 SerialPortBase::AsioSerialPortTypeNames::AsioSerialPortTypeNames()
00071 {
00072   flow_control_values_[1] = "none";
00073   flow_control_values_[2] = "software";
00074   flow_control_values_[3] = "hardware";
00075 
00076   stop_bit_values_[1] = "1";
00077   stop_bit_values_[2] = "1.5";
00078   stop_bit_values_[3] = "2";
00079 
00080   parity_values_[1] = "none";
00081   parity_values_[2] = "odd";
00082   parity_values_[3] = "even";
00083 }
00084 
00085 //-----------------------------------------------------------------------------
00086 
00087 std::string SerialPortBase::AsioSerialPortTypeNames::getFlowControlName(unsigned int id)
00088 {
00089   std::string str;
00090   str = ((flow_control_values_.find(id) != flow_control_values_.end() )?
00091          flow_control_values_.find(id)->second : "");
00092   if(!str.size())
00093     throw(std::runtime_error("AsioSerialPortTypeNames::getFlowControlName() -- ID not found!"));
00094   return(str);
00095 }
00096 
00097 //-----------------------------------------------------------------------------
00098 
00099 std::string SerialPortBase::AsioSerialPortTypeNames::getStopBitName(unsigned int id)
00100 {
00101   std::string str;
00102   str = ( (stop_bit_values_.find(id) != stop_bit_values_.end() )?
00103            stop_bit_values_.find(id)->second : "");
00104   if(!str.size())
00105     throw(std::runtime_error("AsioSerialPortTypeNames::getStopBitName() -- ID not found!"));
00106   return(str);
00107 }
00108 
00109 //-----------------------------------------------------------------------------
00110 
00111 std::string SerialPortBase::AsioSerialPortTypeNames::getParityName(unsigned int id)
00112 {
00113   std::string str;
00114   str = ( (parity_values_.find(id) != parity_values_.end() )?
00115     parity_values_.find(id)->second : ""  );
00116   if(!str.size())
00117     throw(std::runtime_error("AsioSerialPortTypeNames::getParityName() -- ID not found!"));
00118   return(str);
00119 }
00120 
00121 //-----------------------------------------------------------------------------
00122 
00123 unsigned int SerialPortBase::AsioSerialPortTypeNames::getFlowControlID(std::string str)
00124 {
00125   std::map<unsigned int, std::string>::iterator it =
00126       find_if(flow_control_values_.begin(),
00127               flow_control_values_.end(),
00128               std::bind2nd(MapValue(), str) );
00129 
00130   return(it != stop_bit_values_.end() ? it->first :
00131          throw(std::runtime_error("AsioSerialPortTypeNames::getFlowControlID() -- Name not found " + str)));
00132 }
00133 
00134 //-----------------------------------------------------------------------------
00135 
00136 unsigned int SerialPortBase::AsioSerialPortTypeNames::getStopBitID(std::string str)
00137 {
00138   std::map<unsigned int, std::string>::iterator it =
00139       find_if(stop_bit_values_.begin(),
00140               stop_bit_values_.end(),
00141               std::bind2nd(MapValue(), str) );
00142 
00143   return(it != stop_bit_values_.end() ? it->first :
00144          throw( std::runtime_error("AsioSerialPortTypeNames::getStopBitID() -- Name not found: " + str)));
00145 }
00146 
00147 //-----------------------------------------------------------------------------
00148 
00149 unsigned int SerialPortBase::AsioSerialPortTypeNames::getParityID(std::string str)
00150 {
00151   std::map<unsigned int, std::string>::iterator it =
00152       find_if(parity_values_.begin(),
00153               parity_values_.end(),
00154               std::bind2nd(MapValue(), str) );
00155 
00156   return(it != stop_bit_values_.end() ? it->first :
00157          throw(std::runtime_error("AsioSerialPortTypeNames::getParityID() -- Name not found: " + str)));
00158 }
00159 
00160 
00161 //-----------------------------------------------------------------------------
00162 //-----------------------------------------------------------------------------
00163 
00164 
00165 SerialPortBase::SerialPortBase(boost::asio::io_service& io)
00166   : serial_port_(io), data_available_(true), data_written_(true),
00167     baud_rate_(0), flow_control_type_(0), parity_(0), stop_bits_(0), character_size_(0),
00168     asio_types_(AsioSerialPortTypeNames::getInstance())
00169 {
00170 
00171 }
00172 
00173 //-----------------------------------------------------------------------------
00174 
00175 SerialPortBase::~SerialPortBase()
00176 {
00177   if( !serial_port_.is_open() )
00178     return;
00179 
00180   boost::system::error_code ec;
00181   serial_port_.close(ec);
00182   if(ec)
00183     std::cerr << "SerialPortBase::Destructor() -- Error closing port: " + port_name_ << std::endl;
00184 }
00185 
00186 //-----------------------------------------------------------------------------
00187 
00188 void SerialPortBase::setPortName(const std::string& name)
00189 {
00190   if( name == "" )
00191     throw(std::runtime_error("SerialPortBase::open() -- No serial port given"));
00192 
00193   port_name_ = name;
00194 }
00195 
00196 //-----------------------------------------------------------------------------
00197 
00198 void SerialPortBase::open()
00199 {
00200   if( serial_port_.is_open() )
00201     throw(std::runtime_error("SerialPortBase::open() -- Port already open: " + port_name_));
00202 
00203   boost::system::error_code ec;
00204   serial_port_.open(port_name_, ec);
00205 
00206   if(ec)
00207     throw(std::runtime_error("SerialPortBase::open() -- Error opening serial port: " + port_name_));
00208 
00209   if(!baud_rate_)
00210   {
00211     baud_rate_ = DEFAULT_BAUD_RATE;
00212 
00213     boost::asio::serial_port_base::baud_rate br(baud_rate_);
00214     serial_port_.set_option(br);
00215   }
00216 }
00217 
00218 //-----------------------------------------------------------------------------
00219 
00220 void SerialPortBase::close()
00221 {
00222   if( !serial_port_.is_open() )
00223     return;
00224 
00225   boost::system::error_code ec;
00226   serial_port_.close(ec);
00227 
00228   if(ec)
00229     std::cerr << "SerialPortBase::close() -- Error closing port: " + port_name_ << std::endl;
00230 }
00231 
00232 //-----------------------------------------------------------------------------
00233 
00234 void SerialPortBase::setBaudRate(const unsigned int rate)
00235 {
00236   if( !serial_port_.is_open() )
00237     throw(std::runtime_error("SerialPortBase::setBaudRate() -- Port not opened: " + port_name_));
00238 
00239   boost::asio::serial_port_base::baud_rate br(rate);
00240   serial_port_.set_option(br);
00241 
00242   baud_rate_ = rate;
00243 }
00244 
00245 //-----------------------------------------------------------------------------
00246 
00247 void SerialPortBase::setFlowControl(const string& type)
00248 {
00249   if( !serial_port_.is_open() )
00250     throw(std::runtime_error("SerialPortBase::setFlowControl() -- Port not opened: " + port_name_));
00251 
00252   if(asio_types_.getFlowControlID(type) == 1)
00253   {
00254     boost::asio::serial_port_base::flow_control o(boost::asio::serial_port_base::flow_control::none);
00255     serial_port_.set_option(o);
00256   }
00257   if(asio_types_.getFlowControlID(type) == 2)
00258   {
00259     boost::asio::serial_port_base::flow_control o(boost::asio::serial_port_base::flow_control::software);
00260     serial_port_.set_option(o);
00261   }
00262   if(asio_types_.getFlowControlID(type) == 3)
00263   {
00264     boost::asio::serial_port_base::flow_control o(boost::asio::serial_port_base::flow_control::hardware);
00265     serial_port_.set_option(o);
00266   }
00267 }
00268 
00269 //-----------------------------------------------------------------------------
00270 
00271 void SerialPortBase::setParity(const string& type)
00272 {
00273   if( !serial_port_.is_open() )
00274     throw(std::runtime_error("SerialPortBase::setParity() -- Port not opened: " + port_name_));
00275 
00276   if(asio_types_.getParityID(type) == 1)
00277   {
00278     boost::asio::serial_port_base::parity o(boost::asio::serial_port_base::parity::none);
00279     serial_port_.set_option(o);
00280   }
00281   if(asio_types_.getParityID(type) == 2)
00282   {
00283     boost::asio::serial_port_base::parity o(boost::asio::serial_port_base::parity::odd);
00284     serial_port_.set_option(o);
00285   }
00286   if(asio_types_.getParityID(type) == 3)
00287   {
00288     boost::asio::serial_port_base::parity o(boost::asio::serial_port_base::parity::even);
00289     serial_port_.set_option(o);
00290   }
00291 }
00292 
00293 //-----------------------------------------------------------------------------
00294 
00295 void SerialPortBase::setStopBits(const string& bits)
00296 {
00297   if( !serial_port_.is_open() )
00298     throw(std::runtime_error("SerialPortBase::setStopBits() -- Port not opened: " + port_name_));
00299 
00300   if(asio_types_.getStopBitID(bits) == 1)
00301   {
00302     boost::asio::serial_port_base::stop_bits sb(boost::asio::serial_port_base::stop_bits::one);
00303     serial_port_.set_option(sb);
00304   }
00305   if(asio_types_.getStopBitID(bits) == 2)
00306   {
00307     boost::asio::serial_port_base::stop_bits sb(boost::asio::serial_port_base::stop_bits::onepointfive);
00308     serial_port_.set_option(sb);
00309   }
00310   if(asio_types_.getStopBitID(bits) == 3)
00311   {
00312     boost::asio::serial_port_base::stop_bits sb(boost::asio::serial_port_base::stop_bits::two);
00313     serial_port_.set_option(sb);
00314   }
00315 }
00316 
00317 //-----------------------------------------------------------------------------
00318 
00319 void SerialPortBase::setCharacterSize(const unsigned int size)
00320 {
00321   if( !serial_port_.is_open() )
00322     throw(std::runtime_error("SerialPortBase::setCharacterSize() -- Port not opened: " + port_name_));
00323 
00324   boost::asio::serial_port_base::character_size cs(size);
00325   serial_port_.set_option(cs);
00326 }
00327 
00328 //-----------------------------------------------------------------------------
00329 
00330 void SerialPortBase::handleAsyncRead(const boost::system::error_code& ec,
00331                                      std::size_t bytes_transferred )
00332 {
00333   if(ec)
00334     throw(std::runtime_error("SerialPortBase::handleAsyncRead() -- \
00335                              Error handling async read -- bytes transferred: " + bytes_transferred));
00336 
00337   data_available_ = true;
00338 }
00339 
00340 //-----------------------------------------------------------------------------
00341 
00342 void SerialPortBase::handleAsyncWrite(const boost::system::error_code& ec,
00343                                      std::size_t bytes_transferred )
00344 {
00345   if(ec)
00346     throw(std::runtime_error("SerialPortBase::handleAsyncWrite() -- \
00347                              Error handling async write -- bytes transferred: " + bytes_transferred));
00348 
00349   data_written_ = true;
00350 }
00351 
00352 //-----------------------------------------------------------------------------
00353 
00354 }  // tobiss
 All Data Structures Files Functions Variables