mbtcp.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
  3. * Copyright (c) 2006-2018 Christian Walter <cwalter@embedded-solutions.at>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *
  28. */
  29. /* ----------------------- System includes ----------------------------------*/
  30. #include "stdlib.h"
  31. #include "string.h"
  32. /* ----------------------- Platform includes --------------------------------*/
  33. #include "port.h"
  34. /* ----------------------- Modbus includes ----------------------------------*/
  35. #include "mb.h"
  36. #include "mbconfig.h"
  37. #include "mbtcp.h"
  38. #include "mbframe.h"
  39. #include "mbport.h"
  40. #if MB_TCP_ENABLED > 0
  41. /* ----------------------- Defines ------------------------------------------*/
  42. /* ----------------------- MBAP Header --------------------------------------*/
  43. /*
  44. *
  45. * <------------------------ MODBUS TCP/IP ADU(1) ------------------------->
  46. * <----------- MODBUS PDU (1') ---------------->
  47. * +-----------+---------------+------------------------------------------+
  48. * | TID | PID | Length | UID |Code | Data |
  49. * +-----------+---------------+------------------------------------------+
  50. * | | | | |
  51. * (2) (3) (4) (5) (6)
  52. *
  53. * (2) ... MB_TCP_TID = 0 (Transaction Identifier - 2 Byte)
  54. * (3) ... MB_TCP_PID = 2 (Protocol Identifier - 2 Byte)
  55. * (4) ... MB_TCP_LEN = 4 (Number of bytes - 2 Byte)
  56. * (5) ... MB_TCP_UID = 6 (Unit Identifier - 1 Byte)
  57. * (6) ... MB_TCP_FUNC = 7 (Modbus Function Code)
  58. *
  59. * (1) ... Modbus TCP/IP Application Data Unit
  60. * (1') ... Modbus Protocol Data Unit
  61. */
  62. #define MB_TCP_TID 0
  63. #define MB_TCP_PID 2
  64. #define MB_TCP_LEN 4
  65. #define MB_TCP_UID 6
  66. #define MB_TCP_FUNC 7
  67. #define MB_TCP_PROTOCOL_ID 0 /* 0 = Modbus Protocol */
  68. /* ----------------------- Start implementation -----------------------------*/
  69. eMBErrorCode
  70. eMBTCPDoInit( USHORT ucTCPPort )
  71. {
  72. eMBErrorCode eStatus = MB_ENOERR;
  73. if( xMBTCPPortInit( ucTCPPort ) == FALSE )
  74. {
  75. eStatus = MB_EPORTERR;
  76. }
  77. return eStatus;
  78. }
  79. void
  80. eMBTCPStart( void )
  81. {
  82. }
  83. void
  84. eMBTCPStop( void )
  85. {
  86. /* Make sure that no more clients are connected. */
  87. vMBTCPPortDisable( );
  88. }
  89. eMBErrorCode
  90. eMBTCPReceive( UCHAR * pucRcvAddress, UCHAR ** ppucFrame, USHORT * pusLength )
  91. {
  92. eMBErrorCode eStatus = MB_EIO;
  93. UCHAR *pucMBTCPFrame;
  94. USHORT usLength;
  95. USHORT usPID;
  96. if( xMBTCPPortGetRequest( &pucMBTCPFrame, &usLength ) != FALSE )
  97. {
  98. usPID = pucMBTCPFrame[MB_TCP_PID] << 8U;
  99. usPID |= pucMBTCPFrame[MB_TCP_PID + 1];
  100. if( usPID == MB_TCP_PROTOCOL_ID )
  101. {
  102. *ppucFrame = &pucMBTCPFrame[MB_TCP_FUNC];
  103. *pusLength = usLength - MB_TCP_FUNC;
  104. eStatus = MB_ENOERR;
  105. /* Modbus TCP does not use any addresses. Fake the source address such
  106. * that the processing part deals with this frame.
  107. */
  108. *pucRcvAddress = MB_TCP_PSEUDO_ADDRESS;
  109. }
  110. }
  111. else
  112. {
  113. eStatus = MB_EIO;
  114. }
  115. return eStatus;
  116. }
  117. eMBErrorCode
  118. eMBTCPSend( UCHAR _unused, const UCHAR * pucFrame, USHORT usLength )
  119. {
  120. eMBErrorCode eStatus = MB_ENOERR;
  121. UCHAR *pucMBTCPFrame = ( UCHAR * ) pucFrame - MB_TCP_FUNC;
  122. USHORT usTCPLength = usLength + MB_TCP_FUNC;
  123. /* The MBAP header is already initialized because the caller calls this
  124. * function with the buffer returned by the previous call. Therefore we
  125. * only have to update the length in the header. Note that the length
  126. * header includes the size of the Modbus PDU and the UID Byte. Therefore
  127. * the length is usLength plus one.
  128. */
  129. pucMBTCPFrame[MB_TCP_LEN] = ( usLength + 1 ) >> 8U;
  130. pucMBTCPFrame[MB_TCP_LEN + 1] = ( usLength + 1 ) & 0xFF;
  131. if( xMBTCPPortSendResponse( pucMBTCPFrame, usTCPLength ) == FALSE )
  132. {
  133. eStatus = MB_EIO;
  134. }
  135. return eStatus;
  136. }
  137. #endif