00001
00018 #include "serialib.h"
00019
00020
00021
00022
00026
00027 serialib::serialib()
00028 {}
00029
00030
00034
00035 serialib::~serialib()
00036 {
00037 Close();
00038 }
00039
00040
00041
00042
00043
00044
00045
00046
00090 char serialib::Open(const char *Device,const unsigned int Bauds)
00091 {
00092 #if defined (_WIN32) || defined( _WIN64)
00093
00094
00095 hSerial = CreateFileA( Device,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
00096 if(hSerial==INVALID_HANDLE_VALUE) {
00097 if(GetLastError()==ERROR_FILE_NOT_FOUND)
00098 return -1;
00099 return -2;
00100 }
00101
00102
00103 DCB dcbSerialParams = {0};
00104 dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
00105 if (!GetCommState(hSerial, &dcbSerialParams))
00106 return -3;
00107 switch (Bauds)
00108 {
00109 case 110 : dcbSerialParams.BaudRate=CBR_110; break;
00110 case 300 : dcbSerialParams.BaudRate=CBR_300; break;
00111 case 600 : dcbSerialParams.BaudRate=CBR_600; break;
00112 case 1200 : dcbSerialParams.BaudRate=CBR_1200; break;
00113 case 2400 : dcbSerialParams.BaudRate=CBR_2400; break;
00114 case 4800 : dcbSerialParams.BaudRate=CBR_4800; break;
00115 case 9600 : dcbSerialParams.BaudRate=CBR_9600; break;
00116 case 14400 : dcbSerialParams.BaudRate=CBR_14400; break;
00117 case 19200 : dcbSerialParams.BaudRate=CBR_19200; break;
00118 case 38400 : dcbSerialParams.BaudRate=CBR_38400; break;
00119 case 56000 : dcbSerialParams.BaudRate=CBR_56000; break;
00120 case 57600 : dcbSerialParams.BaudRate=CBR_57600; break;
00121 case 115200 : dcbSerialParams.BaudRate=CBR_115200; break;
00122 case 128000 : dcbSerialParams.BaudRate=CBR_128000; break;
00123 case 256000 : dcbSerialParams.BaudRate=CBR_256000; break;
00124 default : return -4;
00125 }
00126 dcbSerialParams.ByteSize=8;
00127 dcbSerialParams.StopBits=ONESTOPBIT;
00128 dcbSerialParams.Parity=NOPARITY;
00129 if(!SetCommState(hSerial, &dcbSerialParams))
00130 return -5;
00131
00132
00133 timeouts.ReadIntervalTimeout=0;
00134 timeouts.ReadTotalTimeoutConstant=MAXDWORD;
00135 timeouts.ReadTotalTimeoutMultiplier=0;
00136 timeouts.WriteTotalTimeoutConstant=MAXDWORD;
00137 timeouts.WriteTotalTimeoutMultiplier=0;
00138 if(!SetCommTimeouts(hSerial, &timeouts))
00139 return -6;
00140 return 1;
00141
00142 #endif
00143 #ifdef __linux__
00144 struct termios options;
00145
00146
00147
00148 fd = open(Device, O_RDWR | O_NOCTTY | O_NDELAY);
00149 if (fd == -1) return -2;
00150 fcntl(fd, F_SETFL, FNDELAY);
00151
00152
00153 tcgetattr(fd, &options);
00154 bzero(&options, sizeof(options));
00155 speed_t Speed;
00156 switch (Bauds)
00157 {
00158 case 110 : Speed=B110; break;
00159 case 300 : Speed=B300; break;
00160 case 600 : Speed=B600; break;
00161 case 1200 : Speed=B1200; break;
00162 case 2400 : Speed=B2400; break;
00163 case 4800 : Speed=B4800; break;
00164 case 9600 : Speed=B9600; break;
00165 case 19200 : Speed=B19200; break;
00166 case 38400 : Speed=B38400; break;
00167 case 57600 : Speed=B57600; break;
00168 case 115200 : Speed=B115200; break;
00169 default : return -4;
00170 }
00171 cfsetispeed(&options, Speed);
00172 cfsetospeed(&options, Speed);
00173 options.c_cflag |= ( CLOCAL | CREAD | CS8);
00174 options.c_iflag |= ( IGNPAR | IGNBRK );
00175 options.c_cc[VTIME]=0;
00176 options.c_cc[VMIN]=0;
00177 tcsetattr(fd, TCSANOW, &options);
00178 return (1);
00179 #endif
00180 }
00181
00182
00186 void serialib::Close()
00187 {
00188 #if defined (_WIN32) || defined( _WIN64)
00189 CloseHandle(hSerial);
00190 #endif
00191 #ifdef __linux__
00192 close (fd);
00193 #endif
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00210 char serialib::WriteChar(const char Byte)
00211 {
00212 #if defined (_WIN32) || defined( _WIN64)
00213 DWORD dwBytesWritten;
00214 if(!WriteFile(hSerial,&Byte,1,&dwBytesWritten,NULL))
00215 return -1;
00216 return 1;
00217 #endif
00218 #ifdef __linux__
00219 if (write(fd,&Byte,1)!=1)
00220 return -1;
00221 return 1;
00222 #endif
00223 }
00224
00225
00226
00227
00228
00229
00230
00237 char serialib::WriteString(const char *String)
00238 {
00239 #if defined (_WIN32) || defined( _WIN64)
00240 DWORD dwBytesWritten;
00241 if(!WriteFile(hSerial,String,strlen(String),&dwBytesWritten,NULL))
00242 return -1;
00243 return 1;
00244 #endif
00245 #ifdef __linux__
00246 int Lenght=strlen(String);
00247 if (write(fd,String,Lenght)!=Lenght)
00248 return -1;
00249 return 1;
00250 #endif
00251 }
00252
00253
00254
00255
00256
00257
00265 char serialib::Write(const void *Buffer, const unsigned int NbBytes)
00266 {
00267 #if defined (_WIN32) || defined( _WIN64)
00268 DWORD dwBytesWritten;
00269 if(!WriteFile(hSerial, Buffer, NbBytes, &dwBytesWritten, NULL))
00270 return -1;
00271 return 1;
00272 #endif
00273 #ifdef __linux__
00274 if (write (fd,Buffer,NbBytes)!=(ssize_t)NbBytes)
00275 return -1;
00276 return 1;
00277 #endif
00278 }
00279
00280
00281
00292 char serialib::ReadChar(char *pByte,unsigned int TimeOut_ms)
00293 {
00294 #if defined (_WIN32) || defined(_WIN64)
00295
00296 DWORD dwBytesRead = 0;
00297 timeouts.ReadTotalTimeoutConstant=TimeOut_ms;
00298 if(!SetCommTimeouts(hSerial, &timeouts))
00299 return -1;
00300 if(!ReadFile(hSerial,pByte, 1, &dwBytesRead, NULL))
00301 return -2;
00302 if (dwBytesRead==0) return 0;
00303 return 1;
00304 #endif
00305 #ifdef __linux__
00306 TimeOut Timer;
00307 Timer.InitTimer();
00308 while (Timer.ElapsedTime_ms()<TimeOut_ms || TimeOut_ms==0)
00309 {
00310 switch (read(fd,pByte,1)) {
00311 case 1 : return 1;
00312 case -1 : return -2;
00313 }
00314 }
00315 return 0;
00316 #endif
00317 }
00318
00319
00320
00331 int serialib::ReadStringNoTimeOut(char *String,char FinalChar,unsigned int MaxNbBytes)
00332 {
00333 unsigned int NbBytes=0;
00334 char ret;
00335 while (NbBytes<MaxNbBytes)
00336 {
00337 ret=ReadChar(&String[NbBytes]);
00338 if (ret==1)
00339 {
00340 if (String[NbBytes]==FinalChar)
00341 {
00342 String [++NbBytes]=0;
00343 return NbBytes;
00344 }
00345 NbBytes++;
00346 }
00347 if (ret<0) return ret;
00348 }
00349 return -3;
00350 }
00351
00364 int serialib::ReadString(char *String,char FinalChar,unsigned int MaxNbBytes,unsigned int TimeOut_ms)
00365 {
00366 if (TimeOut_ms==0)
00367 return ReadStringNoTimeOut(String,FinalChar,MaxNbBytes);
00368
00369 unsigned int NbBytes=0;
00370 char ret;
00371 TimeOut Timer;
00372 long int TimeOutParam;
00373 Timer.InitTimer();
00374
00375 while (NbBytes<MaxNbBytes)
00376 {
00377 TimeOutParam=TimeOut_ms-Timer.ElapsedTime_ms();
00378 if (TimeOutParam>0)
00379 {
00380 ret=ReadChar(&String[NbBytes],TimeOutParam);
00381 if (ret==1)
00382 {
00383
00384 if (String[NbBytes]==FinalChar)
00385 {
00386 String [++NbBytes]=0;
00387 return NbBytes;
00388 }
00389 NbBytes++;
00390 }
00391 if (ret<0) return ret;
00392 }
00393 if (Timer.ElapsedTime_ms()>TimeOut_ms) {
00394 String[NbBytes]=0;
00395 return 0;
00396 }
00397 }
00398 return -3;
00399 }
00400
00401
00412 int serialib::Read (void *Buffer,unsigned int MaxNbBytes,unsigned int TimeOut_ms)
00413 {
00414 #if defined (_WIN32) || defined(_WIN64)
00415 DWORD dwBytesRead = 0;
00416 timeouts.ReadTotalTimeoutConstant=(DWORD)TimeOut_ms;
00417 if(!SetCommTimeouts(hSerial, &timeouts))
00418 return -1;
00419 if(!ReadFile(hSerial,Buffer,(DWORD)MaxNbBytes,&dwBytesRead, NULL))
00420 return -2;
00421 if (dwBytesRead!=(DWORD)MaxNbBytes) return 0;
00422 return 1;
00423 #endif
00424 #ifdef __linux__
00425 TimeOut Timer;
00426 Timer.InitTimer();
00427 unsigned int NbByteRead=0;
00428 while (Timer.ElapsedTime_ms()<TimeOut_ms || TimeOut_ms==0)
00429 {
00430 unsigned char* Ptr=(unsigned char*)Buffer+NbByteRead;
00431 int Ret=read(fd,(void*)Ptr,MaxNbBytes-NbByteRead);
00432 if (Ret==-1) return -2;
00433 if (Ret>0) {
00434 NbByteRead+=Ret;
00435 if (NbByteRead>=MaxNbBytes)
00436 return 1;
00437 }
00438 }
00439 return 0;
00440 #endif
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00455 void serialib::FlushReceiver()
00456 {
00457 #ifdef __linux__
00458 tcflush(fd,TCIFLUSH);
00459 #endif
00460 }
00461
00462
00463
00468 int serialib::Peek()
00469 {
00470 int Nbytes=0;
00471 #ifdef __linux__
00472 ioctl(fd, FIONREAD, &Nbytes);
00473 #endif
00474 return Nbytes;
00475 }
00476
00477
00478
00479
00480
00481
00485
00486 TimeOut::TimeOut()
00487 {}
00488
00492
00493 void TimeOut::InitTimer()
00494 {
00495 gettimeofday(&PreviousTime, NULL);
00496 }
00497
00503
00504 unsigned long int TimeOut::ElapsedTime_ms()
00505 {
00506 struct timeval CurrentTime;
00507 int sec,usec;
00508 gettimeofday(&CurrentTime, NULL);
00509 sec=CurrentTime.tv_sec-PreviousTime.tv_sec;
00510 usec=CurrentTime.tv_usec-PreviousTime.tv_usec;
00511 if (usec<0) {
00512 usec=1000000-PreviousTime.tv_usec+CurrentTime.tv_usec;
00513 sec--;
00514 }
00515 return sec*1000+usec/1000;
00516 }
00517