00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArSerialConnection.h"
00029 #include "ArLog.h"
00030 #include "ariaUtil.h"
00031
00032
00033 AREXPORT ArSerialConnection::ArSerialConnection()
00034 {
00035 myPort = INVALID_HANDLE_VALUE;
00036 myBaudRate = 9600;
00037 myStatus = STATUS_NEVER_OPENED;
00038 myHardwareControl = false;
00039 buildStrMap();
00040 }
00041
00042 AREXPORT ArSerialConnection::~ArSerialConnection()
00043 {
00044 if (myPort != INVALID_HANDLE_VALUE)
00045 close();
00046 }
00047
00048 void ArSerialConnection::buildStrMap(void)
00049 {
00050 myStrMap[OPEN_COULD_NOT_OPEN_PORT] = "Could not open serial port.";
00051 myStrMap[OPEN_COULD_NOT_SET_UP_PORT] = "Could not set up serial port.";
00052 myStrMap[OPEN_INVALID_BAUD_RATE] = "Baud rate invalid, could not set baud on serial port.";
00053 myStrMap[OPEN_COULD_NOT_SET_BAUD] = "Could not set baud rate on serial port.";
00054 myStrMap[OPEN_ALREADY_OPEN] = "Serial port already open.";
00055 }
00056
00057 AREXPORT const char * ArSerialConnection::getOpenMessage(int messageNumber)
00058 {
00059 return myStrMap[messageNumber].c_str();
00060 }
00061
00062 AREXPORT bool ArSerialConnection::openSimple(void)
00063 {
00064 if (internalOpen() == 0)
00065 return true;
00066 else
00067 return false;
00068 }
00069
00076 AREXPORT void ArSerialConnection::setPort(const char *port)
00077 {
00078 if (port == NULL)
00079 myPortName = "COM1";
00080 else
00081 myPortName = port;
00082 }
00083
00087 AREXPORT const char * ArSerialConnection::getPort(void)
00088 {
00089 return myPortName.c_str();
00090 }
00091
00098 AREXPORT int ArSerialConnection::open(const char *port)
00099 {
00100 setPort(port);
00101 return internalOpen();
00102 }
00103
00104
00105
00106 AREXPORT int ArSerialConnection::internalOpen(void)
00107 {
00108 DCB dcb;
00109
00110
00111 if (myStatus == STATUS_OPEN)
00112 {
00113 ArLog::log(ArLog::Terse,
00114 "ArSerialConnection::open: Serial port already open");
00115 return OPEN_ALREADY_OPEN;
00116 }
00117
00118 myPort = CreateFile(myPortName.c_str(),
00119 GENERIC_READ | GENERIC_WRITE,
00120 0,
00121 NULL,
00122 OPEN_EXISTING,
00123 0,
00124 NULL );
00125
00126 if (myPort == INVALID_HANDLE_VALUE) {
00127 ArLog::log(ArLog::Terse,
00128 "ArSerialConnection::open: Could not open serial port '%s'",
00129 myPortName.c_str());
00130 return OPEN_COULD_NOT_OPEN_PORT;
00131 }
00132
00133 if ( !GetCommState(myPort, &dcb) )
00134 {
00135 ArLog::log(ArLog::Terse,
00136 "ArSerialConnection::open: Could not get port data to set up port");
00137 close();
00138 myStatus = STATUS_OPEN_FAILED;
00139 return OPEN_COULD_NOT_SET_UP_PORT;
00140 }
00141
00142 dcb.ByteSize = 8;
00143 dcb.Parity = NOPARITY;
00144 dcb.StopBits = ONESTOPBIT;
00145 dcb.fOutxCtsFlow = FALSE;
00146 dcb.fOutxDsrFlow = 0;
00147 dcb.fBinary = TRUE;
00148 dcb.fParity = FALSE;
00149 dcb.fNull = FALSE;
00150 dcb.fOutX = FALSE;
00151 dcb.fInX = FALSE;
00152
00153 if ( !SetCommState(myPort, &dcb) )
00154 {
00155 ArLog::log(ArLog::Terse,
00156 "ArSerialConnection::open: Could not set up port");
00157 close();
00158 myStatus = STATUS_OPEN_FAILED;
00159 return OPEN_COULD_NOT_SET_UP_PORT;
00160 }
00161
00162 myStatus = STATUS_OPEN;
00163
00164 if (!setBaud(myBaudRate))
00165 {
00166 ArLog::log(ArLog::Terse,
00167 "ArSerialConnection::open: Could not set baud rate.");
00168 close();
00169 myStatus = STATUS_OPEN_FAILED;
00170 return OPEN_COULD_NOT_SET_BAUD;
00171 }
00172
00173 if (!setHardwareControl(myHardwareControl))
00174 {
00175 ArLog::log(ArLog::Terse,
00176 "ArSerialConnection::open: Could not set hardware control.");
00177 close();
00178 myStatus = STATUS_OPEN_FAILED;
00179 return OPEN_COULD_NOT_SET_UP_PORT;
00180 }
00181
00182 ArLog::log(ArLog::Verbose,
00183 "ArSerialConnection::open: Successfully opened and configured serial port.");
00184 return 0;
00185 }
00186
00187
00188
00189 AREXPORT bool ArSerialConnection::close(void)
00190 {
00191 bool ret;
00192
00193 if (myPort == INVALID_HANDLE_VALUE)
00194 return true;
00195
00196
00197 SetCommMask( myPort, 0 ) ;
00198
00199 EscapeCommFunction( myPort, CLRDTR ) ;
00200
00201 PurgeComm( myPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
00202
00203 myStatus = STATUS_CLOSED_NORMALLY;
00204
00205 ret = CloseHandle( myPort ) ;
00206 if (ret)
00207 ArLog::log(ArLog::Verbose,
00208 "ArSerialConnection::close: Successfully closed serial port.");
00209 else
00210 ArLog::log(ArLog::Verbose,
00211 "ArSerialConnection::close: Unsuccessfully closed serial port.");
00212 myPort = (HANDLE) INVALID_HANDLE_VALUE;
00213 return ret;
00214 }
00215
00216 AREXPORT int ArSerialConnection::getBaud(void)
00217 {
00218 return myBaudRate;
00219 }
00220
00221 AREXPORT bool ArSerialConnection::setBaud(int baud)
00222 {
00223 DCB dcb;
00224
00225 myBaudRate = baud;
00226
00227 if (getStatus() != STATUS_OPEN)
00228 return true;
00229
00230 if ( !GetCommState(myPort, &dcb) )
00231 {
00232 ArLog::log(ArLog::Terse, "ArSerialConnection::setBaud: Could not get port Data.");
00233 return false;
00234 }
00235
00236 dcb.BaudRate = myBaudRate;
00237
00238 if ( !SetCommState(myPort, &dcb) )
00239 {
00240 ArLog::log(ArLog::Terse,
00241 "ArSerialConnection::setBaud: Could not set port Data.");
00242 return false;
00243 }
00244
00245 return true;
00246 }
00247
00248 AREXPORT bool ArSerialConnection::getHardwareControl(void)
00249 {
00250 return myHardwareControl;
00251 }
00252
00253 AREXPORT bool ArSerialConnection::setHardwareControl(bool hardwareControl)
00254 {
00255 DCB dcb;
00256
00257 myHardwareControl = hardwareControl;
00258
00259 if (getStatus() != STATUS_OPEN)
00260 return true;
00261
00262 if ( !GetCommState(myPort, &dcb) )
00263 {
00264 ArLog::log(ArLog::Terse,
00265 "ArSerialConnection::setBaud: Could not get port Data.");
00266 return false;
00267 }
00268
00269 if (myHardwareControl == 0)
00270 {
00271 dcb.fRtsControl = RTS_CONTROL_ENABLE;
00272 dcb.fDtrControl = DTR_CONTROL_ENABLE;
00273 }
00274 else
00275 {
00276 dcb.fRtsControl = RTS_CONTROL_DISABLE;
00277 dcb.fDtrControl = DTR_CONTROL_DISABLE;
00278 }
00279
00280 if ( !SetCommState(myPort, &dcb) )
00281 {
00282 ArLog::log(ArLog::Terse, "ArSerialConnection::setBaud: Could not set port Data.");
00283 return false;
00284 }
00285
00286 return true;
00287 }
00288
00289 AREXPORT int ArSerialConnection::write(const char *data, unsigned int size)
00290 {
00291 unsigned long ret;
00292
00293 if (myPort != INVALID_HANDLE_VALUE && myStatus == STATUS_OPEN)
00294 {
00295 if (!WriteFile(myPort, data, size, &ret, NULL))
00296 {
00297 ArLog::log(ArLog::Terse, "ArSerialConnection::write: Error on writing.");
00298 perror("ArSerialConnection::write:");
00299 return -1;
00300 }
00301 return ret;
00302 }
00303 ArLog::log(ArLog::Terse, "ArSerialConnection::write: Connection invalid.");
00304 return -1;
00305 }
00306
00307 AREXPORT int ArSerialConnection::read(const char *data, unsigned int size,
00308 unsigned int msWait)
00309 {
00310 COMSTAT stat;
00311 unsigned long ret;
00312 unsigned int numToRead;
00313 ArTime timeDone;
00314
00315 if (myPort != INVALID_HANDLE_VALUE && myStatus == STATUS_OPEN)
00316 {
00317 if (msWait > 0)
00318 {
00319 timeDone.setToNow();
00320 timeDone.addMSec(msWait);
00321 while (timeDone.mSecTo() >= 0)
00322 {
00323 if (!ClearCommError(myPort, &ret, &stat))
00324 return -1;
00325 if (stat.cbInQue < size)
00326 ArUtil::sleep(2);
00327 else
00328 break;
00329 }
00330 }
00331 if (!ClearCommError(myPort, &ret, &stat))
00332 return -1;
00333 if (stat.cbInQue == 0)
00334 return 0;
00335 if (stat.cbInQue > size)
00336 numToRead = size;
00337 else
00338 numToRead = stat.cbInQue;
00339 if (ReadFile( myPort, (void *)data, numToRead, &ret, NULL))
00340 {
00341 return (int)ret;
00342 }
00343 else
00344 {
00345 ArLog::log(ArLog::Terse, "ArSerialConnection::read: Read failed.");
00346 return -1;
00347 }
00348 }
00349 ArLog::log(ArLog::Terse, "ArSerialConnection::read: Connection invalid.");
00350 return -1;
00351 }
00352
00353
00354 AREXPORT int ArSerialConnection::getStatus(void)
00355 {
00356 return myStatus;
00357 }
00358
00359 AREXPORT bool ArSerialConnection::isTimeStamping(void)
00360 {
00361 return false;
00362 }
00363
00364 AREXPORT ArTime ArSerialConnection::getTimeRead(int index)
00365 {
00366 ArTime now;
00367 now.setToNow();
00368 return now;
00369 }
00370
00371 AREXPORT bool ArSerialConnection::getCTS(void)
00372 {
00373 DWORD modemStat;
00374 if (GetCommModemStatus(myPort, &modemStat))
00375 {
00376 return (bool) (modemStat & MS_CTS_ON);
00377 }
00378 else
00379 {
00380 fprintf(stderr, "problem with GetCommModemStatus\n");
00381 return false;
00382 }
00383 }
00384
00385 AREXPORT bool ArSerialConnection::getDSR(void)
00386 {
00387 DWORD modemStat;
00388 if (GetCommModemStatus(myPort, &modemStat))
00389 {
00390 return (bool) (modemStat & MS_DSR_ON);
00391 }
00392 else
00393 {
00394 fprintf(stderr, "problem with GetCommModemStatus\n");
00395 return false;
00396 }
00397 }
00398
00399 AREXPORT bool ArSerialConnection::getDCD(void)
00400 {
00401 DWORD modemStat;
00402 if (GetCommModemStatus(myPort, &modemStat))
00403 {
00404 return (bool) (modemStat & MS_RLSD_ON);
00405 }
00406 else
00407 {
00408 fprintf(stderr, "problem with GetCommModemStatus\n");
00409 return false;
00410 }
00411 }
00412
00413 AREXPORT bool ArSerialConnection::getRing(void)
00414 {
00415 DWORD modemStat;
00416 if (GetCommModemStatus(myPort, &modemStat))
00417 {
00418 return (bool) (modemStat & MS_RING_ON);
00419 }
00420 else
00421 {
00422 fprintf(stderr, "problem with GetCommModemStatus\n");
00423 return false;
00424 }
00425 }
00426