RUT301 - MQTT Modbus Gateway — Signed/Unsigned Register Value Mismatch (Read vs. Write)

Firmware version: RUT301_R_00.07.x
Device: RUT301
Feature: MQTT Modbus Gateway


Description

There is a signed/unsigned integer interpretation inconsistency in the MQTT Modbus Gateway. Read operations (function code 3) return register values as signed int16, while write operations (function code 16) only accept unsigned uint16 values. This mismatch makes it impossible to use the read response values directly in a subsequent write request.


Steps to Reproduce

1. Read 4 registers holding the value 0xFFFF:

{
  "cookie": 1000,
  "type": 0,
  "host": "10.34.56.127",
  "port": 502,
  "timeout": 5,
  "server_id": 247,
  "function": 3,
  "register_number": 40039,
  "register_count": 4
}

Response:

{"cookie":1000,"success":true,"data":[-1,-1,-1,-1]}

The registers contain 0xFFFF. The gateway returns these as -1 (signed int16 interpretation).


2. Attempt to write back the values returned by the read:

{
  "cookie": 1001,
  "type": 0,
  "host": "10.34.56.127",
  "port": 502,
  "timeout": 1,
  "server_id": 247,
  "function": 16,
  "register_number": 40039,
  "values": [-1,-1,-1,-1]
}

Response:

{"cookie":1001,"success":false,"error":"Bad field 'values' at index 0, out of bounds"}

The write fails because -1 is rejected as out of bounds.


3. Write using unsigned equivalents instead:

{
  "cookie": 1002,
  "type": 0,
  "host": "10.34.56.127",
  "port": 502,
  "timeout": 1,
  "server_id": 247,
  "function": 16,
  "register_number": 40039,
  "values": [65535,65535,65535,65535]
}

Response: Success — write completes without error.


Expected Behavior

Read and write operations should use a consistent value representation. Since Modbus registers are inherently 16-bit unsigned (0x00000xFFFF), read responses should return values in uint16 format (range 065535), not signed int16 (range -3276832767).

This would allow read values to be passed directly into write requests without any manual conversion.


Impact

Any application that reads register values and writes them back (e.g. copy, mirror, or restore operations) will silently fail unless the client manually converts the signed values to unsigned — a non-obvious requirement that is not documented.