class Data(Validatable): SCHEMA = [{ "offset": Types.OBJECT(Offset), "length": Types.OBJECT(Length), "data": Types.BYTES() }] def __init__(self, data=[], offset=Offset()): self.offset = offset self.data = data self.length = Length(len(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.value def __iter__(self): for byte in self.offset: yield byte for byte in self.length: yield byte for byte in self.data: yield chr(byte) def __str__(self): return "{}, length={}, data={}".format(self.offset, self.length, self.data)
class Action(Validatable): SCHEMA = [{ "op": Types.BITS(6), "operation": Types.OBJECT(Operation), "operand": Types.OBJECT(nullable=True) # there is no Operand base-class }] def __init__(self, operation=NoOperation()): self.operation = operation super(Action, self).__init__() @property def op(self): return self.operation.op @property def operand(self): return self.operation.operand def __str__(self): if isinstance(self.operation, ReturnFileData): # when reading a known system files we output the parsed data if self.operation.systemfile_type != None and self.operation.file_data_parsed != None: return "Received {} content: {}".format( self.operation.systemfile_type.__class__.__name__, self.operation.file_data_parsed) return str(self.operation)
class Action(Validatable): SCHEMA = [{ "op": Types.BITS(6), "operation": Types.OBJECT(Operation), "operand": Types.OBJECT(nullable=True) # there is no Operand base-class }] def __init__(self, operation=NoOperation()): self.operation = operation super(Action, self).__init__() @property def op(self): return self.operation.op @property def operand(self): return self.operation.operand def __str__(self): output = "op={}, operand={}({})".format( type(self.operation).__name__, type(self.operand).__name__, self.operand) return output
class StatusAction(Action): SCHEMA = [{ "status_operand_extension": Types.INTEGER(values=StatusActionOperandExtensions.ALL), "operation": Types.OBJECT(Operation), "operand": Types.OBJECT(nullable=True) # there is no Operand base-class }] def __init__(self, status_operand_extension, operation): self.status_operand_extension = status_operand_extension self.operation = operation super(StatusAction, self).__init__(operation=operation) def __iter__(self): byte = 0 byte |= self.status_operand_extension << 6 byte += self.op yield byte for byte in self.operation: yield byte def __str__(self): return "{}".format(self.operand)
class Configuration(Validatable): SCHEMA = [{ "qos": Types.OBJECT(QoS), "dorm_to": Types.OBJECT(CT), "addressee": Types.OBJECT(Addressee) }] def __init__(self, qos=QoS(), dorm_to=CT(), addressee=Addressee()): self.qos = qos self.dorm_to = dorm_to self.addressee = addressee super(Configuration, self).__init__() def __iter__(self): for byte in self.qos: yield byte for byte in self.dorm_to: yield byte for byte in self.addressee: yield byte def __str__(self): return str(self.as_dict()) @staticmethod def parse(s): qos = QoS.parse(s) dorm_to = CT.parse(s) addressee = Addressee.parse(s) return Configuration(qos=qos, dorm_to=dorm_to, addressee=addressee)
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 IndirectForwardAction(Action): SCHEMA = [{ "overload": Types.BOOLEAN(), "resp": Types.BOOLEAN(), "op": Types.BITS(6), "operation": Types.OBJECT(IndirectForward), "operand": Types.OBJECT(IndirectInterfaceOperand ) # TODO for now only D7 interface is supported }] def __init__(self, overload=False, resp=False, operation=NoOperation()): self.overload = overload self.resp = resp super(IndirectForwardAction, self).__init__(operation) def __iter__(self): byte = 0 if self.overload: byte |= 1 << 7 if self.resp: byte |= 1 << 6 byte += self.op yield byte for byte in self.operation: yield byte
class Frame(Validatable): SCHEMA = [{ "control": Types.OBJECT(Control), "dialog_id": Types.INTEGER(min=0, max=255), "transaction_id": Types.INTEGER(min=0, max=255), "ack_template": Types.OBJECT(nullable=True), # TODO "alp_command": Types.OBJECT(Command) }] def __init__(self, control, dialog_id, transaction_id, ack_template, alp_command): self.control = control self.dialog_id = dialog_id self.transaction_id = transaction_id self.ack_template = ack_template self.alp_command = alp_command super(Frame, self).__init__() def __iter__(self): for byte in self.control: yield byte yield self.dialog_id yield self.transaction_id for byte in self.ack_template: yield byte for byte in self.alp_command: yield byte
class FileHeader(Validatable): SCHEMA = [{ "permissions": Types.OBJECT(FilePermissions), "properties": Types.OBJECT(FileProperties), "alp_command_file_id": Types.BYTE(), "interface_file_id": Types.BYTE(), "file_size": Types.INTEGER(min=0, max=0xFFFFFFFF), "allocated_size": Types.INTEGER(min=0, max=0xFFFFFFFF) }] def __init__(self, permissions, properties, alp_command_file_id, interface_file_id, file_size, allocated_size): self.permissions = permissions self.properties = properties self.alp_command_file_id = alp_command_file_id self.interface_file_id = interface_file_id self.file_size = file_size self.allocated_size = allocated_size Validatable.__init__(self) @staticmethod def parse(s): permissions = FilePermissions.parse(s) properties = FileProperties.parse(s) alp_command_file_id = s.read("uint:8") interface_file_id = s.read("uint:8") file_size = s.read("uint:32") allocated_size = s.read("uint:32") return FileHeader(permissions, properties, alp_command_file_id, interface_file_id, file_size, allocated_size) def __iter__(self): for byte in self.permissions: yield byte for byte in self.properties: yield byte yield self.alp_command_file_id yield self.interface_file_id for byte in bytearray(struct.pack(">I", self.file_size)): yield byte for byte in bytearray(struct.pack(">I", self.allocated_size)): yield byte def __eq__(self, other): if isinstance(other, FileHeader): return self.__dict__ == other.__dict__ return False def __ne__(self, other): return not self.__eq__(other) def __str__(self): return "permissions={}, properties=({}), alp_command_file_id={}, interface_file_id={}, file_size={}, allocated_size={}".format( self.permissions, self.properties, self.alp_command_file_id, self.interface_file_id, self.file_size, self.allocated_size)
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 ChannelID(Validatable): SCHEMA = [{ "channel_header": Types.OBJECT(ChannelHeader), "channel_index": Types.INTEGER(min=0, max=0xFFFF), }] def __init__(self, channel_header, channel_index): self.channel_header = channel_header self.channel_index = channel_index super(ChannelID, self).__init__() def __iter__(self): for byte in self.channel_header: yield byte for byte in bytearray(struct.pack(">H", self.channel_index)): yield byte @staticmethod def parse(s): channel_header = ChannelHeader.parse(s) channel_index = s.read("uint:16") return ChannelID(channel_header=channel_header, channel_index=channel_index) def __str__(self): return "{0}{1:0>3}".format(self.channel_header, self.channel_index) @staticmethod def from_string(s): channel_header = ChannelHeader.from_string(s[0:5]) channel_index = int(s[5:8]) return ChannelID(channel_header=channel_header, channel_index=channel_index)
class Offset(Validatable): SCHEMA = [ { "id" : Types.BYTE(), "offset": Types.OBJECT(Length) } ] def __init__(self, id=0, offset=Length()): self.id = id self.offset = offset super(Offset, self).__init__() @staticmethod def parse(s): id = s.read("uint:8") offset = Length.parse(s) return Offset(id=id, offset=offset) def __iter__(self): yield self.id for byte in self.offset: yield byte def __str__(self): return "file-id={}, offset={}".format(self.id, self.offset)
class FileHeaderOperand(Validatable): SCHEMA = [{ "file_id": Types.BYTE(), "file_header": Types.OBJECT(FileHeader) }] def __init__(self, file_id, file_header): self.file_id = file_id self.file_header = file_header super(FileHeaderOperand, self).__init__() def __iter__(self): yield self.file_id for byte in self.file_header: yield byte @staticmethod def parse(s): file_id = s.read("uint:8") file_header = FileHeader.parse(s) return FileHeaderOperand(file_id=file_id, file_header=file_header) def __str__(self): return "file-id={}, header={}".format(self.file_id, self.file_header)
class IndirectInterfaceOperand(Validatable): SCHEMA = [{ "interface_file_id": Types.INTEGER(min=0x40, max=0xFF), "interface_configuration_overload": Types.OBJECT(Addressee, nullable=True) # TODO assuming D7ASP interface }] def __init__(self, interface_file_id, interface_configuration_overload=None): self.interface_file_id = interface_file_id self.interface_configuration_overload = interface_configuration_overload super(IndirectInterfaceOperand, self).__init__() def __iter__(self): yield self.interface_file_id if self.interface_configuration_overload is not None: for byte in self.interface_configuration_overload: yield byte def __str__(self): return "interface-file-id={}, configuration-overload={}".format( self.interface_file_id, self.interface_configuration_overload)
class AccessProfileFile(File, Validatable): SCHEMA = [{ "access_specifier": Types.INTEGER(min=0, max=14), "access_profile": Types.OBJECT(AccessProfile, nullable=True) }] def __init__(self, access_specifier=0, access_profile=None): self.access_specifier = access_specifier self.access_profile = access_profile Validatable.__init__(self) File.__init__(self, SystemFileIds.ACCESS_PROFILE_0.value + access_specifier, 65) def __iter__(self): for byte in self.access_profile: yield byte @staticmethod def parse(s): return AccessProfileFile( access_specifier=0, access_profile=AccessProfile.parse(s)) # TODO access_specifier? def __str__(self): return "active_specifier={}, access_profile={}".format( self.access_specifier, self.access_profile)
class SubProfile(Validatable): SCHEMA = [{ "subband_bitmap": Types.BYTE(), "scan_automation_period": Types.OBJECT(CT) }] def __init__(self, subband_bitmap=0, scan_automation_period=CT()): self.subband_bitmap = subband_bitmap self.scan_automation_period = scan_automation_period super(SubProfile, self).__init__() @staticmethod def parse(s): subband_bitmap = s.read("uint:8") scan_automation_period = CT.parse(s) return SubProfile(subband_bitmap=subband_bitmap, scan_automation_period=scan_automation_period) def __iter__(self): yield self.subband_bitmap for byte in self.scan_automation_period: yield byte def __str__(self): return pprint.PrettyPrinter().pformat(self.as_dict())
class DataRequest(Validatable): SCHEMA = [{"offset": Types.OBJECT(Offset), "length": Types.OBJECT(Length)}] def __init__(self, length, offset=Offset()): self.offset = offset self.length = Length(length) super(DataRequest, self).__init__() def __iter__(self): for byte in self.offset: yield byte for byte in self.length: yield byte def __str__(self): return "{}, length={}".format(self.offset, self.length)
class DllStatusFile(File, Validatable): SCHEMA = [{ "last_rx_packet_level": Types.INTEGER(min=0, max=0xFF), "last_rx_packet_link_budget": Types.INTEGER(min=0, max=0xFF), "noise_floor": Types.INTEGER(min=0, max=0xFF), "channel_header": Types.OBJECT(ChannelHeader), "channel_index":Types.INTEGER(min=0, max=0xFFFF), "scan_timeout_ratio": Types.INTEGER(min=0, max=0xFFFF), "scan_count": Types.INTEGER(min=0, max=0xFFFFFFFF), "scan_timeout_count": Types.INTEGER(min=0, max=0xFFFFFFFF) }] def __init__(self, last_rx_packet_level=0, last_rx_packet_link_budget=0, noise_floor=0, channel_header=ChannelHeader(channel_coding=ChannelCoding.FEC_PN9, channel_band=ChannelBand.BAND_868, channel_class=ChannelClass.LO_RATE), channel_index=0, scan_timeout_ratio=0, scan_count=0, scan_timeout_count=0): self.last_rx_packet_level=last_rx_packet_level self.last_rx_packet_link_budget=last_rx_packet_link_budget self.noise_floor=noise_floor self.channel_header=channel_header self.channel_index=channel_index self.scan_timeout_ratio=scan_timeout_ratio self.scan_count=scan_count self.scan_timeout_count=scan_timeout_count File.__init__(self, SystemFileIds.DLL_STATUS.value, 16) Validatable.__init__(self) @staticmethod def parse(s): last_rx_packet_level = s.read("uint:8") last_rx_packet_link_budget = s.read("uint:8") noise_floor = s.read("uint:8") channel_header = ChannelHeader.parse(s) channel_index = s.read("uint:16") scan_timeout_ratio = s.read("uint:16") scan_count = s.read("uint:32") scan_timeout_count = s.read("uint:32") return DllStatusFile(last_rx_packet_level=last_rx_packet_level, last_rx_packet_link_budget=last_rx_packet_link_budget, noise_floor=noise_floor, channel_header=channel_header, channel_index=channel_index, scan_timeout_ratio=scan_timeout_ratio, scan_count=scan_count, scan_timeout_count=scan_timeout_count) def __iter__(self): yield self.last_rx_packet_level yield self.last_rx_packet_link_budget yield self.noise_floor for byte in self.channel_header: yield byte for byte in bytearray(struct.pack(">H", self.channel_index)): yield byte for byte in bytearray(struct.pack(">H", self.scan_timeout_ratio)): yield byte for byte in bytearray(struct.pack(">I", self.scan_count)): yield byte for byte in bytearray(struct.pack(">I", self.scan_timeout_count)): yield byte def __str__(self): return "last_rx_packet_level={}, last_rx_packet_link_budget={}, noise_floor={}, channel={}{}, scan_timeout_ratio={}, scan_count={}, scan_timeout_count={}".format(self.last_rx_packet_level, self.last_rx_packet_link_budget, self.noise_floor, self.channel_header, self.channel_index, self.scan_timeout_ratio, self.scan_count, self.scan_timeout_count)
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 EngineeringModeFile(File, Validatable): SCHEMA = [{ "mode": Types.ENUM(EngineeringModeMode), "flags": Types.INTEGER(min=0, max=255), "timeout": Types.INTEGER(min=0, max=255), "channel_id": Types.OBJECT(ChannelID), "eirp": Types.INTEGER(min=-128, max=127) }] def __init__(self, mode=EngineeringModeMode.ENGINEERING_MODE_MODE_OFF, flags=0, timeout=0, channel_id=ChannelID(channel_header=ChannelHeader( ChannelCoding.PN9, ChannelClass.LO_RATE, ChannelBand.BAND_868), channel_index=0), eirp=0): self.mode = mode self.flags = flags self.timeout = timeout self.channel_id = channel_id self.eirp = eirp File.__init__(self, SystemFileIds.ENGINEERING_MODE, 9) Validatable.__init__(self) @staticmethod def parse(s): mode = EngineeringModeMode(int(s.read("uint:8"))) flags = s.read("uint:8") timeout = s.read("uint:8") channel_id = ChannelID.parse(s) eirp = s.read("int:8") return EngineeringModeFile(mode=mode, flags=flags, timeout=timeout, channel_id=channel_id, eirp=eirp) def __iter__(self): yield int(self.mode.value) yield self.flags yield self.timeout for byte in self.channel_id: yield byte for byte in bytearray(struct.pack(">b", self.eirp)): yield byte yield 0 yield 0 def __str__(self): return "mode={}, flags={}, timeout={}, channel_id={{{}}}, eirp={}".format( self.mode, hex(self.flags), self.timeout, self.channel_id, self.eirp)
class AccessProfile(Validatable): NUMBER_OF_SUB_PROFILES = 4 MAX_NUMBER_OF_SUB_BANDS = 8 # TODO update to D7AP v1.1 SCHEMA = [{ "channel_header": Types.OBJECT(ChannelHeader), "sub_profiles": Types.LIST(SubProfile, minlength=4, maxlength=4), "sub_bands": Types.LIST(SubBand, minlength=0, maxlength=8) }] def __init__(self, channel_header, sub_profiles, sub_bands): self.channel_header = channel_header self.sub_profiles = sub_profiles self.sub_bands = sub_bands super(AccessProfile, self).__init__() @staticmethod def parse(s): channel_header = ChannelHeader.parse(s) sub_profiles = [] for _ in range(AccessProfile.NUMBER_OF_SUB_PROFILES): sub_profiles.append(SubProfile.parse(s)) sub_bands = [] for _ in range(AccessProfile.MAX_NUMBER_OF_SUB_BANDS): sub_bands.append(SubBand.parse(s)) return AccessProfile(channel_header=channel_header, sub_bands=sub_bands, sub_profiles=sub_profiles) def __iter__(self): for byte in self.channel_header: yield byte for sp in self.sub_profiles: for byte in sp: yield byte for sb in self.sub_bands: for byte in sb: yield byte def __str__(self): subprofiles_string = "" for subprofile in self.sub_profiles: subprofiles_string = subprofiles_string + str(subprofile) subbands_string = "" for subband in self.sub_bands: subbands_string = subbands_string + str(subband) return "channel_header={}, sub_profiles={}, sub_bands={}".format( self.channel_header, subprofiles_string, subbands_string)
class ForwardAction(Action): SCHEMA = [{ "resp" : Types.BOOLEAN(), "op" : Types.BITS(6), "operation": Types.OBJECT(Operation), "operand" : Types.OBJECT(InterfaceConfiguration) # TODO for now only D7 interface is supported }] def __init__(self, resp=False, operation=NoOperation()): self.resp = resp super(ForwardAction, self).__init__(operation) def __iter__(self): byte = 0 if self.group: byte |= 1 << 7 if self.resp: byte |= 1 << 6 byte += self.op yield byte for byte in self.operation: yield byte
class TagRequestAction(Action): SCHEMA = [{ "respond_when_completed": Types.BOOLEAN(), "op": Types.BITS(6), "operation": Types.OBJECT(Operation), "operand": Types.OBJECT(nullable=True) # there is no Operand base-class }] def __init__(self, respond_when_completed=True, operation=NoOperation()): self.respond_when_completed = respond_when_completed super(TagRequestAction, self).__init__(operation) def __iter__(self): byte = 0 if self.respond_when_completed: byte |= 1 << 7 byte += self.op yield byte for byte in self.operation: yield byte
class BackgroundFrame(Validatable): SCHEMA = [{ "subnet": Types.BYTE(), "control": Types.OBJECT(BackgroundFrameControl), "payload": Types.BITS(16), "crc16": Types.BITS( 16 ) # TODO does not work, look into this later {'validator': validate_crc } }] def __init__(self, subnet, control, payload, crc16): self.subnet = subnet self.control = control self.payload = payload self.crc16 = crc16 # TODO validate CRC super(BackgroundFrame, 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): subnet = s.read("int:8") control = BackgroundFrameControl.parse(s) payload = s.read("uint:16") crc = s.read("uint:16") return BackgroundFrame(subnet=subnet, control=control, payload=payload, crc16=crc) def __iter__(self): yield self.subnet for byte in self.control: yield byte for byte in self.payload: yield byte yield self.crc16 def __str__(self): return pprint.PrettyPrinter().pformat(self.as_dict())
class TagResponseAction(Action): SCHEMA = [{ "eop": Types.BOOLEAN(), "error": Types.BOOLEAN(), "op": Types.BITS(6), "operation": Types.OBJECT(Operation), "operand": Types.OBJECT(nullable=True) # there is no Operand base-class }] def __init__(self, eop, error, operation=NoOperation()): self.eop = eop self.error = error super(TagResponseAction, self).__init__(operation) def __iter__(self): byte = 0 if self.eop: byte |= 1 << 7 if self.error: byte |= 1 << 6 byte += self.op yield byte for byte in self.operation: yield byte
class RegularAction(Action): SCHEMA = [{ "group": Types.BOOLEAN(), "resp": Types.BOOLEAN(), "op": Types.BITS(6), "operation": Types.OBJECT(Operation), "operand": Types.OBJECT(nullable=True) # there is no Operand base-class }] def __init__(self, group=False, resp=False, operation=NoOperation()): self.group = group self.resp = resp super(RegularAction, self).__init__(operation) def __iter__(self): byte = 0 if self.group: byte |= 1 << 7 if self.resp: byte |= 1 << 6 byte += self.op yield byte for byte in self.operation: yield byte
class FileHeaderOperand(Validatable): SCHEMA = [{ "file_id": Types.BYTE(), "file_header": Types.OBJECT(FileHeader) }] def __init__(self, file_id, file_header): self.file_id = file_id self.file_header = file_header super(FileHeaderOperand, self).__init__() def __iter__(self): yield self.file_id for byte in self.file_header: yield byte def __str__(self): return "file-id={}, header={}".format(self.file_id, self.file_header)
class InterfaceConfiguration(Validatable): SCHEMA = [{ "interface_id": Types.BYTE(), "interface_configuration": Types.OBJECT(Configuration) }] def __init__(self, interface_id, interface_configuration): self.interface_id = interface_id self.interface_configuration = interface_configuration super(InterfaceConfiguration, self).__init__() def __iter__(self): yield self.interface_id for byte in self.interface_configuration: yield byte def __str__(self): return "interface-id={}, status={}".format( self.interface_id, self.interface_configuration)
class InterfaceStatusOperand(Validatable): SCHEMA = [{ "interface_id": Types.BYTE(), "interface_status": Types.OBJECT(Status, nullable=True) }] def __init__(self, interface_id, interface_status): self.interface_id = interface_id self.interface_status = interface_status super(InterfaceStatusOperand, self).__init__() def __iter__(self): yield self.interface_id for byte in self.interface_status: yield byte def __str__(self): return "interface-id={}, status={}".format(self.interface_id, self.interface_status)