class Data(Validatable): SCHEMA = [{ "offset": Types.OBJECT(Offset), "length": Types.BYTE(), "data": Types.BYTES() }] def __init__(self, data=[], offset=Offset()): self.offset = offset self.data = data super(Data, self).__init__() # for consistency with schema, e.g. if using generic attribute conversion, etc @property def length(self): return len(self.data) # the Python way ;-) def __len__(self): return self.length def __iter__(self): for byte in self.offset: yield byte yield chr(self.length) for byte in self.data: yield chr(byte) def __str__(self): return "{}, length={}, data={}".format(self.offset, self.length, self.data)
class Frame(Validatable): SCHEMA = [{ "timeout": Types.OBJECT(CT), "control": Types.OBJECT(Control), "origin_access_id": Types.BYTES( ), # TODO refactor to use OriginAddressee (subclass of addressee containing control and access_id) "d7atp_frame": Types.OBJECT(D7atpFrame) }] def __init__(self, timeout, control, origin_access_id, d7atp_frame): self.timeout = timeout self.control = control self.origin_access_id = origin_access_id self.d7atp_frame = d7atp_frame # TODO super(Frame, self).__init__() def __iter__(self): for byte in self.timeout: yield byte for byte in self.control: yield byte for byte in self.origin_access_id: yield byte for byte in self.d7atp_frame: yield byte
class QueryOperand(Validatable): SCHEMA = [{ "type": Types.ENUM(type=QueryType), "mask_present": Types.BOOLEAN(), "params": Types.OBJECT(ArithQueryParams), # TODO other query types "compare_length": Types.OBJECT(Length), "compare_value": Types.BYTES(), "file_a_offset": Types.OBJECT(Offset) }] def __init__(self, type, mask_present, params, compare_length, compare_value, file_a_offset): self.type = type self.mask_present = mask_present self.params = params self.compare_length = compare_length self.compare_value = compare_value self.file_a_offset = file_a_offset super(QueryOperand, self).__init__() def __iter__(self): byte = self.type.value << 5 byte += self.mask_present << 4 byte += bytearray(self.params)[0] yield byte for byte in self.compare_length: yield byte for byte in self.compare_value: yield byte for byte in self.file_a_offset: yield byte @staticmethod def parse(s): type = QueryType(s.read("uint:3")) assert (type == QueryType.ARITH_COMP_WITH_VALUE ) # TODO implement other types mask_present = s.read("bool") assert (mask_present is False) # TODO implement this params = ArithQueryParams.parse(s) compare_length = Length.parse(s) compare_value = map(ord, s.read("bytes:" + str(compare_length.value))) file_a_offset = Offset.parse(s) return QueryOperand(type=type, mask_present=mask_present, params=params, compare_length=compare_length, compare_value=compare_value, file_a_offset=file_a_offset)
class Frame(Validatable): SCHEMA = [{ "control": Types.OBJECT(Control), "origin_access_class": Types.BYTE(), "origin_access_id": Types.BYTES(), # TODO refactor to use OriginAddressee (subclass of addressee containing control and access_id) "d7atp_frame": Types.OBJECT(D7atpFrame) }] def __init__(self, control, origin_access_class, origin_access_id, d7atp_frame): self.control = control self.origin_access_class = origin_access_class self.origin_access_id = origin_access_id self.d7atp_frame = d7atp_frame # TODO super(Frame, self).__init__() @staticmethod def parse(bitstream, payload_length): control = Control.parse(bitstream) payload_length -= 1 # substract control origin_access_class = bitstream.read("uint:8") payload_length -= 1 assert control.has_hopping == False, "Not implemented yet" assert control.nls_method == NlsMethod.NONE, "Not implemented yet" if not control.has_no_origin_access_id: if control.origin_id_type == IdType.VID: origin_access_id = map(ord, bitstream.read("bytes:2")) payload_length = payload_length - 2 elif control.origin_id_type == IdType.UID: origin_access_id = map(ord, bitstream.read("bytes:8")) payload_length = payload_length - 8 else: assert False else: origin_access_id = [] #payload=map(ord,bitstream.read("bytes:" + str(payload_length))) d7atp_frame = D7atpFrame.parse(bitstream, payload_length) return Frame(control=control, origin_access_class=origin_access_class, origin_access_id=origin_access_id, d7atp_frame=d7atp_frame) def __iter__(self): for byte in self.control: yield byte yield self.origin_access_class for byte in self.origin_access_id: yield byte for byte in self.d7atp_frame: yield byte
class Frame(Validatable): SCHEMA = [{ "length": Types.BYTE(), "subnet": Types.BYTE(), "control": Types.OBJECT(Control), "target_address": Types.BYTES(), # TODO max size? "d7anp_frame": Types.OBJECT(D7anpFrame), # TODO assuming foreground frames for now "crc16": Types.BITS( 16 ) # TODO does not work, look into this later {'validator': validate_crc } }] def __init__(self, length, subnet, control, target_address, d7anp_frame, crc16): self.length = length self.subnet = subnet self.control = control self.target_address = target_address self.d7anp_frame = d7anp_frame self.crc16 = crc16 # TODO validate CRC super(Frame, self).__init__() # def validate_crc(self, value, error): # raw_data = [] # raw_data.append(self.length) # raw_data.append(self.subnet) # raw_data.append(self.control) # raw_data.append(self.target_address) # raw_data.append(self.payload) # crc = CRCCCITT().calculate(raw_data) def __iter__(self): yield self.length yield self.subnet for byte in self.control: yield byte for byte in self.target_address: yield byte for byte in self.d7anp_frame: yield byte yield self.crc16
class Frame(Validatable): SCHEMA = [{ "length": Types.BYTE(), "subnet": Types.BYTE(), "control": Types.OBJECT(Control), "target_address": Types.BYTES(), # TODO max size? "d7anp_frame": Types.OBJECT(D7anpFrame), # TODO assuming foreground frames for now "crc16": Types.BITS( 16 ) # TODO does not work, look into this later {'validator': validate_crc } }] def __init__(self, length, subnet, control, target_address, d7anp_frame, crc16): self.length = length self.subnet = subnet self.control = control self.target_address = target_address self.d7anp_frame = d7anp_frame self.crc16 = crc16 # TODO validate CRC super(Frame, self).__init__() # def validate_crc(self, value, error): # raw_data = [] # raw_data.append(self.length) # raw_data.append(self.subnet) # raw_data.append(self.control) # raw_data.append(self.target_address) # raw_data.append(self.payload) # crc = CRCCCITT().calculate(raw_data) @staticmethod def parse(s): length = s.read("int:8") subnet = s.read("int:8") control = Control.parse(s) payload_length = length - 4 # substract subnet, control, crc if control.id_type == IdType.VID: target_address = map(ord, s.read("bytes:2")) payload_length = payload_length - 2 elif control.id_type == IdType.UID: target_address = map(ord, s.read("bytes:8")) payload_length = payload_length - 8 else: target_address = [] return Frame(length=length, subnet=subnet, control=control, target_address=target_address, d7anp_frame=D7anpFrame.parse(s, payload_length), crc16=s.read("uint:16")) def __iter__(self): yield self.length yield self.subnet for byte in self.control: yield byte for byte in self.target_address: yield byte for byte in self.d7anp_frame: yield byte yield self.crc16