00001
00015
00016
00017 #include <string.h>
00018
00019 #include "mbtcp.h"
00020
00021
00022
00023
00030
00031 int MBTCPServerInit( int port, int *serverfd)
00032 {
00033 TCPServerInit( port, serverfd);
00034 }
00035
00036
00044
00045 int MBTCPServerWaitConnection( const int serverfd, int *clientfd, char *client_addr)
00046 {
00047 *clientfd= TCPServerWaitConnection( serverfd, clientfd, client_addr);
00048 if( *clientfd < 0 )
00049 return MB_ERROR_TCP_NOT_CONNECTED;
00050
00051 return *clientfd;
00052 }
00053
00054
00060
00061 int MBTCPClientInit( int *clientfd)
00062 {
00063 return TCPClientInit( clientfd);
00064 }
00065
00066
00074
00075 int MBTCPClientConnect( const int clientfd, const char *addr, int port)
00076 {
00077 return TCPClientConnect( clientfd, addr, port);
00078 }
00079
00080
00088
00089 int MBTCPNonBlockRead( int fd, u8 *buf, int len)
00090 {
00091 return TCPNonBlockRead( fd, buf, len);
00092 }
00093
00094
00102
00103 int MBTCPBlockRead( int fd, u8 *buf, int len)
00104 {
00105 return TCPBlockRead( fd, buf, len);
00106 }
00107
00108
00117
00118 int MBTCPWrite(int fd, u8 *pdu, int len, pMBAPStruct mbap)
00119 {
00120 u8 adu[ MB_RTU_ADU_MAX_LENGTH];
00121 int adu_len= 0;
00122
00123 adu_len= MBTCPWriteMBAP( adu, mbap);
00124 bcopy( (const char *)pdu, (char *)(adu+ adu_len), len);
00125 adu_len+= len;
00126
00127 return TCPWrite( fd, adu, adu_len);
00128 }
00129
00130 int MBTCPServerClose(int fd)
00131 {
00132 close( fd);
00133 }
00134
00135 int MBTCPClientClose(int fd)
00136 {
00137 close( fd);
00138 }
00139
00140
00147
00148 int MBTCPGetMBAP(u8 *adu, pMBAPStruct mbap)
00149 {
00150 GETU16( mbap->TransactionIdentifier, adu);
00151 GETU16( mbap->ProtocolIdentifier, adu+ 2);
00152 GETU16( mbap->Length, adu+ 4);
00153 mbap->UnitIdentifier= adu[ 6];
00154
00155 return MB_OK;
00156 }
00157
00158
00167
00168 int MBTCPMakeMBAP( pMBAPStruct mbap, u16 tid, u16 len, u8 uid)
00169 {
00170 mbap->TransactionIdentifier= tid;
00171 mbap->ProtocolIdentifier= 0;
00172 mbap->Length= len;
00173 mbap->UnitIdentifier= uid;
00174
00175 return MB_OK;
00176 }
00177
00178
00185
00186 int MBTCPWriteMBAP( char *buf, pMBAPStruct mbap)
00187 {
00188 PUTU16( buf, mbap->TransactionIdentifier);
00189 PUTU16( buf+ 2, mbap->ProtocolIdentifier);
00190 PUTU16( buf+ 4, mbap->Length);
00191 buf[ 6]= mbap->UnitIdentifier;
00192
00193 return 7;
00194 }
00195
00196
00204
00205 int MBTCPGetPDU(u8 *buf, u8 *adu, int len)
00206 {
00207 bcopy( (const char *)(adu+ 7), (char *)buf, len- 7);
00208
00209 return len- 7;
00210 }
00211
00212
00223
00224 int MBTCPSendAndWaitResponse(int fd, u8 *buf, u8 *pdu, int len, pMBAPStruct mbap)
00225 {
00226 int ret_len= 0;
00227 int tid= 0;
00228 pMBAPStruct ret_mbap= (pMBAPStruct)malloc(sizeof(MBAPStruct));
00229
00230 tid= mbap->TransactionIdentifier;
00231 MBTCPWrite( fd, pdu, len, mbap);
00232
00233 ret_len= MBTCPBlockRead( fd, buf, MB_RTU_ADU_MAX_LENGTH);
00234
00235 MBTCPGetMBAP( buf, ret_mbap);
00236
00237
00238 if( ret_mbap->TransactionIdentifier != tid)
00239 return MB_ERROR_EXECPTION;
00240
00241 return ret_len;
00242 }
00243
00244
00245
00246
00256
00257 int MBTCPReadDecreteInputs(int fd, u16 startdec, u16 no, u8 *value, pMBAPStruct mbap)
00258 {
00259 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00260 int pdu_len= 0, adu_len= 0, ret= 0;
00261 u8 ret_no;
00262
00263 pdu_len= MBReadDecreteInputs( pdu, startdec, no);
00264 mbap->Length= pdu_len+ 1;
00265
00266 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00267
00268 if( adu_len < 0)
00269 return adu_len;
00270
00271 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00272 ret= MBGetResponseReadDecreteInputs( pdu, &ret_no, value);
00273 if( ret < 0)
00274 return ret;
00275 return ret_no;
00276 }
00277
00278
00288
00289 int MBTCPReadCoils(int fd, u16 startcoils, u16 no, u8 *value, pMBAPStruct mbap)
00290 {
00291 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00292 int pdu_len= 0, adu_len= 0, ret= 0;
00293 u8 ret_no;
00294
00295 pdu_len= MBReadCoils( pdu, startcoils, no);
00296 mbap->Length= pdu_len+ 1;
00297
00298 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00299
00300 if( adu_len < 0)
00301 return adu_len;
00302
00303 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00304 ret= MBGetResponseReadCoils( pdu, &ret_no, value);
00305 if( ret < 0)
00306 return ret;
00307 return ret_no;
00308 }
00309
00310
00319
00320 int MBTCPWriteSingleCoil(int fd, u16 coilreg, u16 onoff, pMBAPStruct mbap)
00321 {
00322 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00323 int pdu_len= 0, adu_len= 0, ret= 0;
00324 u16 ret_addr, ret_value;
00325
00326 pdu_len= MBWriteSingleCoil( pdu, coilreg, onoff);
00327 mbap->Length= pdu_len+ 1;
00328
00329 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00330
00331 if( adu_len < 0)
00332 return adu_len;
00333
00334 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00335 ret= MBGetResponseWriteSingleCoil( pdu, &ret_addr, &ret_value);
00336 if( ret < 0)
00337 return ret;
00338 if( ( ret_addr != coilreg) || ( ret_value != onoff))
00339 return MB_ERROR_EXECPTION;
00340 return MB_OK;
00341 }
00342
00343
00353
00354 int MBTCPWriteMultipleCoils(int fd, u16 startcoils, u16 no, u8 *value, pMBAPStruct mbap)
00355 {
00356 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00357 int pdu_len= 0, adu_len= 0, ret= 0;
00358 u16 count;
00359 u16 ret_addr, ret_value;
00360
00361 count= (u8)no/8;
00362 if( count*8 < no)
00363 count++;
00364
00365 pdu_len= MBWriteMultipleCoils( pdu, startcoils, no, count, value);
00366 mbap->Length= pdu_len+ 1;
00367
00368 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00369
00370 if( adu_len < 0)
00371 return adu_len;
00372
00373 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00374 ret= MBGetResponseWriteMultipleCoils( pdu, &ret_addr, &ret_value);
00375 if( ret < 0)
00376 return ret;
00377 if( ( ret_addr != startcoils) || ( ret_value != no))
00378 return MB_ERROR_EXECPTION;
00379 return MB_OK;
00380 }
00381
00382
00392
00393 int MBTCPReadInputRegisters(int fd, u16 startreg, u16 no, u16 *value, pMBAPStruct mbap)
00394 {
00395 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00396 int pdu_len= 0, adu_len= 0, ret= 0;
00397 u8 ret_no;
00398
00399 pdu_len= MBReadInputRegisters( pdu, startreg, no);
00400 mbap->Length= pdu_len+ 1;
00401
00402 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00403
00404 if( adu_len < 0)
00405 return adu_len;
00406
00407 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00408 ret= MBGetResponseReadInputRegisters( pdu, &ret_no, value);
00409 if( ret < 0)
00410 return ret;
00411 return ret_no;
00412 }
00413
00414
00424
00425 int MBTCPReadHoldingRegisters(int fd, u16 startreg, u16 no, u16 *value, pMBAPStruct mbap)
00426 {
00427 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00428 int pdu_len= 0, adu_len= 0, ret= 0;
00429 u8 ret_no;
00430
00431 pdu_len= MBReadHoldingRegisters( pdu, startreg, no);
00432 mbap->Length= pdu_len+ 1;
00433
00434 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00435
00436 if( adu_len < 0)
00437 return adu_len;
00438
00439 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00440 ret= MBGetResponseReadHoldingRegisters( pdu, &ret_no, value);
00441 if( ret < 0)
00442 return ret;
00443 return ret_no;
00444 }
00445
00446
00455
00456 int MBTCPWriteSingleRegister(int fd, u16 devicereg, u16 value, pMBAPStruct mbap)
00457 {
00458 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00459 int pdu_len= 0, adu_len= 0, ret= 0;
00460 u16 ret_addr, ret_value;
00461
00462 pdu_len= MBWriteSingleRegister( pdu, devicereg, value);
00463 mbap->Length= pdu_len+ 1;
00464
00465 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00466
00467 if( adu_len < 0)
00468 return adu_len;
00469
00470 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00471 ret= MBGetResponseWriteSingleRegister( pdu, &ret_addr, &ret_value);
00472 if( ret < 0)
00473 return ret;
00474 if( ( ret_addr != devicereg) || ( ret_value != value))
00475 return MB_ERROR_EXECPTION;
00476 return MB_OK;
00477 }
00478
00479
00490
00491 int MBTCPWriteMultipleRegisters(int fd, u16 startreg, u16 noreg, u8 count, u16 *value, pMBAPStruct mbap)
00492 {
00493 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00494 int pdu_len= 0, adu_len= 0, ret= 0;
00495 u16 ret_addr, ret_value;
00496
00497 pdu_len= MBWriteMultipleRegisters( pdu, startreg, noreg, count, value);
00498 mbap->Length= pdu_len+ 1;
00499
00500 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00501
00502 if( adu_len < 0)
00503 return adu_len;
00504
00505 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00506 ret= MBGetResponseWriteMultipleRegisters( pdu, &ret_addr, &ret_value);
00507 if( ret < 0)
00508 return ret;
00509 if( ( ret_addr != startreg) || ( ret_value != noreg))
00510 return MB_ERROR_EXECPTION;
00511 return MB_OK;
00512 }
00513
00514
00528
00529 int MBTCPReadWriteMultipleRegisters(int fd, u16 rsreg, u16 rno, u16 *rv, u16 wsreg, u16 wno, u8 count, u16 *wv, pMBAPStruct mbap)
00530 {
00531 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00532 int pdu_len= 0, adu_len= 0, ret= 0;
00533 u8 ret_no;
00534
00535 pdu_len= MBReadWriteMultipleRegisters( pdu, rsreg, rno, wsreg, wno, count, wv);
00536 mbap->Length= pdu_len+ 1;
00537
00538 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00539
00540 if( adu_len < 0)
00541 return adu_len;
00542
00543 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00544 ret= MBGetResponseReadWriteMultipleRegisters( pdu, (u8 *)&ret_no, wv);
00545
00546 if( ret < 0)
00547 return ret;
00548 if( ret_no != rno*2)
00549 return MB_ERROR_EXECPTION;
00550 return MB_OK;
00551 }
00552
00553
00563
00564 int MBTCPMaskwWriteRegister(int fd, u16 reg, u16 andmask, u16 ormask, pMBAPStruct mbap)
00565 {
00566 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00567 int pdu_len= 0, adu_len= 0, ret= 0;
00568 u16 ret_reg, ret_and, ret_or;
00569
00570 pdu_len= MBMaskWriteRegister( pdu, reg, andmask, ormask);
00571 mbap->Length= pdu_len+ 1;
00572
00573 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00574
00575 if( adu_len < 0)
00576 return adu_len;
00577
00578 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00579 ret= MBGetResponseMaskWriteRegister( pdu, &ret_reg, &ret_and, &ret_or);
00580
00581 if( ret < 0)
00582 return ret;
00583 if( ( ret_reg != reg) || ( ret_and != andmask) || ( ret_or != ormask))
00584 return MB_ERROR_EXECPTION;
00585 return MB_OK;
00586 }
00587
00588
00598
00599 int MBTCPReadFIFOQueue(int fd, u16 FIFOAddr, u16 *FIFOCount, u16 *FIFOValue, pMBAPStruct mbap)
00600 {
00601 u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
00602 int pdu_len= 0, adu_len= 0, ret= 0;
00603
00604 pdu_len= MBReadFIFOQueue( pdu, FIFOAddr);
00605 mbap->Length= pdu_len+ 1;
00606
00607 adu_len= MBTCPSendAndWaitResponse( fd, adu, pdu, pdu_len, mbap);
00608
00609 if( adu_len < 0)
00610 return adu_len;
00611
00612 pdu_len= MBTCPGetPDU( pdu, adu, adu_len);
00613 ret= MBGetResponseReadFIFOQueue( pdu, FIFOCount, FIFOValue);
00614
00615 if( ret < 0)
00616 return ret;
00617
00618 return MB_OK;
00619 }
00620
00621
00622
00631
00632 int MBTCPSendReadDecreteInputs(int fd, u16 no, u8 *value, pMBAPStruct mbap)
00633 {
00634 u8 pdu[ MAX_BUFFER_SIZE];
00635 int pdu_len= 0, adu_len= 0;
00636
00637 pdu_len= MBResponseReadDecreteInputs( pdu, no, value);
00638 mbap->Length= pdu_len+ 1;
00639
00640 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00641
00642 if( adu_len < 0)
00643 return adu_len;
00644
00645 return MB_OK;
00646 }
00647
00648
00657
00658 int MBTCPSendReadCoils(int fd, u16 no, u8 *value, pMBAPStruct mbap)
00659 {
00660 u8 pdu[ MAX_BUFFER_SIZE];
00661 int pdu_len= 0, adu_len= 0;
00662
00663 pdu_len= MBResponseReadCoils( pdu, no, value);
00664 mbap->Length= pdu_len+ 1;
00665
00666 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00667
00668 if( adu_len < 0)
00669 return adu_len;
00670
00671 return MB_OK;
00672 }
00673
00674
00683
00684 int MBTCPSendReadInputRegisters(int fd, u16 no, u16 *value, pMBAPStruct mbap)
00685 {
00686 u8 pdu[ MAX_BUFFER_SIZE];
00687 int pdu_len= 0, adu_len= 0;
00688
00689 pdu_len= MBResponseReadInputRegisters( pdu, no, value);
00690 mbap->Length= pdu_len+ 1;
00691
00692 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00693
00694 if( adu_len < 0)
00695 return adu_len;
00696
00697 return MB_OK;
00698 }
00699
00700
00709
00710 int MBTCPSendReadHoldingRegisters(int fd, u16 no, u16 *value, pMBAPStruct mbap)
00711 {
00712 u8 pdu[ MAX_BUFFER_SIZE];
00713 int pdu_len= 0, adu_len= 0;
00714
00715 pdu_len= MBResponseReadHoldingRegisters( pdu, no, value);
00716 mbap->Length= pdu_len+ 1;
00717
00718 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00719
00720 if( adu_len < 0)
00721 return adu_len;
00722
00723 return MB_OK;
00724 }
00725
00726
00737
00738 int MBTCPSendWriteMultipleRegisters(int fd, u16 startdevreg, u16 noreg, u8 count, u16 *value, pMBAPStruct mbap)
00739 {
00740 u8 pdu[ MAX_BUFFER_SIZE];
00741 int pdu_len= 0, adu_len= 0;
00742
00743 pdu_len= MBResponseWriteMultipleRegisters( pdu, startdevreg, noreg);
00744 mbap->Length= pdu_len+ 1;
00745
00746 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00747
00748 if( adu_len < 0)
00749 return adu_len;
00750
00751 return MB_OK;
00752 }
00753
00754
00763
00764 int MBTCPSendWriteSingleCoil(int fd, u16 coilreg, u16 onoff, pMBAPStruct mbap)
00765 {
00766 u8 pdu[ MAX_BUFFER_SIZE];
00767 int pdu_len= 0, adu_len= 0;
00768
00769 pdu_len= MBResponseWriteSingleCoil( pdu, coilreg, onoff);
00770 mbap->Length= pdu_len+ 1;
00771
00772 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00773
00774 if( adu_len < 0)
00775 return adu_len;
00776
00777 return MB_OK;
00778 }
00779
00780
00789
00790 int MBTCPSendWriteSingleRegister(int fd, u16 reg, u16 value, pMBAPStruct mbap)
00791 {
00792 u8 pdu[ MAX_BUFFER_SIZE];
00793 int pdu_len= 0, adu_len= 0;
00794
00795 pdu_len= MBResponseWriteSingleRegister( pdu, reg, value);
00796 mbap->Length= pdu_len+ 1;
00797
00798 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00799
00800 if( adu_len < 0)
00801 return adu_len;
00802
00803 return MB_OK;
00804 }
00805
00806
00816
00817 int MBTCPSendReadFIFOQueue(int fd, u16 no, u16 count, u16 *value, pMBAPStruct mbap)
00818 {
00819 u8 pdu[ MAX_BUFFER_SIZE];
00820 int pdu_len= 0, adu_len= 0;
00821
00822 pdu_len= MBResponseReadFIFOQueue( pdu, no, count, value);
00823 mbap->Length= pdu_len+ 1;
00824
00825 adu_len= MBTCPWrite( fd, pdu, pdu_len, mbap);
00826
00827 if( adu_len < 0)
00828 return adu_len;
00829
00830 return MB_OK;
00831 }
00832