Home/Support/Support Forum/MODbust TCP master
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

MODbust TCP master

0 votes
I have tried to implemented MODbust master on TCP on RCM 6700.
Havig really hard time with "int MBM_Send_ADU ( *ADUaddress, ADUlength );"
Any samples?
asked Jun 16, 2017 in Rabbit Software by Demolick New to the Community (28 points)

Please log in or register to answer this question.

1 Answer

+2 votes
 
Best answer
The following code extract should give you a start:
Code:
/*** BeginHeader MBM_Send_ADU_TCP */ int MBM_Send_ADU_TCP(uint32_t IPAddress, char *Packet, int ByteCount); #define MMTCP_STATE_WAIT 0 #define MMTCP_STATE_STARTED 1 #define MMTCP_STATE_REMAINDER 2 #define MMTCP_STATE_DONE 3 #define MMTCP_STATE_ERROR 4 /*** EndHeader */ _modbus_dbg int MBM_Send_ADU_TCP(uint32_t IPAddress, char *Packet, int ByteCount) { static tcp_Socket MMSocket; static far char MMTCPBuffer[1024]; int i; uint32_t ulTemp; int16_t iTemp; int iExpected; int iMMTState; int bytes_read; char cDiscard; int iResponse; iResponse = MB_SUCCESS; #if MODBUS_PRINT if(cModbusPrintEnabled) { printf("Tx TCP:"); for(i=0; i<ByteCount; i++ ) printf ( " %02X", Packet[i]); printf ( "\n\r" ); } #endif if(tcp_extopen(&MMSocket, IF_ETH0, 0, ntohl(IPAddress), 502, NULL, (long)MMTCPBuffer, 1024) != 0) { ulTemp = LocalTimeCorrected(); while(0 == sock_established(&MMSocket)) /* Try establish a connection with at most 2 second timeout */ { if((LocalTimeCorrected() - ulTemp) > 2) break; } if(0 != sock_established(&MMSocket)) { sock_flushnext(&MMSocket); iTemp = sock_write(&MMSocket, Packet, ByteCount); iExpected = MBM_HowMany(&Packet[6]) - 2; // Subtract CRC bytes ulTemp = LocalTimeCorrected(); // Record when we sent packet iMMTState = MMTCP_STATE_WAIT; do { if((LocalTimeCorrected() - ulTemp) > 2) // Taking too long... iMMTState = MMTCP_STATE_ERROR; switch(iMMTState) { case MMTCP_STATE_WAIT: if(sock_bytesready(&MMSocket) >= 8 ) // Got the minimum expected data so goto next stage iMMTState = MMTCP_STATE_STARTED; break; case MMTCP_STATE_STARTED: sock_read(&MMSocket, mbADU, 8 ); // Know this will not block as we checked in previous state... if(mbADU[7] >= 0x80) // Not a good response... iExpected = 1; // Just the error code to get else iExpected -= 2; // Have address and function code... iMMTState = MMTCP_STATE_REMAINDER; break; case MMTCP_STATE_REMAINDER: if(sock_bytesready(&MMSocket) >= iExpected) { sock_read(&MMSocket, &mbADU[8], iExpected); sock_close(&MMSocket); while(sock_bytesready(&MMSocket) != -1) // Flush any unread data just in case { sock_read(&MMSocket, &cDiscard, 1); if((LocalTimeCorrected() - ulTemp) > 2) // Taking too long so... { sock_abort(&MMSocket); break; } } iMMTState = MMTCP_STATE_DONE; } break; case MMTCP_STATE_ERROR: sock_abort(&MMSocket); return(MBM_PACKET_ERROR); break; } } while(iMMTState != MMTCP_STATE_DONE); // receive the response into the same buffer used for the transmit data return(MB_SUCCESS); } else sock_abort(&MMSocket); } return(MBM_PACKET_ERROR); }

The LocalTimeCorrected() function is my own time function which takes into account the offset calculated via SNTP, you can just use the normal SEC_TIMER.

This code uses a fixed small 1024 byte buffer for the TCP socket for efficiency.

Regards,
Peter
answered Jun 16, 2017 by petermcs Veteran of the Digi Community (1,130 points)
selected Jun 19, 2017 by Demolick
Peter, you can use bbcode markup in your posts here.  Wrap code in opening/closing "code" blocks, using square brackets.  Not sure if I can embed it in my comment or not...  [code]code goes here[/code]
Thanks for the tip Tom, done...
Thank you Peter, it'll help me alot.
Regards,
Konstantin.
...