simonvetter / modbus

Go modbus stack (client and server)
MIT License
262 stars 83 forks source link

Write function code for HandleHoldingRegisters #32

Open shantanoo opened 1 year ago

shantanoo commented 1 year ago

In TCP server implementation, how to find whether the function code was 6 or 16 (0x10)? And how to respond to it specifically?

type HoldingRegistersRequest struct {
    ClientAddr string   // the source (client) IP address
    ClientRole string   // the client role as encoded in the client certificate (tcp+tls only)
    UnitId     uint8    // the requested unit id (slave id)
    Addr       uint16   // the base register address requested
    Quantity   uint16   // the number of consecutive registers covered by this request
    IsWrite    bool     // true if the request is a write, false if a read
    Args       []uint16 // a slice of register values to be set, ordered from
                        // Addr to Addr + Quantity - 1 (for writes only)
}
shantanoo commented 1 year ago

Pull Request #33

simonvetter commented 1 year ago

Hi shantanoo,

first off, thanks for the pull request!

I'm trying to keep the code/API simple and concise, so I'm trying to understand the rationale behind this. Why would you need to differentiate between holding reg write opcodes?

shantanoo commented 1 year ago

Need to take action based on opcode. E.g. only write multiple registers should be supported and single register should return error. Might be better to different handler functions for single and multiple registers to have one-to-one mapping as per modbus specification.

simonvetter commented 1 year ago

only write multiple registers should be supported and single register should return error

If what you're trying to achieve is to make sure that multiple registers are being written atomically (instead of a single register), would testing on Quantity work in your handler? Something along those lines:

if isWrite && req.Quantity < 2 {
  err = ErrIllegalDataValue
  return
}

Note that your handler still wouldn't be able to tell if that request came through opcode 0x6 or through 0x10 with a single register, but that shouldn't be a concern for your use case.

Note that this technique can also be used on reads, if you ever want to ensure that reads are atomic as well.

shantanoo commented 1 year ago

Actually I am trying to read the modbus request on TCP server/slave and get the data from RTU client/master. In that case, server don't know what type of request comes from the client. Hence needed to differentiate between function code 6 and 16 (0x10).