@@ -125,7 +125,7 @@ int modbus_flush(modbus_t *ctx)
125125 return rc ;
126126}
127127
128- /* Computes the length of the expected response */
128+ /* Computes the length of the expected response including checksum */
129129static unsigned int compute_response_length_from_request (modbus_t * ctx , uint8_t * req )
130130{
131131 int length ;
@@ -394,8 +394,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
394394 length_to_read = ctx -> backend -> header_length + 1 ;
395395
396396 if (msg_type == MSG_INDICATION ) {
397- /* Wait for a message, we don't know when the message will be
398- * received */
397+ /* Wait for a message, we don't know when the message will be received */
399398 if (ctx -> indication_timeout .tv_sec == 0 && ctx -> indication_timeout .tv_usec == 0 ) {
400399 /* By default, the indication timeout isn't set */
401400 p_tv = NULL ;
@@ -805,7 +804,7 @@ int modbus_reply(modbus_t *ctx,
805804
806805 sft .slave = slave ;
807806 sft .function = function ;
808- sft .t_id = ctx -> backend -> prepare_response_tid (req , & req_length );
807+ sft .t_id = ctx -> backend -> get_response_tid (req );
809808
810809 /* Data are flushed on illegal number of values errors. */
811810 switch (function ) {
@@ -901,7 +900,7 @@ int modbus_reply(modbus_t *ctx,
901900 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS ,
902901 rsp ,
903902 FALSE,
904- "Illegal data address 0x%0X in write_bit \n" ,
903+ "Illegal data address 0x%0X in write bit \n" ,
905904 address );
906905 break ;
907906 }
@@ -910,20 +909,26 @@ int modbus_reply(modbus_t *ctx,
910909 rsp_length = compute_response_length_from_request (ctx , (uint8_t * ) req );
911910 if (rsp_length != req_length ) {
912911 /* Bad use of modbus_reply */
913- rsp_length =
914- response_exception ( ctx ,
915- & sft ,
916- MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE ,
917- rsp ,
918- FALSE,
919- "Invalid request length used in modbus_reply (%d)\n" ,
920- req_length );
912+ rsp_length = response_exception (
913+ ctx ,
914+ & sft ,
915+ MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE ,
916+ rsp ,
917+ FALSE,
918+ "Invalid request length in modbus_reply to write bit (%d)\n" ,
919+ req_length );
921920 break ;
922921 }
923922
923+ /* Don't copy the CRC, if any, it will be computed later (even if identical to the
924+ * request) */
925+ rsp_length -= ctx -> backend -> checksum_length ;
926+
924927 int data = (req [offset + 3 ] << 8 ) + req [offset + 4 ];
925928 if (data == 0xFF00 || data == 0x0 ) {
929+ /* Apply the change to mapping */
926930 mb_mapping -> tab_bits [mapping_address ] = data ? ON : OFF ;
931+ /* Prepare response */
927932 memcpy (rsp , req , rsp_length );
928933 } else {
929934 rsp_length = response_exception (
@@ -955,19 +960,21 @@ int modbus_reply(modbus_t *ctx,
955960 rsp_length = compute_response_length_from_request (ctx , (uint8_t * ) req );
956961 if (rsp_length != req_length ) {
957962 /* Bad use of modbus_reply */
958- rsp_length =
959- response_exception ( ctx ,
960- & sft ,
961- MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE ,
962- rsp ,
963- FALSE,
964- "Invalid request length used in modbus_reply (%d)\n" ,
965- req_length );
963+ rsp_length = response_exception (
964+ ctx ,
965+ & sft ,
966+ MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE ,
967+ rsp ,
968+ FALSE,
969+ "Invalid request length in modbus_reply to write register (%d)\n" ,
970+ req_length );
966971 break ;
967972 }
968973 int data = (req [offset + 3 ] << 8 ) + req [offset + 4 ];
969974
970975 mb_mapping -> tab_registers [mapping_address ] = data ;
976+
977+ rsp_length -= ctx -> backend -> checksum_length ;
971978 memcpy (rsp , req , rsp_length );
972979 } break ;
973980 case MODBUS_FC_WRITE_MULTIPLE_COILS : {
@@ -1088,8 +1095,23 @@ int modbus_reply(modbus_t *ctx,
10881095
10891096 data = (data & and ) | (or & (~and ) );
10901097 mb_mapping -> tab_registers [mapping_address ] = data ;
1091- memcpy (rsp , req , req_length );
1092- rsp_length = req_length ;
1098+
1099+ rsp_length = compute_response_length_from_request (ctx , (uint8_t * ) req );
1100+ if (rsp_length != req_length ) {
1101+ /* Bad use of modbus_reply */
1102+ rsp_length = response_exception (ctx ,
1103+ & sft ,
1104+ MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE ,
1105+ rsp ,
1106+ FALSE,
1107+ "Invalid request length in modbus_reply "
1108+ "to mask write register (%d)\n" ,
1109+ req_length );
1110+ break ;
1111+ }
1112+
1113+ rsp_length -= ctx -> backend -> checksum_length ;
1114+ memcpy (rsp , req , rsp_length );
10931115 }
10941116 } break ;
10951117 case MODBUS_FC_WRITE_AND_READ_REGISTERS : {
@@ -1177,7 +1199,6 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int excep
11771199 int function ;
11781200 uint8_t rsp [MAX_MESSAGE_LENGTH ];
11791201 int rsp_length ;
1180- int dummy_length = 99 ;
11811202 sft_t sft ;
11821203
11831204 if (ctx == NULL ) {
@@ -1191,7 +1212,7 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int excep
11911212
11921213 sft .slave = slave ;
11931214 sft .function = function + 0x80 ;
1194- sft .t_id = ctx -> backend -> prepare_response_tid (req , & dummy_length );
1215+ sft .t_id = ctx -> backend -> get_response_tid (req );
11951216 rsp_length = ctx -> backend -> build_response_basis (& sft , rsp );
11961217
11971218 /* Positive exception code */
0 commit comments