Handle invalid object id request for a read device identification request


I came across a situation for which I don't get a clear definition from the Modbus Application Protocol Specification (v1.1b3). It's about the MEI type 14 "read device identification" as part of Function Code 43 "encapsulated interface transport".

Let's assume that a device supports basic and regular category:

With stream access, the device returns all objects from the requested category starting at the object id stated in the request.
But how should the device respond if the object id is not within the category, i.e., a mismatch between ReadDevId code and object id?

1. Request for basic category with stream access and object id 5 (which is in regular category):
req.PDU: 2B 0E 01 05

2. Request for regular category with stream access and object id 1 (which is in basic category):
req.PDU: 2B 0E 02 01

I get two possible behaviors from the specification:

If the Object Id does not match any known object, the server responds as if object 0 were pointed out (restart at the beginning).
Figure 30: Object Id OK = NO -> Exception Code 02 "illegal data address"

I'm curious to know your opinion :)
I interpret the spec as saying, for any stream access the following is applicable:
If the Object Id does not match any known object, the server responds as if object 0 were pointed out (restart at the beginning).
My interpretations is that the exception code response is only for individual access:
In case of an individual access: ReadDevId code 04, the Object Id in the request gives the identification of the object to obtain, and if the Object Id doesn't match to any known object, the server returns an exception response with exception code = 02 (Illegal data address).
Keep in mind that the spec defines the 3 categories in an additive nature, i.e.. Regular data objects include Basic data objects and Extended data objects include both Regular and Basic data objects. So while your example #1 above should respond as if object 0 were requested, example #2 should start at object ID 1, since the Regular data encompasses all Basic data as well. That's at least how I interpret the spec.

I do agree, though, that Figure 30 seems to somewhat contradict the rest of the spec. It doesn't seem to diagram the stream access state machine - only the individual access. Also, I don't understand why the Object Id should be checked before the Read deviceID Code, as the ReadDevId code tells which Object Id's are valid for the requested category.
Thank you for your comments!

I agree with your opinion that the first quote applies to stream access only; "restart at the beginning" does not make sense for the individual access.

I think that the individual access is specified in sufficient detail. However, it's really hard to differentiate between those access types in the specification.

Figure 30 is not even only about the individual access because it shows also the segmentation which only applies to stream access. And checking Object Id before the Read deviceId code causes a mess in the implementation. That has always annoyed me...

My attempt to apply the rules for stream access:

Let's assume a device that supports basic and regular category with objects 0 to 6.

#req: Object Idreq: Read DeviceId codeResponseRemarks
101 (basic cat., stream access)objects 0, 1, 2
211 (basic cat., stream access)objects 1, 2
331 (basic cat., stream access)objects 0, 1, 2object 3 not within requested category -> "restart at beginning"
4421 (basic cat., stream access)objects 0, 1, 2object 42 unknown -> "restart at beginning"
502 (regular cat., stream access)objects 0, 1, 2, 3, 4, 5, 6
652 (regular cat., stream access)objects 5, 6
74242illegal data address or
illegal data value
undetermined because either individual access nor stream access!
8042illegal data value

The approach to "restart at beginning" is kind of okay for #3 and #4 but I don't get a solution for #7:
1) illegal data address if rules for individual access apply
2) illegal data value if rules for stream access apply because an invalid object Id is never been reported

I'd go with 1). What do you think?

I don't know the history of this Function Code / MEI type but I think it's a missed opportunity to specify a generic device identification. It's unnecessarily overcomplicated :-(
If you were strictly following Figure 30 in the spec (though we both agree seems backwards), that would dictate that exception code 02 Illegal Data Address be returned for your example #7, since the state diagram shows the Object ID being checked first.

However, my opinion is that it makes more sense to implement handling this function by checking the ReadDevId code first, it comes before the Object ID in the packet after all, so this would be a logical parsing of the packet. Therefore, this would result in returning exception code 03 Illegal Data Value.

As others have pointed out, there is no Modbus Police, so it's not so important which exception code is being returned, only that an exception code is being returned (most masters won't care which exception code is used either).

I too would be curious about the history of the MEI function code. It's a newer function code that is not in the original PI MBUS 300 spec. It does feel like it's a sort of hack to try to get Modbus to do something it shouldn't be doing and was never designed for (not that that's stopped anyone else from using Modbus for things it was never designed for - e.g., 32-bit data, strings, Enron/Daniels, etc.). It is overly complex and seems like an attempt to try to be as cool as the newer protocols on the block.
It is overly complex and seems like an attempt to try to be as cool as the newer protocols on the block.
and failed successfully...

Yes, there is no Modbus Police but the Modbus Organization started with a "Conformance Test" program which easily could cover all tests required to verify protocol compliance. Unfortunately, those tests are incomplete thus absolutely useless/meaningless :-(

I'd appreciate a new revision of the specification that addresses the known issues and shortcomings.