@@ -322,6 +322,16 @@ static bool mbs_fc03_hreg_read(struct modbus_context *ctx)
322322 reg_addr = sys_get_be16 (& ctx -> rx_adu .data [0 ]);
323323 reg_qty = sys_get_be16 (& ctx -> rx_adu .data [2 ]);
324324
325+ if (reg_qty == 0 || reg_qty > regs_limit ) {
326+ LOG_ERR ("Wrong register quantity, %u (limit is %u)" ,
327+ reg_qty , regs_limit );
328+ mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
329+ return true;
330+ }
331+
332+ /* Get number of bytes needed for response. */
333+ num_bytes = (uint8_t )(reg_qty * sizeof (uint16_t ));
334+
325335 if ((reg_addr < MODBUS_FP_EXTENSIONS_ADDR ) ||
326336 !IS_ENABLED (CONFIG_MODBUS_FP_EXTENSIONS )) {
327337 /* Read integer register */
@@ -330,29 +340,17 @@ static bool mbs_fc03_hreg_read(struct modbus_context *ctx)
330340 return true;
331341 }
332342
333- if (reg_qty == 0 || reg_qty > regs_limit ) {
334- LOG_ERR ("Number of registers limit exceeded" );
335- mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
336- return true;
337- }
338-
339- /* Get number of bytes needed for response. */
340- num_bytes = (uint8_t )(reg_qty * sizeof (uint16_t ));
341343 } else {
342344 /* Read floating-point register */
343345 if (ctx -> mbs_user_cb -> holding_reg_rd_fp == NULL ) {
344346 mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_FC );
345347 return true;
346348 }
347349
348- if (reg_qty == 0 || reg_qty > (regs_limit / 2 )) {
349- LOG_ERR ("Number of registers limit exceeded" );
350- mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
350+ if (num_bytes % sizeof (uint32_t )) {
351+ mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_FC );
351352 return true;
352353 }
353-
354- /* Get number of bytes needed for response. */
355- num_bytes = (uint8_t )(reg_qty * sizeof (float ));
356354 }
357355
358356 /* Number of data bytes + byte count. */
@@ -374,6 +372,9 @@ static bool mbs_fc03_hreg_read(struct modbus_context *ctx)
374372 presp += sizeof (uint16_t );
375373 }
376374
375+ /* Increment current register address */
376+ reg_addr ++ ;
377+ reg_qty -- ;
377378 } else if (IS_ENABLED (CONFIG_MODBUS_FP_EXTENSIONS )) {
378379 float fp ;
379380 uint32_t reg ;
@@ -385,6 +386,10 @@ static bool mbs_fc03_hreg_read(struct modbus_context *ctx)
385386 sys_put_be32 (reg , presp );
386387 presp += sizeof (uint32_t );
387388 }
389+
390+ /* Increment current register address */
391+ reg_addr += 2 ;
392+ reg_qty -= 2 ;
388393 }
389394
390395 if (err != 0 ) {
@@ -393,9 +398,6 @@ static bool mbs_fc03_hreg_read(struct modbus_context *ctx)
393398 return true;
394399 }
395400
396- /* Increment current register address */
397- reg_addr ++ ;
398- reg_qty -- ;
399401 }
400402
401403 return true;
@@ -432,6 +434,16 @@ static bool mbs_fc04_inreg_read(struct modbus_context *ctx)
432434 reg_addr = sys_get_be16 (& ctx -> rx_adu .data [0 ]);
433435 reg_qty = sys_get_be16 (& ctx -> rx_adu .data [2 ]);
434436
437+ if (reg_qty == 0 || reg_qty > regs_limit ) {
438+ LOG_ERR ("Wrong register quantity, %u (limit is %u)" ,
439+ reg_qty , regs_limit );
440+ mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
441+ return true;
442+ }
443+
444+ /* Get number of bytes needed for response. */
445+ num_bytes = (uint8_t )(reg_qty * sizeof (uint16_t ));
446+
435447 if ((reg_addr < MODBUS_FP_EXTENSIONS_ADDR ) ||
436448 !IS_ENABLED (CONFIG_MODBUS_FP_EXTENSIONS )) {
437449 /* Read integer register */
@@ -440,29 +452,17 @@ static bool mbs_fc04_inreg_read(struct modbus_context *ctx)
440452 return true;
441453 }
442454
443- if (reg_qty == 0 || reg_qty > regs_limit ) {
444- LOG_ERR ("Number of registers limit exceeded" );
445- mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
446- return true;
447- }
448-
449- /* Get number of bytes needed for response. */
450- num_bytes = (uint8_t )(reg_qty * sizeof (uint16_t ));
451455 } else {
452456 /* Read floating-point register */
453457 if (ctx -> mbs_user_cb -> input_reg_rd_fp == NULL ) {
454458 mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_FC );
455459 return true;
456460 }
457461
458- if (reg_qty == 0 || reg_qty > (regs_limit / 2 )) {
459- LOG_ERR ("Number of registers limit exceeded" );
460- mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
462+ if (num_bytes % sizeof (uint32_t )) {
463+ mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_FC );
461464 return true;
462465 }
463-
464- /* Get number of bytes needed for response. */
465- num_bytes = (uint8_t )(reg_qty * sizeof (float ));
466466 }
467467
468468 /* Number of data bytes + byte count. */
@@ -484,6 +484,9 @@ static bool mbs_fc04_inreg_read(struct modbus_context *ctx)
484484 presp += sizeof (uint16_t );
485485 }
486486
487+ /* Increment current register number */
488+ reg_addr ++ ;
489+ reg_qty -- ;
487490 } else if (IS_ENABLED (CONFIG_MODBUS_FP_EXTENSIONS )) {
488491 float fp ;
489492 uint32_t reg ;
@@ -495,17 +498,17 @@ static bool mbs_fc04_inreg_read(struct modbus_context *ctx)
495498 sys_put_be32 (reg , presp );
496499 presp += sizeof (uint32_t );
497500 }
501+
502+ /* Increment current register address */
503+ reg_addr += 2 ;
504+ reg_qty -= 2 ;
498505 }
499506
500507 if (err != 0 ) {
501508 LOG_INF ("Input register address not supported" );
502509 mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_ADDR );
503510 return true;
504511 }
505-
506- /* Increment current register number */
507- reg_addr ++ ;
508- reg_qty -- ;
509512 }
510513
511514 return true;
@@ -833,7 +836,6 @@ static bool mbs_fc16_hregs_write(struct modbus_context *ctx)
833836 uint16_t reg_addr ;
834837 uint16_t reg_qty ;
835838 uint16_t num_bytes ;
836- uint8_t reg_size ;
837839
838840 if (ctx -> rx_adu .length < request_len ) {
839841 LOG_ERR ("Wrong request length %u" , ctx -> rx_adu .length );
@@ -845,35 +847,30 @@ static bool mbs_fc16_hregs_write(struct modbus_context *ctx)
845847 /* Get the byte count for the data. */
846848 num_bytes = ctx -> rx_adu .data [4 ];
847849
850+ if (reg_qty == 0 || reg_qty > regs_limit ) {
851+ LOG_ERR ("Number of registers limit exceeded" );
852+ mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
853+ return true;
854+ }
855+
848856 if ((reg_addr < MODBUS_FP_EXTENSIONS_ADDR ) ||
849857 !IS_ENABLED (CONFIG_MODBUS_FP_EXTENSIONS )) {
850858 /* Write integer register */
851859 if (ctx -> mbs_user_cb -> holding_reg_wr == NULL ) {
852860 mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_FC );
853861 return true;
854862 }
855-
856- if (reg_qty == 0 || reg_qty > regs_limit ) {
857- LOG_ERR ("Number of registers limit exceeded" );
858- mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
859- return true;
860- }
861-
862- reg_size = sizeof (uint16_t );
863863 } else {
864864 /* Write floating-point register */
865865 if (ctx -> mbs_user_cb -> holding_reg_wr_fp == NULL ) {
866866 mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_FC );
867867 return true;
868868 }
869869
870- if (reg_qty == 0 || reg_qty > (regs_limit / 2 )) {
871- LOG_ERR ("Number of registers limit exceeded" );
872- mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
870+ if (num_bytes % sizeof (uint32_t )) {
871+ mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_FC );
873872 return true;
874873 }
875-
876- reg_size = sizeof (float );
877874 }
878875
879876 /* Compare number of bytes and payload length */
@@ -883,7 +880,7 @@ static bool mbs_fc16_hregs_write(struct modbus_context *ctx)
883880 return true;
884881 }
885882
886- if ((num_bytes / reg_qty ) != (uint16_t )reg_size ) {
883+ if ((num_bytes / reg_qty ) != sizeof (uint16_t )) {
887884 LOG_ERR ("Mismatch in the number of registers" );
888885 mbs_exception_rsp (ctx , MODBUS_EXC_ILLEGAL_DATA_VAL );
889886 return true;
@@ -892,7 +889,7 @@ static bool mbs_fc16_hregs_write(struct modbus_context *ctx)
892889 /* The 1st registers data byte is 6th element in payload */
893890 prx_data = & ctx -> rx_adu .data [5 ];
894891
895- for (uint16_t reg_cntr = 0 ; reg_cntr < reg_qty ; reg_cntr ++ ) {
892+ for (uint16_t reg_cntr = 0 ; reg_cntr < reg_qty ;) {
896893 uint16_t addr = reg_addr + reg_cntr ;
897894
898895 if ((reg_addr < MODBUS_FP_EXTENSIONS_ADDR ) ||
@@ -901,14 +898,16 @@ static bool mbs_fc16_hregs_write(struct modbus_context *ctx)
901898
902899 prx_data += sizeof (uint16_t );
903900 err = ctx -> mbs_user_cb -> holding_reg_wr (addr , reg_val );
901+ reg_cntr ++ ;
904902 } else {
905903 uint32_t reg_val = sys_get_be32 (prx_data );
906904 float fp ;
907905
908906 /* Write to floating point register */
909- memcpy (& fp , & reg_val , sizeof (float ));
907+ memcpy (& fp , & reg_val , sizeof (uint32_t ));
910908 prx_data += sizeof (uint32_t );
911909 err = ctx -> mbs_user_cb -> holding_reg_wr_fp (addr , fp );
910+ reg_cntr += 2 ;
912911 }
913912
914913 if (err != 0 ) {
0 commit comments