@ -40,15 +40,44 @@ ModbusError_t mb_handleRequest(
size_t * resp_size
)
{
uint16_t txn_id , msglen , protocol_id , ref , count , ref2 , count2 , value , and_mask , or_mask ;
uint16_t txn_id , protocol_id , ref ;
# ifdef MB_SUPPORT_FC22
uint16_t and_mask , or_mask ;
# endif
# ifdef MB_SUPPORT_FC23
uint16_t ref2 , count2 ;
# endif
# if defined(MB_SUPPORT_FC01) || defined(MB_SUPPORT_FC02)
bool bvalue ;
# endif
# if defined(MB_SUPPORT_FC03) || defined(MB_SUPPORT_FC04) \
| | defined ( MB_SUPPORT_FC16 ) | | defined ( MB_SUPPORT_FC22 ) | | defined ( MB_SUPPORT_FC23 ) \
| | defined ( MB_SUPPORT_FC05 ) | | defined ( MB_SUPPORT_FC06 )
uint16_t value ;
# endif
# if defined(MB_SUPPORT_FC01) || defined(MB_SUPPORT_FC02) || defined(MB_SUPPORT_FC15)
uint8_t scratch , bytecount , bitcnt ;
# endif
# if defined(MB_SUPPORT_FC01) || defined(MB_SUPPORT_FC02) || defined(MB_SUPPORT_FC03) \
| | defined ( MB_SUPPORT_FC04 ) | | defined ( MB_SUPPORT_FC15 ) | | defined ( MB_SUPPORT_FC16 ) \
| | defined ( MB_SUPPORT_FC23 )
uint16_t count ;
# endif
ModbusException_t exc = MB_EXCEPTION_OK ;
size_t numbytes ;
uint8_t fcx , bytecount , bitcnt , scratch ;
uint8_t fcx ;
const size_t TCP_RESP_OVERHEAD = 8 ;
const size_t RTU_RESP_OVERHEAD = 4 ;
const size_t overhead = ms - > proto = = MB_PROTO_TCP ? TCP_RESP_OVERHEAD : RTU_RESP_OVERHEAD ;
pb_mark_t resp_fc_mark , resp_len_mark , resp_pld_start_mark ;
pb_mark_t resp_fc_mark = NULL , resp_len_mark = NULL , resp_pld_start_mark = NULL ;
const bool tcp = ms - > proto = = MB_PROTO_TCP ;
PayloadParser pp = pp_start_be ( req , req_size , NULL ) ;
@ -58,12 +87,11 @@ ModbusError_t mb_handleRequest(
/* Parse header */
txn_id = pp_u16 ( & pp ) ;
protocol_id = pp_u16 ( & pp ) ;
msglen = pp_u16 ( & pp ) ;
pp_skip ( & pp , 2 ) ; // msglen
if ( protocol_id ! = 0 ) {
return MB_ERR_BADPROTO ;
}
} else {
msglen = req_size ;
/* check CRC */
uint16_t crc = crc16_init ( ) ;
for ( int pos = 0 ; pos < req_size /* size of CRC */ ; pos + + ) {
@ -108,6 +136,7 @@ ModbusError_t mb_handleRequest(
}
switch ( fcx ) {
# ifdef MB_SUPPORT_FC05
case FC05_WRITE_SINGLE_COIL :
if ( ! ms - > writeCoil ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
@ -133,17 +162,24 @@ ModbusError_t mb_handleRequest(
pb_u16 ( & pb , ref ) ;
pb_u16 ( & pb , value ) ;
break ;
# endif
# if defined(MB_SUPPORT_FC01) || defined(MB_SUPPORT_FC02)
case FC01_READ_COILS :
case FC02_READ_DISCRETES :
/* check we have the needed function */
# ifdef MB_SUPPORT_FC01
if ( fcx = = FC01_READ_COILS & & ! ms - > readCoil ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
goto exception ;
} else if ( ! ms - > readDiscrete ) {
}
# endif
# ifdef MB_SUPPORT_FC02
if ( fcx = = FC02_READ_DISCRETES & & ! ms - > readDiscrete ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
goto exception ;
}
# endif
ref = pp_u16 ( & pp ) ;
count = pp_u16 ( & pp ) ;
if ( ! pp_ok ( & pp ) ) {
@ -158,11 +194,16 @@ ModbusError_t mb_handleRequest(
bitcnt = 0 ;
scratch = 0 ;
while ( count - - > 0 ) {
# ifdef MB_SUPPORT_FC01
if ( fcx = = FC01_READ_COILS ) {
exc = ms - > readCoil ( ms , ref + + , & bvalue ) ;
} else {
}
# endif
# ifdef MB_SUPPORT_FC02
if ( fcx = = FC02_READ_DISCRETES ) {
exc = ms - > readDiscrete ( ms , ref + + , & bvalue ) ;
}
# endif
if ( exc ! = 0 ) {
goto exception ;
}
@ -178,18 +219,24 @@ ModbusError_t mb_handleRequest(
pb_u8 ( & pb , scratch ) ;
}
break ;
# endif
# if defined(MB_SUPPORT_FC03) || defined(MB_SUPPORT_FC04)
case FC03_READ_HOLDING_REGISTERS :
case FC04_READ_INPUT_REGISTERS :
# ifdef MB_SUPPORT_FC03
/* check we have the needed function */
if ( fcx = = FC03_READ_HOLDING_REGISTERS & & ! ms - > readHolding ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
goto exception ;
} else if ( ! ms - > readInput ) {
}
# endif
# ifdef MB_SUPPORT_FC04
if ( fcx = = FC04_READ_INPUT_REGISTERS & & ! ms - > readInput ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
goto exception ;
}
# endif
ref = pp_u16 ( & pp ) ;
count = pp_u16 ( & pp ) ;
if ( ! pp_ok ( & pp ) ) {
@ -201,18 +248,25 @@ ModbusError_t mb_handleRequest(
}
pb_u8 ( & pb , count * 2 ) ;
while ( count - - > 0 ) {
# ifdef MB_SUPPORT_FC03
if ( fcx = = FC03_READ_HOLDING_REGISTERS ) {
exc = ms - > readHolding ( ms , ref + + , & value ) ;
} else {
}
# endif
# ifdef MB_SUPPORT_FC04
if ( fcx = = FC04_READ_INPUT_REGISTERS ) {
exc = ms - > readInput ( ms , ref + + , & value ) ;
}
# endif
if ( exc ! = 0 ) {
goto exception ;
}
pb_u16 ( & pb , value ) ;
}
break ;
# endif
# ifdef MB_SUPPORT_FC06
case FC06_WRITE_SINGLE_REGISTER :
if ( ! ms - > writeHolding ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
@ -234,7 +288,9 @@ ModbusError_t mb_handleRequest(
pb_u16 ( & pb , ref ) ;
pb_u16 ( & pb , value ) ;
break ;
# endif
# ifdef MB_SUPPORT_FC16
case FC16_WRITE_MULTIPLE_REGISTERS :
if ( ! ms - > writeHolding ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
@ -263,7 +319,9 @@ ModbusError_t mb_handleRequest(
}
}
break ;
# endif
# ifdef MB_SUPPORT_FC15
case FC15_WRITE_MULTIPLE_COILS :
if ( ! ms - > writeCoil ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
@ -298,7 +356,9 @@ ModbusError_t mb_handleRequest(
}
}
break ;
# endif
# ifdef MB_SUPPORT_FC22
case FC22_MASK_WRITE_REGISTER :
if ( ! ms - > writeHolding | | ! ms - > readHolding ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
@ -329,7 +389,9 @@ ModbusError_t mb_handleRequest(
pb_u16 ( & pb , and_mask ) ;
pb_u16 ( & pb , or_mask ) ;
break ;
# endif
# ifdef MB_SUPPORT_FC23
case FC23_READ_WRITE_MULTIPLE_REGISTERS :
if ( ! ms - > writeHolding | | ! ms - > readHolding ) {
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
@ -370,6 +432,7 @@ ModbusError_t mb_handleRequest(
pb_u16 ( & pb , value ) ;
}
break ;
# endif
default :
exc = MB_EXCEPTION_ILLEGAL_FUNCTION ;
@ -386,7 +449,6 @@ ModbusError_t mb_handleRequest(
checksum :
numbytes = pb_length ( & pb ) ;
if ( tcp ) {
pb_mark_t end = pb_save ( & pb ) ;
pb_restore ( & pb , resp_len_mark ) ;
pb_u16 ( & pb , numbytes - 6 ) ;
* resp_size = numbytes ;