Use a packet structure to wrap raw data
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
This commit is contained in:
parent
a882228458
commit
acf1cffec1
|
@ -48,10 +48,79 @@ class Squinnondation:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
data, addr = squirrel.receive_raw_data()
|
data, addr = squirrel.receive_raw_data()
|
||||||
print("received message: %s" % data)
|
pkt = Packet.unmarshal(data)
|
||||||
|
print("received message: %d %d %d %s" % (pkt.magic, pkt.version, pkt.body_length, pkt.body.raw_data))
|
||||||
|
print(str(pkt.marshal()))
|
||||||
# squirrel.send_raw_data(hazelnut, b"Hello squirrel!")
|
# squirrel.send_raw_data(hazelnut, b"Hello squirrel!")
|
||||||
|
|
||||||
|
|
||||||
|
class TLV:
|
||||||
|
"""
|
||||||
|
The Tag-Length-Value contains the different type of data that can be sent.
|
||||||
|
TODO: add subclasses for each type of TLV
|
||||||
|
"""
|
||||||
|
type: int
|
||||||
|
raw_data: bytes
|
||||||
|
|
||||||
|
def validate_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
Ensure that the TLV is well-formed.
|
||||||
|
Raises a ValueError if it is not the case.
|
||||||
|
TODO: Make some tests
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class Packet:
|
||||||
|
"""
|
||||||
|
A Packet is a wrapper around the
|
||||||
|
"""
|
||||||
|
magic: int
|
||||||
|
version: int
|
||||||
|
body_length: int
|
||||||
|
body: TLV
|
||||||
|
|
||||||
|
def validate_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
Ensure that the packet is well-formed.
|
||||||
|
Raises a ValueError if the packet contains bad data.
|
||||||
|
"""
|
||||||
|
if self.magic != 95:
|
||||||
|
raise ValueError("The magic code of the packet must be 95, found: {:d}".format(self.magic))
|
||||||
|
if self.version != 0:
|
||||||
|
raise ValueError("The version of the packet is not supported: {:d}".format(self.version))
|
||||||
|
if not (0 <= self.body_length <= 120):
|
||||||
|
raise ValueError("The body length of the packet is negative or too high. It must be between 0 and 1020,"
|
||||||
|
"found: {:d}".format(self.body_length))
|
||||||
|
return self.body.validate_data()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def unmarshal(data: bytes) -> "Packet":
|
||||||
|
"""
|
||||||
|
Read raw data and build the packet wrapper.
|
||||||
|
Raises a ValueError whenever the data is invalid.
|
||||||
|
"""
|
||||||
|
pkt = Packet()
|
||||||
|
pkt.magic = data[0]
|
||||||
|
pkt.version = data[1]
|
||||||
|
pkt.body_length = int.from_bytes(data[2:4], byteorder="big")
|
||||||
|
pkt.body = TLV()
|
||||||
|
pkt.body.raw_data = data[4:4+pkt.body_length]
|
||||||
|
|
||||||
|
pkt.validate_data()
|
||||||
|
|
||||||
|
return pkt
|
||||||
|
|
||||||
|
def marshal(self) -> bytes:
|
||||||
|
"""
|
||||||
|
Compute the byte array data associated to the packet.
|
||||||
|
"""
|
||||||
|
data = bytes([self.magic, self.version])
|
||||||
|
data += self.body_length.to_bytes(2, "big")
|
||||||
|
data += self.body.raw_data
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class Hazelnut:
|
class Hazelnut:
|
||||||
"""
|
"""
|
||||||
A hazelnut is a connected client, with its socket.
|
A hazelnut is a connected client, with its socket.
|
||||||
|
|
Loading…
Reference in New Issue