diff --git a/modbus/modbus.c b/modbus/modbus.c index 73afe14..b6c9e91 100644 --- a/modbus/modbus.c +++ b/modbus/modbus.c @@ -616,32 +616,51 @@ static int modbus_receive(modbus_param_t *mb_param, response, &response_length); if (ret == 0) { /* GOOD RESPONSE */ + int query_nb_value; + int response_nb_value; - /* The number of values is returned for the following - * cases */ + /* The number of values is returned if it's corresponding + * to the query */ switch (response[offset + 1]) { case FC_READ_COIL_STATUS: case FC_READ_INPUT_STATUS: - /* Read functions 1 value = 1 byte */ - ret = response[offset + 2]; + /* Read functions, 8 values in a byte (nb + * of values in the query and byte count in + * the response. */ + query_nb_value = (query[offset+4] << 8) + query[offset+5]; + query_nb_value = (query_nb_value / 8) + ((query_nb_value % 8) ? 1 : 0); + response_nb_value = response[offset + 2]; break; case FC_READ_HOLDING_REGISTERS: case FC_READ_INPUT_REGISTERS: /* Read functions 1 value = 2 bytes */ - ret = response[offset + 2] / 2; + query_nb_value = (query[offset+4] << 8) + query[offset+5]; + response_nb_value = (response[offset + 2] / 2); break; case FC_FORCE_MULTIPLE_COILS: case FC_PRESET_MULTIPLE_REGISTERS: /* N Write functions */ - ret = response[offset + 4] << 8 | - response[offset + 5]; + query_nb_value = (query[offset+4] << 8) + query[offset+5]; + response_nb_value = (response[offset + 4] << 8) | response[offset + 5]; break; case FC_REPORT_SLAVE_ID: /* Report slave ID (bytes received) */ + query_nb_value = response_nb_value = response_length; break; default: /* 1 Write functions & others */ - ret = 1; + query_nb_value = response_nb_value = 1; + } + + if (query_nb_value == response_nb_value) { + ret = response_nb_value; + } else { + char *s_error = malloc(64 * sizeof(char)); + sprintf(s_error, "Quantity (%d) not corresponding to the query (%d)", + response_nb_value, query_nb_value); + ret = ILLEGAL_DATA_VALUE; + error_treat(mb_param, ILLEGAL_DATA_VALUE, s_error); + free(s_error); } } else if (ret == COMM_TIME_OUT) { @@ -669,9 +688,8 @@ static int modbus_receive(modbus_param_t *mb_param, if (exception_code < NB_TAB_ERROR_MSG) { error_treat(mb_param, -exception_code, TAB_ERROR_MSG[response[offset + 2]]); + /* RETURN THE EXCEPTION CODE */ /* Modbus error code is negative */ - - /* RETURN THE GOOD EXCEPTION CODE */ return -exception_code; } else { /* The chances are low to hit this @@ -781,7 +799,8 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query, } break; case FC_READ_INPUT_STATUS: { - /* Similar to coil status */ + /* Similar to coil status (but too much arguments to use a + * function) */ int nb = (query[offset+4] << 8) + query[offset+5]; 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, } break; case FC_READ_INPUT_REGISTERS: { - /* Similar to holding registers */ + /* Similar to holding registers (but too much arguments to use a + * function) */ int nb = (query[offset+4] << 8) + query[offset+5]; 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, /* If ret is negative, the loop is jumped ! */ for (i = 0; i < ret; i++) { /* shift reg hi_byte to temp OR with lo_byte */ - data_dest[i] = response[offset + 3 + (i << 1)] << 8 | + data_dest[i] = (response[offset + 3 + (i << 1)] << 8) | response[offset + 4 + (i << 1)]; } }