|
@@ -706,6 +706,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
switch (function) {
|
|
switch (function) {
|
|
case MODBUS_FC_READ_COILS: {
|
|
case MODBUS_FC_READ_COILS: {
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
+ int addr = address - mb_mapping->offset_bits;
|
|
|
|
|
|
if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
|
|
if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
@@ -718,10 +719,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
- } else if ((address + nb) > mb_mapping->nb_bits) {
|
|
|
|
|
|
+ } else if (address < mb_mapping->offset_bits || (addr + nb) > mb_mapping->nb_bits) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_bits\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_bits\n",
|
|
- address + nb);
|
|
|
|
|
|
+ address < mb_mapping->offset_bits ? address : address + nb);
|
|
}
|
|
}
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
@@ -729,7 +730,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
} else {
|
|
} else {
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
|
|
rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
|
|
- rsp_length = response_io_status(address, nb,
|
|
|
|
|
|
+ rsp_length = response_io_status(addr, nb,
|
|
mb_mapping->tab_bits,
|
|
mb_mapping->tab_bits,
|
|
rsp, rsp_length);
|
|
rsp, rsp_length);
|
|
}
|
|
}
|
|
@@ -739,6 +740,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
/* Similar to coil status (but too many arguments to use a
|
|
/* Similar to coil status (but too many arguments to use a
|
|
* function) */
|
|
* function) */
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
+ int addr = address - mb_mapping->offset_input_bits;
|
|
|
|
|
|
if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
|
|
if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
@@ -751,10 +753,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
- } else if ((address + nb) > mb_mapping->nb_input_bits) {
|
|
|
|
|
|
+ } else if (address < mb_mapping->offset_input_bits || (addr + nb) > mb_mapping->nb_input_bits) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_input_bits\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_input_bits\n",
|
|
- address + nb);
|
|
|
|
|
|
+ address < mb_mapping->offset_input_bits ? address : address + nb);
|
|
}
|
|
}
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
@@ -762,7 +764,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
} else {
|
|
} else {
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
|
|
rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
|
|
- rsp_length = response_io_status(address, nb,
|
|
|
|
|
|
+ rsp_length = response_io_status(addr, nb,
|
|
mb_mapping->tab_input_bits,
|
|
mb_mapping->tab_input_bits,
|
|
rsp, rsp_length);
|
|
rsp, rsp_length);
|
|
}
|
|
}
|
|
@@ -770,6 +772,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
break;
|
|
break;
|
|
case MODBUS_FC_READ_HOLDING_REGISTERS: {
|
|
case MODBUS_FC_READ_HOLDING_REGISTERS: {
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
+ int addr = address - mb_mapping->offset_registers;
|
|
|
|
|
|
if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
|
|
if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
@@ -782,10 +785,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
- } else if ((address + nb) > mb_mapping->nb_registers) {
|
|
|
|
|
|
+ } else if (address < mb_mapping->offset_registers || (addr + nb) > mb_mapping->nb_registers) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_registers\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_registers\n",
|
|
- address + nb);
|
|
|
|
|
|
+ address < mb_mapping->offset_registers ? address : address + nb);
|
|
}
|
|
}
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
@@ -795,7 +798,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
|
|
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp[rsp_length++] = nb << 1;
|
|
rsp[rsp_length++] = nb << 1;
|
|
- for (i = address; i < address + nb; i++) {
|
|
|
|
|
|
+ for (i = addr; i < addr + nb; i++) {
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
|
|
}
|
|
}
|
|
@@ -806,6 +809,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
/* Similar to holding registers (but too many arguments to use a
|
|
/* Similar to holding registers (but too many arguments to use a
|
|
* function) */
|
|
* function) */
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
+ int addr = address - mb_mapping->offset_input_registers;
|
|
|
|
|
|
if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
|
|
if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
@@ -818,10 +822,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
- } else if ((address + nb) > mb_mapping->nb_input_registers) {
|
|
|
|
|
|
+ } else if (address < mb_mapping->offset_input_registers || (addr + nb) > mb_mapping->nb_input_registers) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_input_registers\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in read_input_registers\n",
|
|
- address + nb);
|
|
|
|
|
|
+ address < mb_mapping->offset_input_registers ? address : address + nb);
|
|
}
|
|
}
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
@@ -831,15 +835,17 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
|
|
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp[rsp_length++] = nb << 1;
|
|
rsp[rsp_length++] = nb << 1;
|
|
- for (i = address; i < address + nb; i++) {
|
|
|
|
|
|
+ for (i = addr; i < addr + nb; i++) {
|
|
rsp[rsp_length++] = mb_mapping->tab_input_registers[i] >> 8;
|
|
rsp[rsp_length++] = mb_mapping->tab_input_registers[i] >> 8;
|
|
rsp[rsp_length++] = mb_mapping->tab_input_registers[i] & 0xFF;
|
|
rsp[rsp_length++] = mb_mapping->tab_input_registers[i] & 0xFF;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
- case MODBUS_FC_WRITE_SINGLE_COIL:
|
|
|
|
- if (address >= mb_mapping->nb_bits) {
|
|
|
|
|
|
+ case MODBUS_FC_WRITE_SINGLE_COIL: {
|
|
|
|
+ int addr = address - mb_mapping->offset_bits;
|
|
|
|
+
|
|
|
|
+ if (address < mb_mapping->offset_bits || addr >= mb_mapping->nb_bits) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr,
|
|
fprintf(stderr,
|
|
"Illegal data address 0x%0X in write_bit\n",
|
|
"Illegal data address 0x%0X in write_bit\n",
|
|
@@ -852,7 +858,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
int data = (req[offset + 3] << 8) + req[offset + 4];
|
|
int data = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
|
|
if (data == 0xFF00 || data == 0x0) {
|
|
if (data == 0xFF00 || data == 0x0) {
|
|
- mb_mapping->tab_bits[address] = (data) ? ON : OFF;
|
|
|
|
|
|
+ mb_mapping->tab_bits[addr] = (data) ? ON : OFF;
|
|
memcpy(rsp, req, req_length);
|
|
memcpy(rsp, req, req_length);
|
|
rsp_length = req_length;
|
|
rsp_length = req_length;
|
|
} else {
|
|
} else {
|
|
@@ -866,9 +872,12 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
- case MODBUS_FC_WRITE_SINGLE_REGISTER:
|
|
|
|
- if (address >= mb_mapping->nb_registers) {
|
|
|
|
|
|
+ case MODBUS_FC_WRITE_SINGLE_REGISTER: {
|
|
|
|
+ int addr = address - mb_mapping->offset_registers;
|
|
|
|
+
|
|
|
|
+ if (address < mb_mapping->offset_registers || addr >= mb_mapping->nb_registers) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_register\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_register\n",
|
|
address);
|
|
address);
|
|
@@ -879,13 +888,15 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
} else {
|
|
} else {
|
|
int data = (req[offset + 3] << 8) + req[offset + 4];
|
|
int data = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
|
|
- mb_mapping->tab_registers[address] = data;
|
|
|
|
|
|
+ mb_mapping->tab_registers[addr] = data;
|
|
memcpy(rsp, req, req_length);
|
|
memcpy(rsp, req, req_length);
|
|
rsp_length = req_length;
|
|
rsp_length = req_length;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
case MODBUS_FC_WRITE_MULTIPLE_COILS: {
|
|
case MODBUS_FC_WRITE_MULTIPLE_COILS: {
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
+ int addr = address - mb_mapping->offset_bits;
|
|
|
|
|
|
if (nb < 1 || MODBUS_MAX_WRITE_BITS < nb) {
|
|
if (nb < 1 || MODBUS_MAX_WRITE_BITS < nb) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
@@ -901,17 +912,17 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
- } else if ((address + nb) > mb_mapping->nb_bits) {
|
|
|
|
|
|
+ } else if (address < mb_mapping->offset_bits || (addr + nb) > mb_mapping->nb_bits) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_bits\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_bits\n",
|
|
- address + nb);
|
|
|
|
|
|
+ address < mb_mapping->offset_bits ? address : address + nb);
|
|
}
|
|
}
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
} else {
|
|
} else {
|
|
/* 6 = byte count */
|
|
/* 6 = byte count */
|
|
- modbus_set_bits_from_bytes(mb_mapping->tab_bits, address, nb, &req[offset + 6]);
|
|
|
|
|
|
+ modbus_set_bits_from_bytes(mb_mapping->tab_bits, addr, nb, &req[offset + 6]);
|
|
|
|
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
|
|
/* 4 to copy the bit address (2) and the quantity of bits */
|
|
/* 4 to copy the bit address (2) and the quantity of bits */
|
|
@@ -922,6 +933,8 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
break;
|
|
break;
|
|
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: {
|
|
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: {
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
|
|
+ int addr = address - mb_mapping->offset_registers;
|
|
|
|
+
|
|
if (nb < 1 || MODBUS_MAX_WRITE_REGISTERS < nb) {
|
|
if (nb < 1 || MODBUS_MAX_WRITE_REGISTERS < nb) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr,
|
|
fprintf(stderr,
|
|
@@ -936,17 +949,17 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
- } else if ((address + nb) > mb_mapping->nb_registers) {
|
|
|
|
|
|
+ } else if (address < mb_mapping->offset_registers || (addr + nb) > mb_mapping->nb_registers) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_registers\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_registers\n",
|
|
- address + nb);
|
|
|
|
|
|
+ address < mb_mapping->offset_registers ? address : address + nb);
|
|
}
|
|
}
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
} else {
|
|
} else {
|
|
int i, j;
|
|
int i, j;
|
|
- for (i = address, j = 6; i < address + nb; i++, j += 2) {
|
|
|
|
|
|
+ for (i = addr, j = 6; i < addr + nb; i++, j += 2) {
|
|
/* 6 and 7 = first value */
|
|
/* 6 and 7 = first value */
|
|
mb_mapping->tab_registers[i] =
|
|
mb_mapping->tab_registers[i] =
|
|
(req[offset + j] << 8) + req[offset + j + 1];
|
|
(req[offset + j] << 8) + req[offset + j + 1];
|
|
@@ -983,8 +996,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
errno = ENOPROTOOPT;
|
|
errno = ENOPROTOOPT;
|
|
return -1;
|
|
return -1;
|
|
break;
|
|
break;
|
|
- case MODBUS_FC_MASK_WRITE_REGISTER:
|
|
|
|
- if (address >= mb_mapping->nb_registers) {
|
|
|
|
|
|
+ case MODBUS_FC_MASK_WRITE_REGISTER: {
|
|
|
|
+ int addr = address - mb_mapping->offset_registers;
|
|
|
|
+
|
|
|
|
+ if (address < mb_mapping->offset_registers || addr >= mb_mapping->nb_registers) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_register\n",
|
|
fprintf(stderr, "Illegal data address 0x%0X in write_register\n",
|
|
address);
|
|
address);
|
|
@@ -993,21 +1008,24 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
} else {
|
|
} else {
|
|
- uint16_t data = mb_mapping->tab_registers[address];
|
|
|
|
|
|
+ uint16_t data = mb_mapping->tab_registers[addr];
|
|
uint16_t and = (req[offset + 3] << 8) + req[offset + 4];
|
|
uint16_t and = (req[offset + 3] << 8) + req[offset + 4];
|
|
uint16_t or = (req[offset + 5] << 8) + req[offset + 6];
|
|
uint16_t or = (req[offset + 5] << 8) + req[offset + 6];
|
|
|
|
|
|
data = (data & and) | (or & (~and));
|
|
data = (data & and) | (or & (~and));
|
|
- mb_mapping->tab_registers[address] = data;
|
|
|
|
|
|
+ mb_mapping->tab_registers[addr] = data;
|
|
memcpy(rsp, req, req_length);
|
|
memcpy(rsp, req, req_length);
|
|
rsp_length = req_length;
|
|
rsp_length = req_length;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
case MODBUS_FC_WRITE_AND_READ_REGISTERS: {
|
|
case MODBUS_FC_WRITE_AND_READ_REGISTERS: {
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
int nb = (req[offset + 3] << 8) + req[offset + 4];
|
|
uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6];
|
|
uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6];
|
|
int nb_write = (req[offset + 7] << 8) + req[offset + 8];
|
|
int nb_write = (req[offset + 7] << 8) + req[offset + 8];
|
|
int nb_write_bytes = req[offset + 9];
|
|
int nb_write_bytes = req[offset + 9];
|
|
|
|
+ int addr = address - mb_mapping->offset_registers;
|
|
|
|
+ int addr_write = address_write - mb_mapping->offset_registers;
|
|
|
|
|
|
if (nb_write < 1 || MODBUS_MAX_WR_WRITE_REGISTERS < nb_write ||
|
|
if (nb_write < 1 || MODBUS_MAX_WR_WRITE_REGISTERS < nb_write ||
|
|
nb < 1 || MODBUS_MAX_WR_READ_REGISTERS < nb ||
|
|
nb < 1 || MODBUS_MAX_WR_READ_REGISTERS < nb ||
|
|
@@ -1023,12 +1041,15 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
rsp_length = response_exception(
|
|
rsp_length = response_exception(
|
|
ctx, &sft,
|
|
ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
|
|
- } else if ((address + nb) > mb_mapping->nb_registers ||
|
|
|
|
- (address_write + nb_write) > mb_mapping->nb_registers) {
|
|
|
|
|
|
+ } else if (address < mb_mapping->offset_registers ||
|
|
|
|
+ (addr + nb) > mb_mapping->nb_registers ||
|
|
|
|
+ address_write < mb_mapping->offset_registers ||
|
|
|
|
+ (addr_write + nb_write) > mb_mapping->nb_registers) {
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
fprintf(stderr,
|
|
fprintf(stderr,
|
|
"Illegal data read address 0x%0X or write address 0x%0X write_and_read_registers\n",
|
|
"Illegal data read address 0x%0X or write address 0x%0X write_and_read_registers\n",
|
|
- address + nb, address_write + nb_write);
|
|
|
|
|
|
+ address < mb_mapping->offset_registers ? address : address + nb,
|
|
|
|
+ address_write < mb_mapping->offset_registers ? address_write : address_write + nb_write);
|
|
}
|
|
}
|
|
rsp_length = response_exception(ctx, &sft,
|
|
rsp_length = response_exception(ctx, &sft,
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
|
|
@@ -1039,13 +1060,13 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
|
|
|
|
|
|
/* Write first.
|
|
/* Write first.
|
|
10 and 11 are the offset of the first values to write */
|
|
10 and 11 are the offset of the first values to write */
|
|
- for (i = address_write, j = 10; i < address_write + nb_write; i++, j += 2) {
|
|
|
|
|
|
+ for (i = addr_write, j = 10; i < addr_write + nb_write; i++, j += 2) {
|
|
mb_mapping->tab_registers[i] =
|
|
mb_mapping->tab_registers[i] =
|
|
(req[offset + j] << 8) + req[offset + j + 1];
|
|
(req[offset + j] << 8) + req[offset + j + 1];
|
|
}
|
|
}
|
|
|
|
|
|
/* and read the data for the response */
|
|
/* and read the data for the response */
|
|
- for (i = address; i < address + nb; i++) {
|
|
|
|
|
|
+ for (i = addr; i < addr + nb; i++) {
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
|
|
rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
|
|
}
|
|
}
|
|
@@ -1786,10 +1807,12 @@ int modbus_set_debug(modbus_t *ctx, int flag)
|
|
/* Allocates 4 arrays to store bits, input bits, registers and inputs
|
|
/* Allocates 4 arrays to store bits, input bits, registers and inputs
|
|
registers. The pointers are stored in modbus_mapping structure.
|
|
registers. The pointers are stored in modbus_mapping structure.
|
|
|
|
|
|
- The modbus_mapping_new() function shall return the new allocated structure if
|
|
|
|
|
|
+ The modbus_mapping_offset_new() function shall return the new allocated structure if
|
|
successful. Otherwise it shall return NULL and set errno to ENOMEM. */
|
|
successful. Otherwise it shall return NULL and set errno to ENOMEM. */
|
|
-modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
|
|
|
|
- int nb_registers, int nb_input_registers)
|
|
|
|
|
|
+modbus_mapping_t* modbus_mapping_offset_new(int nb_bits, int offset_bits,
|
|
|
|
+ int nb_input_bits, int offset_input_bits,
|
|
|
|
+ int nb_registers, int offset_registers,
|
|
|
|
+ int nb_input_registers, int offset_input_registers)
|
|
{
|
|
{
|
|
modbus_mapping_t *mb_mapping;
|
|
modbus_mapping_t *mb_mapping;
|
|
|
|
|
|
@@ -1800,6 +1823,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
|
|
|
|
|
|
/* 0X */
|
|
/* 0X */
|
|
mb_mapping->nb_bits = nb_bits;
|
|
mb_mapping->nb_bits = nb_bits;
|
|
|
|
+ mb_mapping->offset_bits = offset_bits;
|
|
if (nb_bits == 0) {
|
|
if (nb_bits == 0) {
|
|
mb_mapping->tab_bits = NULL;
|
|
mb_mapping->tab_bits = NULL;
|
|
} else {
|
|
} else {
|
|
@@ -1815,6 +1839,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
|
|
|
|
|
|
/* 1X */
|
|
/* 1X */
|
|
mb_mapping->nb_input_bits = nb_input_bits;
|
|
mb_mapping->nb_input_bits = nb_input_bits;
|
|
|
|
+ mb_mapping->offset_input_bits = offset_input_bits;
|
|
if (nb_input_bits == 0) {
|
|
if (nb_input_bits == 0) {
|
|
mb_mapping->tab_input_bits = NULL;
|
|
mb_mapping->tab_input_bits = NULL;
|
|
} else {
|
|
} else {
|
|
@@ -1830,6 +1855,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
|
|
|
|
|
|
/* 4X */
|
|
/* 4X */
|
|
mb_mapping->nb_registers = nb_registers;
|
|
mb_mapping->nb_registers = nb_registers;
|
|
|
|
+ mb_mapping->offset_registers = offset_registers;
|
|
if (nb_registers == 0) {
|
|
if (nb_registers == 0) {
|
|
mb_mapping->tab_registers = NULL;
|
|
mb_mapping->tab_registers = NULL;
|
|
} else {
|
|
} else {
|
|
@@ -1846,6 +1872,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
|
|
|
|
|
|
/* 3X */
|
|
/* 3X */
|
|
mb_mapping->nb_input_registers = nb_input_registers;
|
|
mb_mapping->nb_input_registers = nb_input_registers;
|
|
|
|
+ mb_mapping->offset_input_registers = offset_input_registers;
|
|
if (nb_input_registers == 0) {
|
|
if (nb_input_registers == 0) {
|
|
mb_mapping->tab_input_registers = NULL;
|
|
mb_mapping->tab_input_registers = NULL;
|
|
} else {
|
|
} else {
|
|
@@ -1865,6 +1892,12 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
|
|
return mb_mapping;
|
|
return mb_mapping;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
|
|
|
|
+ int nb_registers, int nb_input_registers)
|
|
|
|
+{
|
|
|
|
+ return modbus_mapping_offset_new(nb_bits, 0, nb_input_bits, 0, nb_registers, 0, nb_input_registers, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
/* Frees the 4 arrays */
|
|
/* Frees the 4 arrays */
|
|
void modbus_mapping_free(modbus_mapping_t *mb_mapping)
|
|
void modbus_mapping_free(modbus_mapping_t *mb_mapping)
|
|
{
|
|
{
|