Commit 3a6476e34cc2e3fd01f2b97fcfe762bdf0964407

Authored by Stéphane Raimbault
1 parent 05984bc0

Another round of DRY in modbus_reply()

Showing 1 changed file with 30 additions and 75 deletions
src/modbus.c
@@ -721,112 +721,67 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, @@ -721,112 +721,67 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
721 721
722 /* Data are flushed on illegal number of values errors. */ 722 /* Data are flushed on illegal number of values errors. */
723 switch (function) { 723 switch (function) {
724 - case MODBUS_FC_READ_COILS: { 724 + case MODBUS_FC_READ_COILS:
  725 + case MODBUS_FC_READ_DISCRETE_INPUTS: {
  726 + unsigned int is_input = (function == MODBUS_FC_READ_DISCRETE_INPUTS);
  727 + int start_bits = is_input ? mb_mapping->start_input_bits : mb_mapping->start_bits;
  728 + int nb_bits = is_input ? mb_mapping->nb_input_bits : mb_mapping->nb_bits;
  729 + uint8_t *tab_bits = is_input ? mb_mapping->tab_input_bits : mb_mapping->tab_bits;
  730 + const char * const name = is_input ? "read_input_bits" : "read_bits";
725 int nb = (req[offset + 3] << 8) + req[offset + 4]; 731 int nb = (req[offset + 3] << 8) + req[offset + 4];
726 /* The mapping can be shifted to reduce memory consumption and it 732 /* The mapping can be shifted to reduce memory consumption and it
727 doesn't always start at address zero. */ 733 doesn't always start at address zero. */
728 - int mapping_address = address - mb_mapping->start_bits; 734 + int mapping_address = address - start_bits;
729 735
730 if (nb < 1 || MODBUS_MAX_READ_BITS < nb) { 736 if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
731 rsp_length = response_exception( 737 rsp_length = response_exception(
732 ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp, TRUE, 738 ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp, TRUE,
733 - "Illegal nb of values %d in read_bits (max %d)\n",  
734 - nb, MODBUS_MAX_READ_BITS);  
735 - } else if (mapping_address < 0 ||  
736 - (mapping_address + nb) > mb_mapping->nb_bits) { 739 + "Illegal nb of values %d in %s (max %d)\n",
  740 + nb, name, MODBUS_MAX_READ_BITS);
  741 + } else if (mapping_address < 0 || (mapping_address + nb) > nb_bits) {
737 rsp_length = response_exception( 742 rsp_length = response_exception(
738 ctx, &sft, 743 ctx, &sft,
739 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp, FALSE, 744 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp, FALSE,
740 - "Illegal data address 0x%0X in read_bits\n",  
741 - mapping_address < 0 ? address : address + nb); 745 + "Illegal data address 0x%0X in %s\n",
  746 + mapping_address < 0 ? address : address + nb, name);
742 } else { 747 } else {
743 rsp_length = ctx->backend->build_response_basis(&sft, rsp); 748 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
744 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0); 749 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
745 - rsp_length = response_io_status(mb_mapping->tab_bits,  
746 - mapping_address, nb, 750 + rsp_length = response_io_status(tab_bits, mapping_address, nb,
747 rsp, rsp_length); 751 rsp, rsp_length);
748 } 752 }
749 } 753 }
750 break; 754 break;
751 - case MODBUS_FC_READ_DISCRETE_INPUTS: {  
752 - /* Similar to coil status (but too many arguments to use a  
753 - * function) */  
754 - int nb = (req[offset + 3] << 8) + req[offset + 4];  
755 - int mapping_address = address - mb_mapping->start_input_bits;  
756 -  
757 - if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {  
758 - rsp_length = response_exception(  
759 - ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp, TRUE,  
760 - "Illegal nb of values %d in read_input_bits (max %d)\n",  
761 - nb, MODBUS_MAX_READ_BITS);  
762 - } else if (mapping_address < 0 ||  
763 - (mapping_address + nb) > mb_mapping->nb_input_bits) {  
764 - rsp_length = response_exception(  
765 - ctx, &sft,  
766 - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp, FALSE,  
767 - "Illegal data address 0x%0X in read_input_bits\n",  
768 - mapping_address < 0 ? address : address + nb);  
769 - } else {  
770 - rsp_length = ctx->backend->build_response_basis(&sft, rsp);  
771 - rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);  
772 - rsp_length = response_io_status(mb_mapping->tab_input_bits,  
773 - mapping_address, nb,  
774 - rsp, rsp_length);  
775 - }  
776 - }  
777 - break;  
778 - case MODBUS_FC_READ_HOLDING_REGISTERS: {  
779 - int nb = (req[offset + 3] << 8) + req[offset + 4];  
780 - int mapping_address = address - mb_mapping->start_registers;  
781 -  
782 - if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {  
783 - rsp_length = response_exception(  
784 - ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp, TRUE,  
785 - "Illegal nb of values %d in read_registers (max %d)\n",  
786 - nb, MODBUS_MAX_READ_REGISTERS);  
787 - } else if (mapping_address < 0 ||  
788 - (mapping_address + nb) > mb_mapping->nb_registers) {  
789 - rsp_length = response_exception(  
790 - ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp, FALSE,  
791 - "Illegal data address 0x%0X in read_registers\n",  
792 - mapping_address < 0 ? address : address + nb);  
793 - } else {  
794 - int i;  
795 -  
796 - rsp_length = ctx->backend->build_response_basis(&sft, rsp);  
797 - rsp[rsp_length++] = nb << 1;  
798 - for (i = mapping_address; i < mapping_address + nb; i++) {  
799 - rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;  
800 - rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;  
801 - }  
802 - }  
803 - }  
804 - break; 755 + case MODBUS_FC_READ_HOLDING_REGISTERS:
805 case MODBUS_FC_READ_INPUT_REGISTERS: { 756 case MODBUS_FC_READ_INPUT_REGISTERS: {
806 - /* Similar to holding registers (but too many arguments to use a  
807 - * function) */ 757 + unsigned int is_input = (function == MODBUS_FC_READ_INPUT_REGISTERS);
  758 + int start_registers = is_input ? mb_mapping->start_input_registers : mb_mapping->start_registers;
  759 + int nb_registers = is_input ? mb_mapping->nb_input_registers : mb_mapping->nb_registers;
  760 + uint16_t *tab_registers = is_input ? mb_mapping->tab_input_registers : mb_mapping->tab_registers;
  761 + const char * const name = is_input ? "read_input_registers" : "read_registers";
808 int nb = (req[offset + 3] << 8) + req[offset + 4]; 762 int nb = (req[offset + 3] << 8) + req[offset + 4];
809 - int mapping_address = address - mb_mapping->start_input_registers; 763 + /* The mapping can be shifted to reduce memory consumption and it
  764 + doesn't always start at address zero. */
  765 + int mapping_address = address - start_registers;
810 766
811 if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) { 767 if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
812 rsp_length = response_exception( 768 rsp_length = response_exception(
813 ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp, TRUE, 769 ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp, TRUE,
814 - "Illegal number of values %d in read_input_registers (max %d)\n",  
815 - nb, MODBUS_MAX_READ_REGISTERS);  
816 - } else if (mapping_address < 0 ||  
817 - (mapping_address + nb) > mb_mapping->nb_input_registers) { 770 + "Illegal nb of values %d in %s (max %d)\n",
  771 + nb, name, MODBUS_MAX_READ_REGISTERS);
  772 + } else if (mapping_address < 0 || (mapping_address + nb) > nb_registers) {
818 rsp_length = response_exception( 773 rsp_length = response_exception(
819 ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp, FALSE, 774 ctx, &sft, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp, FALSE,
820 - "Illegal data address 0x%0X in read_input_registers\n",  
821 - mapping_address < 0 ? address : address + nb); 775 + "Illegal data address 0x%0X in %s\n",
  776 + mapping_address < 0 ? address : address + nb, name);
822 } else { 777 } else {
823 int i; 778 int i;
824 779
825 rsp_length = ctx->backend->build_response_basis(&sft, rsp); 780 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
826 rsp[rsp_length++] = nb << 1; 781 rsp[rsp_length++] = nb << 1;
827 for (i = mapping_address; i < mapping_address + nb; i++) { 782 for (i = mapping_address; i < mapping_address + nb; i++) {
828 - rsp[rsp_length++] = mb_mapping->tab_input_registers[i] >> 8;  
829 - rsp[rsp_length++] = mb_mapping->tab_input_registers[i] & 0xFF; 783 + rsp[rsp_length++] = tab_registers[i] >> 8;
  784 + rsp[rsp_length++] = tab_registers[i] & 0xFF;
830 } 785 }
831 } 786 }
832 } 787 }