Commit 618f06bafb7a213eeaa88a7fca68285434b22f4c

Authored by Stéphane Raimbault
1 parent 084e7e6a

Check the number of values in the response is corresponding to the query.

Showing 1 changed file with 33 additions and 13 deletions
modbus/modbus.c
@@ -616,32 +616,51 @@ static int modbus_receive(modbus_param_t *mb_param, @@ -616,32 +616,51 @@ static int modbus_receive(modbus_param_t *mb_param,
616 response, &response_length); 616 response, &response_length);
617 if (ret == 0) { 617 if (ret == 0) {
618 /* GOOD RESPONSE */ 618 /* GOOD RESPONSE */
  619 + int query_nb_value;
  620 + int response_nb_value;
619 621
620 - /* The number of values is returned for the following  
621 - * cases */ 622 + /* The number of values is returned if it's corresponding
  623 + * to the query */
622 switch (response[offset + 1]) { 624 switch (response[offset + 1]) {
623 case FC_READ_COIL_STATUS: 625 case FC_READ_COIL_STATUS:
624 case FC_READ_INPUT_STATUS: 626 case FC_READ_INPUT_STATUS:
625 - /* Read functions 1 value = 1 byte */  
626 - ret = response[offset + 2]; 627 + /* Read functions, 8 values in a byte (nb
  628 + * of values in the query and byte count in
  629 + * the response. */
  630 + query_nb_value = (query[offset+4] << 8) + query[offset+5];
  631 + query_nb_value = (query_nb_value / 8) + ((query_nb_value % 8) ? 1 : 0);
  632 + response_nb_value = response[offset + 2];
627 break; 633 break;
628 case FC_READ_HOLDING_REGISTERS: 634 case FC_READ_HOLDING_REGISTERS:
629 case FC_READ_INPUT_REGISTERS: 635 case FC_READ_INPUT_REGISTERS:
630 /* Read functions 1 value = 2 bytes */ 636 /* Read functions 1 value = 2 bytes */
631 - ret = response[offset + 2] / 2; 637 + query_nb_value = (query[offset+4] << 8) + query[offset+5];
  638 + response_nb_value = (response[offset + 2] / 2);
632 break; 639 break;
633 case FC_FORCE_MULTIPLE_COILS: 640 case FC_FORCE_MULTIPLE_COILS:
634 case FC_PRESET_MULTIPLE_REGISTERS: 641 case FC_PRESET_MULTIPLE_REGISTERS:
635 /* N Write functions */ 642 /* N Write functions */
636 - ret = response[offset + 4] << 8 |  
637 - response[offset + 5]; 643 + query_nb_value = (query[offset+4] << 8) + query[offset+5];
  644 + response_nb_value = (response[offset + 4] << 8) | response[offset + 5];
638 break; 645 break;
639 case FC_REPORT_SLAVE_ID: 646 case FC_REPORT_SLAVE_ID:
640 /* Report slave ID (bytes received) */ 647 /* Report slave ID (bytes received) */
  648 + query_nb_value = response_nb_value = response_length;
641 break; 649 break;
642 default: 650 default:
643 /* 1 Write functions & others */ 651 /* 1 Write functions & others */
644 - ret = 1; 652 + query_nb_value = response_nb_value = 1;
  653 + }
  654 +
  655 + if (query_nb_value == response_nb_value) {
  656 + ret = response_nb_value;
  657 + } else {
  658 + char *s_error = malloc(64 * sizeof(char));
  659 + sprintf(s_error, "Quantity (%d) not corresponding to the query (%d)",
  660 + response_nb_value, query_nb_value);
  661 + ret = ILLEGAL_DATA_VALUE;
  662 + error_treat(mb_param, ILLEGAL_DATA_VALUE, s_error);
  663 + free(s_error);
645 } 664 }
646 } else if (ret == COMM_TIME_OUT) { 665 } else if (ret == COMM_TIME_OUT) {
647 666
@@ -669,9 +688,8 @@ static int modbus_receive(modbus_param_t *mb_param, @@ -669,9 +688,8 @@ static int modbus_receive(modbus_param_t *mb_param,
669 if (exception_code < NB_TAB_ERROR_MSG) { 688 if (exception_code < NB_TAB_ERROR_MSG) {
670 error_treat(mb_param, -exception_code, 689 error_treat(mb_param, -exception_code,
671 TAB_ERROR_MSG[response[offset + 2]]); 690 TAB_ERROR_MSG[response[offset + 2]]);
  691 + /* RETURN THE EXCEPTION CODE */
672 /* Modbus error code is negative */ 692 /* Modbus error code is negative */
673 -  
674 - /* RETURN THE GOOD EXCEPTION CODE */  
675 return -exception_code; 693 return -exception_code;
676 } else { 694 } else {
677 /* The chances are low to hit this 695 /* The chances are low to hit this
@@ -781,7 +799,8 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query, @@ -781,7 +799,8 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
781 } 799 }
782 break; 800 break;
783 case FC_READ_INPUT_STATUS: { 801 case FC_READ_INPUT_STATUS: {
784 - /* Similar to coil status */ 802 + /* Similar to coil status (but too much arguments to use a
  803 + * function) */
785 int nb = (query[offset+4] << 8) + query[offset+5]; 804 int nb = (query[offset+4] << 8) + query[offset+5];
786 805
787 if ((address + nb) > mb_mapping->nb_input_status) { 806 if ((address + nb) > mb_mapping->nb_input_status) {
@@ -819,7 +838,8 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query, @@ -819,7 +838,8 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
819 } 838 }
820 break; 839 break;
821 case FC_READ_INPUT_REGISTERS: { 840 case FC_READ_INPUT_REGISTERS: {
822 - /* Similar to holding registers */ 841 + /* Similar to holding registers (but too much arguments to use a
  842 + * function) */
823 int nb = (query[offset+4] << 8) + query[offset+5]; 843 int nb = (query[offset+4] << 8) + query[offset+5];
824 844
825 if ((address + nb) > mb_mapping->nb_input_registers) { 845 if ((address + nb) > mb_mapping->nb_input_registers) {
@@ -1059,7 +1079,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function, @@ -1059,7 +1079,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function,
1059 /* If ret is negative, the loop is jumped ! */ 1079 /* If ret is negative, the loop is jumped ! */
1060 for (i = 0; i < ret; i++) { 1080 for (i = 0; i < ret; i++) {
1061 /* shift reg hi_byte to temp OR with lo_byte */ 1081 /* shift reg hi_byte to temp OR with lo_byte */
1062 - data_dest[i] = response[offset + 3 + (i << 1)] << 8 | 1082 + data_dest[i] = (response[offset + 3 + (i << 1)] << 8) |
1063 response[offset + 4 + (i << 1)]; 1083 response[offset + 4 + (i << 1)];
1064 } 1084 }
1065 } 1085 }