Hi Anja, not quite ... I think in general you will always be able to read the PLC4X supported datatypes as for all of the ones that aren't supported everywhere, we just read byte arrays in all cases. So you might encounter some situations where you see a REAL being passed, but perhaps also a byte[] (in that case only the requesting driver will know what to expect in the response)
Yeah ... the TransportSize vs. DataTransportSize was killing me when I created the first version of the S7 driver. It's really strange ... especially as DataTransportSize has something like "Byte/Word/DWord" as one size and obviously there are great differences in size. I think in general it boils down to if the size of the payload is provided in Bits or Bytes ... so the DataTransportSizes have flags that tell the Client how to interpret the size (Bits or Bytes). The error you are getting is probably related to the fact that some of the constant names in TransportSize have a counterpart in DataTransportSize (Well ... actually only REAL ;-) ) .. if you haven't had a look yet, I would stronlgy suggest you have a look at the mspec for S7. https://github.com/apache/plc4x/blob/develop/protocols/s7/src/main/resources/protocols/s7/s7.mspec If you have a look at the definition of TransportSize starting at line 419, this also contains which will be the expected DataTransportSize for a given TransportSize. So what you need it at least the Transport size used in the Request's Parameter Items as this is the only one you will be able to use for decoding. I hope I was able to shed some light on this. If not, don't hesitate to ask .. I'll probably be somewhere near my keyboard over the weekend (If the weather-forcast is correct) Chris Am 30.04.21 um 14:03 schrieb Anja Hager: > Hi, > so I tried to understand both of your answers :) > > What I get is: You can try to read values on the PLC given the datatype that > you wish to read e.g. DATE_AND_TIME, REAL etc. (which are defined via PLC4X, > have a protocolID ...). But I can't be sure if the PLC is supporting this > type and also if the value can be decoded or there will be some gibberish. Is > this correct? > So I had a look into my code again and what I was able to retrieve from the > original network byte stream. What I DO have is the transportsize from the > read request (e.g REAL, 0x08 as type TransportSize ) and also the > transportsize within the response (REAL, 0x07 as type DataTransportSize). How > does this DataTransportSize in the response correspond to the actual datatype > on the PLC? Is this just a wild guess? > I am able to map the response message back to the corresponding request. So > if I get the value as byte array I can tell that the request had been for > type REAL (0x08). I found that this is indeed a TransportSize variable, so it > should have the protocolID. But when I try getDataProtocolId() on this > variable I get the following compile time error: "incompatible types: > java.lang.String cannot be converted to short". If I get this to work I could > at least try to decode it. If the requested data type is the correct datatype > of the DB on PLC I would get a correctly parsed value, right? > I hope to get a partial solution to this at least, as this seems to become > quite complex in detail :( > Thanks again! > > Anja > > > > -----Ursprüngliche Nachricht----- > Von: Christofer Dutz <[email protected]> > Gesendet: Freitag, 30. April 2021 11:23 > An: [email protected] > Betreff: Re: Retrieving the value from byte[] for a S7 read operation > > Hi and first of all, welcome Anja, > > sorry for the late response. I was having "Issues" (TM) as I am currently > switching operating-systems and this is causing a tad of pain ;-) > > Regarding your question. > > As Lukasz already mentioned not all protocols support providing detailed > information on the datatype. Some just expect you to know. The S7 is somewhat > in-between ... it's a strange mixture of having some type information in the > request (but not response) but not enough to be explicit. > > > The Response just expects you to know what you asked for and doesn't waste > bandwidth for that. However there are some data-types that not all > S7 devices support equally. Some Date and Time and especially the huge > Integers and Double-Precision Real values aren't supported by all types. > Therefore we use a little trick: we know how big the datatype is, so instead > of requesting one of these data-types, we some-times request a byte-array of > the right size. This is probably a case where you don't know what's going > over the wire. In this case the software one layer up knows the type it > requested. And this is where the protocolId comes into place. We use this id > to identify all PLC4X Datatypes. So the driver knows the detailed datatype, > but the protocol doesn't > > This is specially true for protocols like Modbus, which generally only > support short and boolean and we simulate all the other types on top of that. > > We are currently working hard on implementing some Browse functionality, but > this is a) gonna take a bit of time and b) we're probably not going to be > able to do this for all. > > Chris > > > > > Am 30.04.21 um 11:01 schrieb Łukasz Dywicki: >> Hey Anja, >> I don't know by heart S7 protocol. I will try to answer based on other >> things I've seen. Maybe follow up replies will bring more light to us. >> :) >> >> Depending on protocol, some keep and propagate type information, some >> do not. If all you have within request/response is bit or byte size >> then it is really matter of interpretation of returned data. If you >> request 4 bytes of data and PLC answers with 4 bytes and no error then >> you can expect any type which fits into this limit. >> >> That's why in many cases an additional information is needed. Either >> put manually by technician or through list of (pre)defined tags announced by >> manufacturer who embeds given PLC. >> The request fields we define in our "client" code ship an expected >> data type on our end which then is used to map it to transport sizes >> understod by PLC. Yet actual value on PLC might be different than we >> define. Then you most likely will get decoding errors or values out of >> reasonable range. >> >> Actual reason for skipping type/length information is to minimize >> transfer overhead. Typical type-length-value (TLV) encoding adds one >> or two bytes thus some systems omit it and communicate only value. The >> type and length information is then delivered by other way. >> >> Best, >> Łukasz >> >> >> On 29.04.2021 14:32, Anja Hager wrote: >>> Hi everyone, >>> >>> >>> >>> I'm currently writing my master thesis on the topic of Architecture >>> Mining for S7 machines through analysis of pcap files. >>> >>> >>> >>> Therefore I'm already able to retrieve all the fields for request and >>> response messages (S7ParameterReadVarRequest tells me the read >>> request was for DB444:0.0:REAL and the corresponding >>> S7ParameterReadVarResponse contains the answer as data item >>> S7VarPayloadDataItem). >>> >>> Now I'm stuck at the point where I've got a byte array as returned by >>> item.getData() . How is it possible to convert this byte[] to the >>> concrete value of that DB, if the type is known >>> (item.getTransportSize() returns a DataTransportSize e.g. REAL, NULL >>> etc.) >>> >>> I want: data of response as byte[] "41 dd bf 4e" of type REAL --> >>> concrete >>> value: e.g. 123,456 >>> >>> >>> >>> I've had a look at the mechanism when actively reading a S7 DB e.g. >>> via HelloPlc4x example . Within S7ProtocolLogic.java a private >>> function (PlcValue parsePlcValue(S7Field field, ByteBuf data)) is >>> used : return DataItemIO.staticParse(readBuffer, >>> field.getDataType().getDataProtocolId(), >>> stringLength) >>> >>> Unfortunately in my case I don't have all the parameters. My data >>> types REAL, NULL, .. are types enum DataTransportSize not enum >>> TransportSize, so there is no protocolId. >>> >>> Is there any way to make use of this function or do you have any >>> other idea how to convert the bytes ? >>> >>> I would really appreciate any help in this. Thanks! >>> >>> >>> >>> Best, >>> >>> Anja Hager >>> >>> >>> >>> >
