00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <serialport.h>
00021 #include <errno.h>
00022 #include <ctype.h>
00023 #include <iostream>
00024 #include <util.h>
00025
00026 SerialPort::SerialPort() :
00027 Port()
00028 {
00029 }
00030
00031 SerialPort::~SerialPort()
00032 {
00033 close();
00034 }
00035
00036 Port::Error SerialPort::open( const std::string & config )
00037 {
00038 bool rts=false, dtr=false, dsr=false, cts=false;
00039
00040 TokenList token = Util::tokenize( config, ":" );
00041 int tokenCnt = token.size();
00042
00043 for (int i=5; i<tokenCnt; ++i)
00044 {
00045 for (unsigned j=0; j<token[i].size(); ++j)
00046 {
00047 token[i][j] = toupper( token[i][j] );
00048 }
00049 if (token[i] == "RTS") rts=true;
00050 else if (token[i] == "DTR") dtr=true;
00051 else if (token[i] == "DSR") dsr=true;
00052 else if (token[i] == "CTS") cts=true;
00053 }
00054
00055 int baud;
00056 if (!Util::fromString( &baud, token[1] )) return Port::SyntaxError;
00057 int bits;
00058 if (!Util::fromString( &bits, token[2] )) return Port::SyntaxError;
00059 int stopBits;
00060 if (!Util::fromString( &stopBits, token[4] )) return Port::SyntaxError;
00061
00062 int parity = -1;
00063
00064 if (token[3] == "N" || token[3] == "n") parity = 0;
00065 if (token[3] == "E" || token[3] == "e") parity = 1;
00066 if (token[3] == "O" || token[3] == "o") parity = 2;
00067
00068 if (parity == -1) return Port::UnknownParity;
00069 if (stopBits != 1 && stopBits != 2) return Port::UnknownStopBits;
00070
00071 tcflag_t cflag = CREAD | CLOCAL;
00072
00073 if (stopBits == 2)
00074 {
00075 cflag |= CSTOPB;
00076 }
00077
00078 switch (bits)
00079 {
00080 case 5:
00081 cflag |= CS5;
00082 break;
00083 case 6:
00084 cflag |= CS6;
00085 break;
00086 case 7:
00087 cflag |= CS7;
00088 break;
00089 case 8:
00090 cflag |= CS8;
00091 break;
00092 default:
00093 return Port::UnknownNumberOfBits;
00094 }
00095
00096 switch (parity)
00097 {
00098 case 0:
00099 break;
00100 case 1:
00101 cflag |= PARENB;
00102 break;
00103 case 2:
00104 cflag |= PARENB;
00105 cflag |= PARODD;
00106 }
00107
00108 struct termios attr;
00109 int mdlns;
00110
00111 memset( &attr, 0, sizeof( struct termios ) );
00112
00113 m_handle = ::open( token[0].c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
00114
00115 if (-1 == m_handle)
00116 {
00117 switch (errno)
00118 {
00119 case EACCES:
00120 return Port::PermissionDenied;
00121 case ENXIO:
00122 case ENODEV:
00123 case ENOENT:
00124 return Port::NoSuchPort;
00125 default:
00126 return Port::OpenError;
00127 }
00128 }
00129
00130 fcntl( m_handle, F_SETFL, 0 );
00131 tcgetattr( m_handle, &m_oldSettings );
00132
00133 attr.c_oflag = 0;
00134 attr.c_lflag = 0;
00135 attr.c_cflag = cflag;
00136
00137
00138
00139 if (0 == parity)
00140 {
00141 attr.c_iflag = IGNBRK | IGNPAR ;
00142 }
00143 else
00144 {
00145 attr.c_iflag = IGNBRK | INPCK | ISTRIP;
00146 }
00147
00148 attr.c_cc[VTIME]= 0;
00149 attr.c_cc[VMIN]= 1;
00150
00151 if (300 == baud)
00152 {
00153 cfsetospeed( &attr, B300 );
00154 cfsetispeed( &attr, B300 );
00155 }
00156 else if (600 == baud)
00157 {
00158 cfsetospeed( &attr, B600 );
00159 cfsetispeed( &attr, B600 );
00160 }
00161 else if (1200 == baud)
00162 {
00163 cfsetospeed( &attr, B1200 );
00164 cfsetispeed( &attr, B1200 );
00165 }
00166 else if (1800 == baud)
00167 {
00168 cfsetospeed( &attr, B1800 );
00169 cfsetispeed( &attr, B1800 );
00170 }
00171 else if (2400 == baud)
00172 {
00173 cfsetospeed( &attr, B2400 );
00174 cfsetispeed( &attr, B2400 );
00175 }
00176 else if (4800 == baud)
00177 {
00178 cfsetospeed( &attr, B4800 );
00179 cfsetispeed( &attr, B4800 );
00180 }
00181 else if (9600 == baud)
00182 {
00183 cfsetospeed( &attr, B9600 );
00184 cfsetispeed( &attr, B9600 );
00185 }
00186 else if (19200 == baud)
00187 {
00188 cfsetospeed( &attr, B19200 );
00189 cfsetispeed( &attr, B19200 );
00190 }
00191 else
00192 {
00193 cfsetospeed( &attr, B38400 );
00194 cfsetispeed( &attr, B38400 );
00195 }
00196
00197 if (-1 == tcsetattr( m_handle, TCSANOW, &attr ))
00198 {
00199 goto config_error;
00200 }
00201
00202 mdlns = 0;
00203 if (-1 == ioctl( m_handle, TIOCMGET, &mdlns ))
00204 {
00205 goto config_error;
00206 }
00207
00208 if (rts) mdlns |= TIOCM_RTS;
00209 else mdlns &= ~TIOCM_RTS;
00210
00211 if (dtr) mdlns |= TIOCM_DTR;
00212 else mdlns &= ~TIOCM_DTR;
00213
00214 if (dsr) mdlns |= TIOCM_DSR;
00215 else mdlns &= ~TIOCM_DSR;
00216
00217 if (cts) mdlns |= TIOCM_CTS;
00218 else mdlns &= ~TIOCM_CTS;
00219
00220 if (-1 == ioctl( m_handle, TIOCMSET, &mdlns ))
00221 {
00222 goto config_error;
00223 }
00224
00225 tcsetattr( m_handle, TCSAFLUSH, &attr );
00226
00227 return Port::Ok;
00228
00229 config_error:
00230 ::close(m_handle);
00231 m_handle = -1;
00232
00233 return Port::ConfigError;
00234 }
00235
00236 Port::Error SerialPort::close()
00237 {
00238 if (-1 != m_handle)
00239 {
00240
00241 ::tcsetattr( m_handle, TCSANOW, &m_oldSettings );
00242 ::close( m_handle );
00243 m_handle = -1;
00244 }
00245
00246 return Port::Ok;
00247 }