I'm attempting to use the client to send EIP requests, but I had an issue pop up when the data type is an SINT. Essentially, I send the operation @0x64/1/0x05 = (SINT)-1, which fails with the following trace:
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/get_attribute.py:431: in read
for val,(sts,(att,typ,uni)) in reader:
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/get_attribute.py:618: in read_details
for i,(idx,dsc,req,rpy,sts,val) in enumerate( connection.operate(
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/client.py:1749: in operate
for idx,dsc,req,rpy,sts,val in harvested:
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/client.py:1599: in pipeline
iss = next( issuer )
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/client.py:1348: in issue
req = self.set_attribute_single( timeout=timeout, send=not multiple, **op )
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/client.py:903: in set_attribute_sing
e
self.req_send(
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/client.py:1188: in req_send
return self.unconnected_send( request, **kwds )
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/client.py:1074: in unconnected_send
us.request.input= bytearray( dialect.produce( us.request )) # eg. logix.Logix
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/logix.py:539: in produce
result = super( Logix, cls ).produce( data )
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/device.py:1797: in produce
result = super( Message_Router, cls ).produce( data )
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/device.py:1235: in produce
result += typed_data.produce( data.set_attribute_single,
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/parser.py:2103: in produce
result += b''.join( map( producer, data.get( 'data' )))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'cpppo.server.enip.parser.USINT'>, value = -1
@classmethod
def produce( cls, value ):
> return struct.pack( cls.struct_format, value )
E struct.error: ubyte format requires 0 <= number <= 255
/usr/local/lib/python3.8/dist-packages/cpppo/server/enip/parser.py:175: error
This is was unexpected because if the data was not valid for the specific type to begin with, it would have been caught with in the earlier int_validate step, however it doesn't fail until the produce function is called.
After digging a little more, I came across the following:
What I'm understanding is that if the data type is more than a byte long (aka USINT or SINT), it converts it to a byte array of USINTs that it can later send. However, since the data isn't getting formatted, the SINT retains its negative value, which then causes the issue down the line when it tries to pack the data as a USINT. This seems like a quick fix (just removing the SINT check from the quoted line), but I was wondering if there was an intended reason for this behavior since i don't think it's been mentioned before.
I'm attempting to use the client to send EIP requests, but I had an issue pop up when the data type is an SINT. Essentially, I send the operation @0x64/1/0x05 = (SINT)-1, which fails with the following trace:
This is was unexpected because if the data was not valid for the specific type to begin with, it would have been caught with in the earlier int_validate step, however it doesn't fail until the produce function is called.
After digging a little more, I came across the following:
https://github.com/pjkundert/cpppo/blob/4c217b6c06b88bede3888cc5ea2731f271a95086/server/enip/client.py#L888
What I'm understanding is that if the data type is more than a byte long (aka USINT or SINT), it converts it to a byte array of USINTs that it can later send. However, since the data isn't getting formatted, the SINT retains its negative value, which then causes the issue down the line when it tries to pack the data as a USINT. This seems like a quick fix (just removing the SINT check from the quoted line), but I was wondering if there was an intended reason for this behavior since i don't think it's been mentioned before.