Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending SINT write request using client results in error #109

Open
mgomez12 opened this issue Jul 12, 2022 · 0 comments
Open

Sending SINT write request using client results in error #109

mgomez12 opened this issue Jul 12, 2022 · 0 comments

Comments

@mgomez12
Copy link

mgomez12 commented Jul 12, 2022

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:

if tag_type not in (None,parser.SINT.tag_type,parser.USINT.tag_type):

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant