0

I'm trying to do protocol decoding in Python.

Short version of my question:

  • I have received an array of bytes that is a packet of data.

    • Using the first byte of the packet, I know what type of packet it is.
    • Using that - I want to construct a packet via a class.
  • When i want to send a packet, really need to reuse about 90% of the processing done in the same packet class so that I can construct and send a packet.

I can do one of the above, I can't seem to do both

For example - something like this:


class PacketType123(BasePacketType):

    def __init__fromparams( self, field1, field2 ):
        # called when you want to send a packet
        # ... initialize like I'am sending the packet
        self.field1 = field1
        self.field2 = field2

    def encode_and_send(self,destination):
        # encode into raw byte
        databytes = self.encode()
        destination.send( databytes )

    # called when a packet is received on the wire
    def __init__frombytearray( self, bytearray ):
        self.decode_bytearray( bytearray )
        print("Hi Field2 = %d" % self.field2 )

# create packet decode lookup table.
lookuptable = dict()
# populate it with classes
lookuptable[123] = PacketType123
# other packets would added to the lookup table
lookuptable[44] = PacketType44
lookuptable[12] = PacketType12

To send

   p1 = PacketType1( 42, "dogs and cats" )
   p1.encode_and_send( server )

To process incomming data, do this:

   databytes = receive_message()

   packet = lookuptable[ datbytes[0] ].__init__frombytearray(databytes)

My problem is I can do either the ToSend or the ProcessIncomming, I don't know how to do both with the same class.

I've looked over:

It seems the only way to make this work is with keyword args.. Yuck that complicates other things for me... Looking for other way of doing this.

Suggestions please?

9
  • The reading and linked question certainly helps to show us what/how you have got to this point, but having additional examples from how you want the API to look like for your user would be even more useful. Then again, I am guessing you might not know exactly what you want. I am guessing that you have the BasePacketType class, your specific classes would inherit from that class, which will implement the specific constructors (i.e. the keyword arguments). Your question is how to turn a bytearray automagically into the correct subclass? Commented Feb 16, 2020 at 5:40
  • Essentially, I would imagine doing something like AutoPacket(some_bytearray), if the some_bytearray is decoded into something that has been registered into the lookup table, it will then produce the correct type, e.g. it would produce PacketType1 with field1 set to 42 and field2 set to "dogs and cats". Let us know if this is closer to to how you imagine this API might appear. Commented Feb 16, 2020 at 5:43
  • Also it would be useful to explain why you can't do both in the same class, when you essentially almost have a working implementation - I think what you are missing is to declare both decode_bytearray and __init__frombytearray as classmethod, and that decode_bytearray need to return something rather than setting some attributes inside the implementation. It would be useful to include what your current implementation is for the line that invoked self.decode_bytearray( bytearray ). Commented Feb 16, 2020 at 6:06
  • metatoaster - You have exactly what I'm trying to do: Commented Feb 17, 2020 at 0:12
  • @metatoaster - There are two use cases, case (A) is I want to send a packet, so create that type of packet/class. The class/packet contains an array of fields, each field is a small dict - with a "field_name", "type" (u8, u16, etc), and "description" Some fields are a bit more complex (enumerations which are further decoded). In the send case, you populate the thing.field['name'].value = 123, and then later thing.encoded_and_send(), when the packet comes back the same array is used to decode the byte stream back into the field array. Commented Feb 17, 2020 at 0:17

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.