00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdio.h>
00018 #include <string.h>
00019 #include <errno.h>
00020
00021 #ifdef LINUX
00022 #include <sys/socket.h>
00023 #include <netinet/in.h>
00024 #include <arpa/inet.h>
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <sys/file.h>
00028 #include <sys/ioctl.h>
00029 #include <fcntl.h>
00030 #include <unistd.h>
00031 #include <stropts.h>
00032 #include <termios.h>
00033 #include <linux/serial.h>
00034 #endif
00035
00036 #include "com_phy_layer.h"
00037
00038 #ifdef LINUX
00039
00040 #endif
00041
00042
00043
00044 #define MAX_SOCKET_CONNECTIONS 1
00045
00046
00047
00048
00049 #ifndef CDTRDSR
00050 #define CDTRDSR 004000000000
00051 #endif
00052 #define CPL_RX_TIMEOUT_MSEC 10
00053
00054
00055
00056 #if defined( LINUX)
00057 #define CPL_LOCK( pCPLObj) pthread_mutex_lock( &pCPLObj->m_mutex);
00058 #define CPL_UNLOCK( pCPLObj) pthread_mutex_unlock( &pCPLObj->m_mutex);
00059 #elif defined( WIN32)
00060 #define CPL_LOCK( pCPLObj) WaitForSingleObject( pCPLObj->m_mutex, INFINITE);
00061 #define CPL_UNLOCK( pCPLObj) ReleaseMutex( pCPLObj->m_mutex);
00062 #else
00063 ???
00064 #endif
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 static BOOL CPL_OpenCom( CPL_OBJ* pCPLObj);
00080 static BOOL CPL_OpenEth( CPL_OBJ* pCPLObj);
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 void CPL_BiosInit( CPL_OBJ* pCPLObj )
00095 {
00096
00097 memset( pCPLObj, 0, sizeof( CPL_OBJ));
00098
00099 pCPLObj->m_comm.m_tag= INVALID_HANDLE_VALUE;
00100 #if defined( LINUX)
00101 pthread_mutex_init( &pCPLObj->m_mutex, 0);
00102 #elif defined( WIN32)
00103 pCPLObj->m_mutex= CreateMutex(NULL, FALSE, "CPL_MUTEX");
00104 #else
00105 ???
00106 #endif
00107
00108
00109 CPL_Flush( pCPLObj, BOTH_BUFFER );
00110
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120 static BOOL CPL_OpenCom( CPL_OBJ* pCPLObj)
00121 {
00122 #ifdef LINUX
00123 struct termios info;
00124 #endif
00125
00126
00127 CPL_Flush( pCPLObj, BOTH_BUFFER );
00128
00129 #if defined( LINUX)
00130 if( ( pCPLObj->m_comm.m_serial= open ( pCPLObj->m_config.m_device_config.m_com_device.m_com_str, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL))< 0)
00131 {
00132 pCPLObj->m_comm.m_serial= INVALID_HANDLE_VALUE;
00133 return FALSE;
00134 }
00135 #elif defined( WIN32)
00136 if( ( pCPLObj->m_comm.m_serial= CreateFile( pCPLObj->m_config.m_device_config.m_com_device.m_com_str, GENERIC_READ| GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))== INVALID_HANDLE_VALUE)
00137 {
00138 pCPLObj->m_comm.m_serial= INVALID_HANDLE_VALUE;
00139 return FALSE;
00140 }
00141 #endif
00142
00143 #ifdef CPL_LOCK_DEVICE
00144 if (flock (pCPLObj->m_comm.m_serial, LOCK_EX|LOCK_NB) == -1)
00145 {
00146 close ( pCPLObj->m_comm.m_serial);
00147 pCPLObj->m_comm.m_serial= INVALID_HANDLE_VALUE;
00148 return FALSE;
00149 }
00150 #endif
00151
00152
00153 #if defined( LINUX)
00154 fcntl ( pCPLObj->m_comm.m_serial, F_SETFL, FNDELAY);
00155
00156 tcgetattr ( pCPLObj->m_comm.m_serial, &info);
00157 switch( pCPLObj->m_config.m_device_config.m_com_device.m_baudrate)
00158 {
00159 case SERBAUD_9600:
00160 cfsetispeed (&info, B9600);
00161 break;
00162 case SERBAUD_19200:
00163 cfsetispeed (&info, B19200);
00164 break;
00165 case SERBAUD_38400:
00166 cfsetispeed (&info, B38400);
00167 break;
00168 case SERBAUD_57600:
00169 cfsetispeed (&info, B57600);
00170 break;
00171 case SERBAUD_115200:
00172 cfsetispeed (&info, B115200);
00173 break;
00174 default:
00175 return FALSE;
00176 }
00177 info.c_cflag |= (CLOCAL | CREAD);
00178 info.c_cflag &= ~CSIZE;
00179 switch( pCPLObj->m_config.m_device_config.m_com_device.m_dataBit)
00180 {
00181 case DATA_SEVEN:
00182 info.c_cflag |= CS7;
00183 break;
00184 case DATA_EIGHT:
00185 info.c_cflag |= CS8;
00186 break;
00187 default:
00188 return FALSE;
00189 }
00190 switch( pCPLObj->m_config.m_device_config.m_com_device.m_stopBit)
00191 {
00192 case STOP_ONE:
00193 info.c_cflag &= ~CSTOPB;
00194 break;
00195 case STOP_TWO:
00196 info.c_cflag |= CSTOPB;
00197 break;
00198 default:
00199 return FALSE;
00200 }
00201 switch( pCPLObj->m_config.m_device_config.m_com_device.m_parity)
00202 {
00203 case SERPARITY_NONE:
00204 break;
00205 case SERPARITY_EVEN:
00206 info.c_cflag |= PARENB;
00207 break;
00208 case SERPARITY_ODD:
00209 info.c_cflag |= PARODD;
00210 break;
00211 default:
00212 return FALSE;
00213 }
00214
00215 info.c_lflag &= ~(ICANON | ECHO
00216 | ECHOE | ISIG);
00217 info.c_iflag = INPCK;
00218 info.c_oflag = 0;
00219 switch( pCPLObj->m_config.m_device_config.m_com_device.m_RTSFlow)
00220 {
00221 case RTS_DISABLE:
00222 break;
00223 case RTS_HANDSHAKE:
00224 info.c_cflag |= CRTSCTS;
00225 break;
00226 default:
00227 return FALSE;
00228 }
00229 switch( pCPLObj->m_config.m_device_config.m_com_device.m_DTRFlow)
00230 {
00231 case DTR_DISABLE:
00232 break;
00233 case DTR_HANDSHAKE:
00234 info.c_cflag |= CDTRDSR;
00235 break;
00236 default:
00237 return FALSE;
00238 }
00239 tcsetattr ( pCPLObj->m_comm.m_serial, TCSAFLUSH, &info);
00240
00241 {
00242 struct serial_struct serial_info;
00243
00244 ioctl( pCPLObj->m_comm.m_serial, TIOCGSERIAL, &serial_info);
00245 serial_info.flags |= ASYNC_LOW_LATENCY;
00246 ioctl( pCPLObj->m_comm.m_serial, TIOCSSERIAL, &serial_info);
00247 }
00248 #elif defined( WIN32)
00249 {
00250 DCB dcb;
00251 COMMTIMEOUTS comm_time_outs;
00252
00253
00254 comm_time_outs.ReadIntervalTimeout = 0xFFFFFFFF ;
00255 comm_time_outs.ReadTotalTimeoutMultiplier = 0 ;
00256 comm_time_outs.ReadTotalTimeoutConstant = 0 ;
00257 comm_time_outs.WriteTotalTimeoutMultiplier = 40;
00258 comm_time_outs.WriteTotalTimeoutConstant = 1000 ;
00259 SetCommTimeouts( pCPLObj->m_comm.m_serial, &comm_time_outs ) ;
00260
00261
00262 SetupComm( pCPLObj->m_comm.m_serial, 1024, 1024);
00263
00264 memset( &dcb, 0, sizeof( DCB));
00265 dcb.DCBlength = sizeof (DCB);
00266
00267 switch( pCPLObj->m_config.m_device_config.m_com_device.m_baudrate)
00268 {
00269 case SERBAUD_9600:
00270 dcb.BaudRate= CBR_9600;
00271 break;
00272 case SERBAUD_19200:
00273 dcb.BaudRate= CBR_19200;
00274 break;
00275 case SERBAUD_38400:
00276 dcb.BaudRate= CBR_38400;
00277 break;
00278 case SERBAUD_57600:
00279 dcb.BaudRate= CBR_57600;
00280 break;
00281 case SERBAUD_115200:
00282 dcb.BaudRate= CBR_115200;
00283 break;
00284 default:
00285 return FALSE;
00286 }
00287 switch( pCPLObj->m_config.m_device_config.m_com_device.m_dataBit)
00288 {
00289 case DATA_SEVEN:
00290 dcb.ByteSize= 7;
00291 break;
00292 case DATA_EIGHT:
00293 dcb.ByteSize= 8;
00294 break;
00295 default:
00296 return FALSE;
00297 }
00298 switch( pCPLObj->m_config.m_device_config.m_com_device.m_stopBit)
00299 {
00300 case STOP_ONE:
00301 dcb.StopBits= ONESTOPBIT;
00302 break;
00303 case STOP_TWO:
00304 dcb.StopBits= TWOSTOPBITS;
00305 break;
00306 default:
00307 return FALSE;
00308 }
00309
00310 switch( pCPLObj->m_config.m_device_config.m_com_device.m_parity)
00311 {
00312 case SERPARITY_NONE:
00313 dcb.Parity= NOPARITY;
00314 dcb.fParity= FALSE;
00315 break;
00316 case SERPARITY_EVEN:
00317 dcb.Parity= EVENPARITY;
00318 dcb.fParity= TRUE;
00319 break;
00320 case SERPARITY_ODD:
00321 dcb.Parity= ODDPARITY;
00322 dcb.fParity= TRUE;
00323 break;
00324 default:
00325 return FALSE;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 dcb.fBinary = TRUE;
00338 switch( pCPLObj->m_config.m_device_config.m_com_device.m_RTSFlow)
00339 {
00340 case RTS_DISABLE:
00341 dcb.fRtsControl= RTS_CONTROL_DISABLE;
00342 break;
00343 case RTS_HANDSHAKE:
00344 dcb.fRtsControl= RTS_CONTROL_HANDSHAKE;
00345 dcb.fOutxCtsFlow= TRUE;
00346 break;
00347 default:
00348 return FALSE;
00349 }
00350 switch( pCPLObj->m_config.m_device_config.m_com_device.m_DTRFlow)
00351 {
00352 case DTR_DISABLE:
00353 dcb.fDtrControl= DTR_CONTROL_DISABLE;
00354 break;
00355 case DTR_HANDSHAKE:
00356 dcb.fDtrControl= DTR_CONTROL_HANDSHAKE;
00357 dcb.fOutxDsrFlow = TRUE;
00358 dcb.fDsrSensitivity = TRUE;
00359 break;
00360 default:
00361 return FALSE;
00362 }
00363 SetCommState( pCPLObj->m_comm.m_serial, &dcb);
00364
00365 FlushFileBuffers( pCPLObj->m_comm.m_serial);
00366 }
00367 #else
00368 ???
00369 #endif
00370 return TRUE;
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 BOOL CPL_Reconnect( CPL_OBJ* pCPLObj)
00382 {
00383 switch( pCPLObj->m_config.m_device)
00384 {
00385 case CPL_COM:
00386 if( pCPLObj->m_comm.m_serial== INVALID_HANDLE_VALUE)
00387 {
00388 return CPL_OpenCom( pCPLObj);
00389 }
00390 return TRUE;
00391 case CPL_ETH:
00392
00393 CPL_Close( pCPLObj);
00394 return CPL_OpenEth( pCPLObj);
00395 }
00396 return FALSE;
00397
00398 }
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 static BOOL CPL_OpenEth( CPL_OBJ* pCPLObj)
00409 {
00410 CPL_Flush( pCPLObj, BOTH_BUFFER );
00411 pCPLObj->m_comm.m_socket= socket( AF_INET, SOCK_STREAM, 0);
00412 if( ( pCPLObj->m_comm.m_socket< 0)|| ( pCPLObj->m_comm.m_socket== INVALID_SOCKET))
00413 {
00414 pCPLObj->m_comm.m_socket= INVALID_SOCKET;
00415 return FALSE;
00416 }
00417
00418 #if defined ( LINUX)
00419 {
00420 int flags= fcntl( pCPLObj->m_comm.m_socket, F_GETFL);
00421 fcntl( pCPLObj->m_comm.m_socket, F_SETFL, flags| O_NONBLOCK);
00422 }
00423 #elif defined ( WIN32)
00424 {
00425 UINT32 timeout= 10;
00426 if( setsockopt( pCPLObj->m_comm.m_socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof( timeout))== SOCKET_ERROR)
00427 {
00428 closesocket( pCPLObj->m_comm.m_socket);
00429 pCPLObj->m_comm.m_socket= INVALID_SOCKET;
00430 return FALSE;
00431 }
00432 if( setsockopt( pCPLObj->m_comm.m_socket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof( timeout))== SOCKET_ERROR)
00433 {
00434 closesocket( pCPLObj->m_comm.m_socket);
00435 pCPLObj->m_comm.m_socket= INVALID_SOCKET;
00436 return FALSE;
00437 }
00438 }
00439 #else
00440 ???
00441 #endif
00442
00443 {
00444 struct sockaddr_in address;
00445 address.sin_family= AF_INET;
00446 address.sin_port= htons( pCPLObj->m_config.m_device_config.m_eth_device.m_port);
00447 address.sin_addr.s_addr= inet_addr( pCPLObj->m_config.m_device_config.m_eth_device.m_address);
00448 if( connect( pCPLObj->m_comm.m_socket, (struct sockaddr *)&address, sizeof( address))< 0)
00449 {
00450 #if defined( LINUX)
00451 close( pCPLObj->m_comm.m_socket);
00452 #elif defined( WIN32)
00453 closesocket( pCPLObj->m_comm.m_socket);
00454 #else
00455 ???
00456 #endif
00457 pCPLObj->m_comm.m_socket= INVALID_SOCKET;
00458 return FALSE;
00459 }
00460 }
00461 return TRUE;
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 BOOL CPL_Open( CPL_OBJ* pCPLObj, const CPLConfig* pConfig)
00473 {
00474
00475 CPL_Close( pCPLObj);
00476
00477 memcpy( &pCPLObj->m_config, pConfig, sizeof( CPLConfig));
00478
00479
00480 switch( pCPLObj->m_config.m_device)
00481 {
00482 case CPL_COM:
00483
00484 return CPL_OpenCom( pCPLObj);
00485 case CPL_ETH:
00486
00487 return CPL_OpenEth( pCPLObj);
00488 default:
00489 pCPLObj->m_comm.m_tag= INVALID_HANDLE_VALUE;
00490 return FALSE;
00491 }
00492 return TRUE;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 BOOL CPL_Close( CPL_OBJ* pCPLObj)
00624 {
00625 if (pCPLObj->m_comm.m_tag== INVALID_HANDLE_VALUE)
00626 return FALSE;
00627
00628
00629 switch( pCPLObj->m_config.m_device)
00630 {
00631 case CPL_COM:
00632 #if defined ( LINUX)
00633 close( pCPLObj->m_comm.m_serial);
00634 #elif defined ( WIN32)
00635 CloseHandle( pCPLObj->m_comm.m_serial);
00636 #else
00637 ???
00638 #endif
00639 #ifdef CPL_LOCK_DEVICE
00640 if (flock ( pCPLObj->m_comm.m_serial, LOCK_UN|LOCK_NB) == -1)
00641 {
00642 return FALSE;
00643 }
00644 #endif
00645 break;
00646 case CPL_ETH:
00647 #if defined ( LINUX)
00648 close( pCPLObj->m_comm.m_socket);
00649 #elif defined ( WIN32)
00650 closesocket( pCPLObj->m_comm.m_socket);
00651 #else
00652 #endif
00653 break;
00654 }
00655 pCPLObj->m_comm.m_tag= INVALID_HANDLE_VALUE;
00656 return TRUE;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 void CPL_Flush( CPL_OBJ* pCPLObj, CPLBufferType type )
00669 {
00670 switch ( type)
00671 {
00672 case TX_BUFFER:
00673 CPL_LOCK( pCPLObj);
00674 pCPLObj->m_wBuffTXLen= pCPLObj->m_wBuffTXIni= 0;
00675 CPL_UNLOCK( pCPLObj);
00676 break;
00677 case RX_BUFFER:
00678 switch( pCPLObj->m_config.m_device)
00679 {
00680 case CPL_COM:
00681 while( CPL_RX( pCPLObj, 1))
00682 Sleep( 300);
00683 CPL_LOCK( pCPLObj);
00684 pCPLObj->m_wBuffRXLen= 0;
00685 #if defined ( LINUX)
00686 ioctl ( pCPLObj->m_comm.m_serial, TCFLSH, 0);
00687 #elif defined ( WIN32)
00688 FlushFileBuffers( pCPLObj->m_comm.m_serial);
00689 #else
00690 ???
00691 #endif
00692 CPL_UNLOCK( pCPLObj);
00693 break;
00694 case CPL_ETH:
00695 CPL_LOCK( pCPLObj);
00696 pCPLObj->m_wBuffRXLen= 0;
00697 CPL_UNLOCK( pCPLObj);
00698 break;
00699 }
00700 case BOTH_BUFFER:
00701 switch( pCPLObj->m_config.m_device)
00702 {
00703 case CPL_COM:
00704 CPL_LOCK( pCPLObj);
00705 pCPLObj->m_wBuffTXIni= pCPLObj->m_wBuffTXLen= pCPLObj->m_wBuffRXLen= 0;
00706 #if defined ( LINUX)
00707 ioctl ( pCPLObj->m_comm.m_serial, TCFLSH, 0);
00708 #elif defined ( WIN32)
00709 FlushFileBuffers( pCPLObj->m_comm.m_serial);
00710 #else
00711 ???
00712 #endif
00713 CPL_UNLOCK( pCPLObj);
00714 break;
00715 case CPL_ETH:
00716 CPL_LOCK( pCPLObj);
00717 pCPLObj->m_wBuffTXIni= pCPLObj->m_wBuffTXLen= pCPLObj->m_wBuffRXLen= 0;
00718 CPL_UNLOCK( pCPLObj);
00719 break;
00720 }
00721 }
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 UINT8* CPL_GetBuffTX( CPL_OBJ* pCPLObj, UINT16 *wSize)
00735 {
00736
00737 UINT8* buff= NULL;
00738
00739 CPL_LOCK( pCPLObj);
00740 if(( !pCPLObj->m_wBuffTXIni)&& ( pCPLObj->m_wBuffTXLen< CPL_DIM_TX_BUFF))
00741 {
00742
00743 *wSize= CPL_DIM_TX_BUFF- pCPLObj->m_wBuffTXLen;
00744 buff= pCPLObj->m_bBuffTX+ pCPLObj->m_wBuffTXIni;
00745 }
00746 else
00747 {
00748
00749 *wSize= 0;
00750 }
00751 CPL_UNLOCK( pCPLObj);
00752 return buff;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 BOOL CPL_TX( CPL_OBJ* pCPLObj, UINT16 wCount)
00764 {
00765 int sent_bytes= 0;
00766 if( pCPLObj->m_comm.m_tag== INVALID_HANDLE_VALUE)
00767 {
00768 return FALSE;
00769 }
00770 if( ( !wCount)|| pCPLObj->m_wBuffTXIni)
00771 {
00772 return FALSE;
00773 }
00774
00775 pCPLObj->m_wBuffTXLen= wCount;
00776
00777
00778 switch( pCPLObj->m_config.m_device)
00779 {
00780 case CPL_COM:
00781 #if defined ( LINUX)
00782 sent_bytes= write( pCPLObj->m_comm.m_serial, pCPLObj->m_bBuffTX, wCount);
00783 #elif defined ( WIN32)
00784 WriteFile( pCPLObj->m_comm.m_serial, pCPLObj->m_bBuffTX, wCount, &sent_bytes, NULL );
00785 #else
00786 ???
00787 #endif
00788 break;
00789 case CPL_ETH:
00790 sent_bytes= send( pCPLObj->m_comm.m_socket, pCPLObj->m_bBuffTX, wCount, 0);
00791 break;
00792 }
00793 CPL_LOCK( pCPLObj);
00794 pCPLObj->m_wBuffTXIni+= sent_bytes;
00795 CPL_UNLOCK( pCPLObj);
00796 if ((sent_bytes < 0)||( (UINT16)sent_bytes< wCount))
00797 {
00798 return FALSE;
00799 }
00800 return TRUE;
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 const UINT8* CPL_GetBuffRX( CPL_OBJ* pCPLObj, UINT16 *wSize)
00812 {
00813 UINT8* buff= NULL;
00814
00815 CPL_LOCK( pCPLObj);
00816 if(pCPLObj->m_wBuffRXLen)
00817 {
00818
00819 *wSize= pCPLObj->m_wBuffRXLen;
00820 buff= pCPLObj->m_bBuffRX;
00821 }
00822 else
00823 {
00824
00825 *wSize= 0;
00826 }
00827 CPL_UNLOCK( pCPLObj);
00828 return buff;
00829 }
00830
00831
00832
00833
00834
00835
00836
00837
00838 BOOL CPL_IsDataReady( CPL_OBJ* pCPLObj)
00839 {
00840
00841 BOOL ret;
00842 CPL_LOCK( pCPLObj);
00843 ret= (( clock()> pCPLObj->m_rx_tout)&& ( pCPLObj->m_wBuffRXLen))? TRUE: FALSE;
00844 CPL_UNLOCK( pCPLObj);
00845 return ret;
00846 }
00847
00848
00849
00850
00851
00852
00853
00854
00855 BOOL CPL_RX( CPL_OBJ* pCPLObj, UINT16 wCount)
00856 {
00857 UINT32 read_bytes= 0;
00858 if( pCPLObj->m_comm.m_tag== INVALID_HANDLE_VALUE)
00859 {
00860 return FALSE;
00861 }
00862 if (wCount == 0)
00863 {
00864 return TRUE;
00865 }
00866 if ( wCount+ pCPLObj->m_wBuffRXLen>= CPL_DIM_RX_BUFF)
00867 {
00868 return FALSE;
00869 }
00870
00871 switch( pCPLObj->m_config.m_device)
00872 {
00873 case CPL_COM:
00874
00875 {
00876 int in_q;
00877 #if defined ( LINUX)
00878 ioctl( pCPLObj->m_comm.m_serial, FIONREAD, &in_q);
00879 #elif defined ( WIN32)
00880 COMSTAT cs;
00881 DWORD errorCode;
00882 ClearCommError( pCPLObj->m_comm.m_serial, &errorCode, &cs);
00883 if( errorCode & ( CE_OVERRUN| CE_RXOVER| CE_RXPARITY))
00884 {
00885 return FALSE;
00886 }
00887 in_q= cs.cbInQue;
00888 #else
00889 ???
00890 #endif
00891 if( in_q< wCount)
00892 {
00893 return FALSE;
00894 }
00895 pCPLObj->m_rx_tout= clock()+ (CPL_RX_TIMEOUT_MSEC* CLOCKS_PER_SEC)/ 1000;
00896
00897 #if defined ( LINUX)
00898 read_bytes= read( pCPLObj->m_comm.m_serial, pCPLObj->m_bBuffRX+ pCPLObj->m_wBuffRXLen, wCount);
00899 #elif defined ( WIN32)
00900
00901 if( !ReadFile( pCPLObj->m_comm.m_serial, pCPLObj->m_bBuffRX+ pCPLObj->m_wBuffRXLen, wCount, &read_bytes, NULL ))
00902 {
00903 if (GetLastError() == ERROR_IO_PENDING)
00904 {
00905 ClearCommError( pCPLObj->m_comm.m_serial, &errorCode, &cs);
00906 return FALSE;
00907 }
00908 }
00909 #else
00910 ???
00911 #endif
00912 }
00913 break;
00914 case CPL_ETH:
00915 pCPLObj->m_rx_tout= clock()+ (CPL_RX_TIMEOUT_MSEC*CLOCKS_PER_SEC)/ 1000;
00916
00917 {
00918 int byte_avail= 0;
00919 if( ( byte_avail= recv( pCPLObj->m_comm.m_socket, pCPLObj->m_bBuffRX+ pCPLObj->m_wBuffRXLen, wCount, MSG_PEEK))< (int)wCount)
00920 {
00921
00922
00923
00924
00925
00926
00927
00928 return FALSE;
00929 }
00930 }
00931 read_bytes= recv( pCPLObj->m_comm.m_socket, pCPLObj->m_bBuffRX+ pCPLObj->m_wBuffRXLen, wCount, 0);
00932 break;
00933 }
00934 CPL_LOCK( pCPLObj);
00935 pCPLObj->m_wBuffRXLen+= (UINT16)read_bytes;
00936 CPL_UNLOCK( pCPLObj);
00937
00938 return ((read_bytes>= wCount))? TRUE: FALSE;
00939 }
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 UINT16 CPL_GetCount( CPL_OBJ* pCPLObj, CPLBufferType type )
00950 {
00951 UINT16 count= 0;
00952 if( pCPLObj->m_comm.m_tag== INVALID_HANDLE_VALUE)
00953 {
00954 return 0;
00955 }
00956 CPL_LOCK( pCPLObj);
00957
00958 switch ( type)
00959 {
00960 case TX_BUFFER:
00961 count= pCPLObj->m_wBuffTXLen- pCPLObj->m_wBuffTXIni;
00962 break;
00963 case RX_BUFFER:
00964 count= pCPLObj->m_wBuffRXLen;
00965 break;
00966 case BOTH_BUFFER:
00967 break;
00968 }
00969 CPL_UNLOCK( pCPLObj);
00970 return count;
00971 }
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 UINT16 CPL_GetFree( CPL_OBJ* pCPLObj, CPLBufferType type )
00983 {
00984 UINT16 count= 0;
00985 CPL_LOCK( pCPLObj);
00986 switch ( type)
00987 {
00988 case TX_BUFFER:
00989 count= CPL_DIM_TX_BUFF- pCPLObj->m_wBuffTXLen;
00990 case RX_BUFFER:
00991 count= CPL_DIM_RX_BUFF- pCPLObj->m_wBuffRXLen;
00992 case BOTH_BUFFER:
00993 break;
00994 }
00995 CPL_UNLOCK( pCPLObj);
00996 return count;
00997 }
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008 BOOL CPL_direct_TX( CPL_OBJ* pCPLObj, const UINT8* bBuff, UINT16 wCount)
01009 {
01010 int sent_bytes= 0;
01011 if( pCPLObj->m_comm.m_tag== INVALID_HANDLE_VALUE)
01012 {
01013 return FALSE;
01014 }
01015
01016 switch( pCPLObj->m_config.m_device)
01017 {
01018 case CPL_COM:
01019 #if defined ( LINUX)
01020 sent_bytes= write ( pCPLObj->m_comm.m_serial, bBuff, wCount);
01021 #elif defined ( WIN32)
01022 WriteFile( pCPLObj->m_comm.m_serial, bBuff, wCount, &sent_bytes, NULL );
01023 #else
01024 ???
01025 #endif
01026 break;
01027 case CPL_ETH:
01028 sent_bytes= send( pCPLObj->m_comm.m_socket, bBuff, wCount,0);
01029 break;
01030 }
01031 if ((sent_bytes < 0)||( (UINT16)sent_bytes< wCount))
01032 {
01033 return FALSE;
01034 }
01035 return TRUE;
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048 BOOL CPL_direct_RX( CPL_OBJ* pCPLObj, UINT8* bBuff, UINT16 *wCount)
01049 {
01050 UINT32 read_bytes= 0;
01051 if( pCPLObj->m_comm.m_tag== INVALID_HANDLE_VALUE)
01052 {
01053 return FALSE;
01054 }
01055 if (*wCount == 0)
01056 {
01057 return TRUE;
01058 }
01059
01060 switch( pCPLObj->m_config.m_device)
01061 {
01062 case CPL_COM:
01063
01064 {
01065 int in_q;
01066 #if defined ( LINUX)
01067 ioctl( pCPLObj->m_comm.m_serial, FIONREAD, &in_q);
01068 #elif defined ( WIN32)
01069 COMSTAT cs;
01070 DWORD errorCode;
01071 ClearCommError( pCPLObj->m_comm.m_serial, &errorCode, &cs);
01072 if( errorCode & ( CE_OVERRUN| CE_RXOVER| CE_RXPARITY))
01073 {
01074 return FALSE;
01075 }
01076 in_q= cs.cbInQue;
01077
01078 #else
01079 ???
01080 #endif
01081 if( in_q> *wCount)
01082 {
01083 in_q= *wCount;
01084 }
01085 *wCount= 0;
01086 pCPLObj->m_rx_tout= clock()+ (CPL_RX_TIMEOUT_MSEC* CLOCKS_PER_SEC)/ 1000;
01087
01088 #if defined ( LINUX)
01089 read_bytes= read( pCPLObj->m_comm.m_serial, bBuff, in_q);
01090 #elif defined ( WIN32)
01091 {
01092
01093 if( !ReadFile( pCPLObj->m_comm.m_serial, bBuff, in_q, &read_bytes, NULL ))
01094 {
01095 if (GetLastError() == ERROR_IO_PENDING)
01096 {
01097 ClearCommError( pCPLObj->m_comm.m_serial, &errorCode, &cs);
01098 return FALSE;
01099 }
01100 }
01101 }
01102 #else
01103 ???
01104 #endif
01105 }
01106 break;
01107 case CPL_ETH:
01108
01109 {
01110 int in_q= recv( pCPLObj->m_comm.m_socket, bBuff, *wCount, MSG_PEEK);
01111 if( in_q< 0) {
01112 return FALSE;
01113 }
01114 if( in_q> *wCount)
01115 {
01116 in_q= *wCount;
01117 }
01118
01119 read_bytes= recv( pCPLObj->m_comm.m_socket, bBuff, in_q, 0);
01120 }
01121 break;
01122 }
01123 *wCount= ( UINT16)read_bytes;
01124
01125 return TRUE;
01126 }