@@ -125,7 +125,7 @@ int modbus_flush(modbus_t *ctx)
125
125
return rc ;
126
126
}
127
127
128
- /* Computes the length of the expected response */
128
+ /* Computes the length of the expected response including checksum */
129
129
static unsigned int compute_response_length_from_request (modbus_t * ctx , uint8_t * req )
130
130
{
131
131
int length ;
@@ -394,8 +394,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
394
394
length_to_read = ctx -> backend -> header_length + 1 ;
395
395
396
396
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 */
399
398
if (ctx -> indication_timeout .tv_sec == 0 && ctx -> indication_timeout .tv_usec == 0 ) {
400
399
/* By default, the indication timeout isn't set */
401
400
p_tv = NULL ;
@@ -805,7 +804,7 @@ int modbus_reply(modbus_t *ctx,
805
804
806
805
sft .slave = slave ;
807
806
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 );
809
808
810
809
/* Data are flushed on illegal number of values errors. */
811
810
switch (function ) {
@@ -901,7 +900,7 @@ int modbus_reply(modbus_t *ctx,
901
900
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS ,
902
901
rsp ,
903
902
FALSE,
904
- "Illegal data address 0x%0X in write_bit \n" ,
903
+ "Illegal data address 0x%0X in write bit \n" ,
905
904
address );
906
905
break ;
907
906
}
@@ -910,20 +909,26 @@ int modbus_reply(modbus_t *ctx,
910
909
rsp_length = compute_response_length_from_request (ctx , (uint8_t * ) req );
911
910
if (rsp_length != req_length ) {
912
911
/* 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 );
921
920
break ;
922
921
}
923
922
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
+
924
927
int data = (req [offset + 3 ] << 8 ) + req [offset + 4 ];
925
928
if (data == 0xFF00 || data == 0x0 ) {
929
+ /* Apply the change to mapping */
926
930
mb_mapping -> tab_bits [mapping_address ] = data ? ON : OFF ;
931
+ /* Prepare response */
927
932
memcpy (rsp , req , rsp_length );
928
933
} else {
929
934
rsp_length = response_exception (
@@ -955,19 +960,21 @@ int modbus_reply(modbus_t *ctx,
955
960
rsp_length = compute_response_length_from_request (ctx , (uint8_t * ) req );
956
961
if (rsp_length != req_length ) {
957
962
/* 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 );
966
971
break ;
967
972
}
968
973
int data = (req [offset + 3 ] << 8 ) + req [offset + 4 ];
969
974
970
975
mb_mapping -> tab_registers [mapping_address ] = data ;
976
+
977
+ rsp_length -= ctx -> backend -> checksum_length ;
971
978
memcpy (rsp , req , rsp_length );
972
979
} break ;
973
980
case MODBUS_FC_WRITE_MULTIPLE_COILS : {
@@ -1088,8 +1095,23 @@ int modbus_reply(modbus_t *ctx,
1088
1095
1089
1096
data = (data & and ) | (or & (~and ) );
1090
1097
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 );
1093
1115
}
1094
1116
} break ;
1095
1117
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
1177
1199
int function ;
1178
1200
uint8_t rsp [MAX_MESSAGE_LENGTH ];
1179
1201
int rsp_length ;
1180
- int dummy_length = 99 ;
1181
1202
sft_t sft ;
1182
1203
1183
1204
if (ctx == NULL ) {
@@ -1191,7 +1212,7 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int excep
1191
1212
1192
1213
sft .slave = slave ;
1193
1214
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 );
1195
1216
rsp_length = ctx -> backend -> build_response_basis (& sft , rsp );
1196
1217
1197
1218
/* Positive exception code */
0 commit comments