import io import logging import struct import bson from lib.crypto_utils import aes_encrypt class LocoPacket: def __init__( self, identifier=0, status_code=0, loco_command="", body_type=0, body_length=0, body_payload=b"", ): self.id = identifier self.status_code = status_code self.loco_command = loco_command self.body_type = body_type self.body_length = body_length self.body_payload = body_payload def get_packet_bytes(self) -> bytes: try: f = io.BytesIO() f.write(struct.pack(" dict: loco_dict = vars(self) try: if loco_dict["body_payload"] and isinstance( loco_dict["body_payload"], bytes ): loco_dict["body_payload"] = bson.loads(self.body_payload) elif loco_dict["body_payload"] and isinstance( loco_dict["body_payload"], dict ): loco_dict["body_payload"] = self.body_payload except Exception as general_exception: loco_dict = {} logging.error( "Couldn't decode BSON body of %s packet. Exception: %s.", self.loco_command, general_exception, ) return loco_dict class LocoEncryptedPacket: def __init__(self, length=0, iv=b"", payload=b"", is_fragmented=False): self.length = length self.iv = iv self.payload = payload self.is_fragmented = is_fragmented def create_new_packet(self, loco_packet: LocoPacket) -> bytes: if not loco_packet: logging.error( "Could not create LOCO encrypted packet: LOCO packet data is None." ) return None encrypted_packet = aes_encrypt(loco_packet.get_packet_bytes(), self.iv) if not encrypted_packet: logging.error("Could not encrypt LOCO packet.") return None try: f = io.BytesIO() f.write(struct.pack(" bytes: try: f = io.BytesIO() f.write(struct.pack("