Commit 3a6476e34cc2e3fd01f2b97fcfe762bdf0964407
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 | 721 | |
| 722 | 722 | /* Data are flushed on illegal number of values errors. */ |
| 723 | 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 | 731 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| 726 | 732 | /* The mapping can be shifted to reduce memory consumption and it |
| 727 | 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 | 736 | if (nb < 1 || MODBUS_MAX_READ_BITS < nb) { |
| 731 | 737 | rsp_length = response_exception( |
| 732 | 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 | 742 | rsp_length = response_exception( |
| 738 | 743 | ctx, &sft, |
| 739 | 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 | 747 | } else { |
| 743 | 748 | rsp_length = ctx->backend->build_response_basis(&sft, rsp); |
| 744 | 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 | 751 | rsp, rsp_length); |
| 748 | 752 | } |
| 749 | 753 | } |
| 750 | 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 | 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 | 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 | 767 | if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) { |
| 812 | 768 | rsp_length = response_exception( |
| 813 | 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 | 773 | rsp_length = response_exception( |
| 819 | 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 | 777 | } else { |
| 823 | 778 | int i; |
| 824 | 779 | |
| 825 | 780 | rsp_length = ctx->backend->build_response_basis(&sft, rsp); |
| 826 | 781 | rsp[rsp_length++] = nb << 1; |
| 827 | 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 | } | ... | ... |