Esempio n. 1
0
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)
Esempio n. 2
0
class PhyStatusFile(File, Validatable):
    SCHEMA = [{
        "up_time":
        Types.INTEGER(min=0, max=0xFFFFFFFF),
        "rx_time":
        Types.INTEGER(min=0, max=0xFFFFFFFF),
        "tx_time":
        Types.INTEGER(min=0, max=0xFFFFFFFF),
        "tx_duty_cycle":
        Types.INTEGER(min=0, max=1000),
        "channel_status_list_length":
        Types.INTEGER(min=0, max=0xFF),
        "channel_status_identifier":
        Types.LIST(ChannelStatusIdentifier, minlength=0, maxlength=0xFF),
        "channel_noise_floor":
        Types.LIST(minlength=0, maxlength=0xFF)
    }]

    def __init__(self,
                 up_time=0,
                 rx_time=0,
                 tx_time=0,
                 tx_duty_cycle=0,
                 channel_status_list_length=0,
                 channel_status_identifier=[],
                 channel_noise_floor=[]):
        self.up_time = up_time
        self.rx_time = rx_time
        self.tx_time = tx_time
        self.tx_duty_cycle = tx_duty_cycle
        self.channel_status_list_length = channel_status_list_length

        self.channel_status_identifier = channel_status_identifier
        if len(channel_status_identifier) != channel_status_list_length:
            self.channel_status_identifier.extend(
                [ChannelStatusIdentifier()] *
                (channel_status_list_length - len(channel_status_identifier)))

        self.channel_noise_floor = channel_noise_floor
        if len(channel_noise_floor) != channel_status_list_length:
            self.channel_noise_floor.extend(
                [0] * (channel_status_list_length - len(channel_noise_floor)))

        File.__init__(self, SystemFileIds.PHY_STATUS.value,
                      15 + (3 * 10))  # allocate enough space for 20 channels
        Validatable.__init__(self)

    @staticmethod
    def parse(s):
        up_time = s.read("uint:32")
        rx_time = s.read("uint:32")
        tx_time = s.read("uint:32")
        tx_duty_cycle = s.read("uint:16")
        channel_status_list_length = s.read("uint:8")
        channel_status_identifier = []
        channel_noise_floor = []
        for counter in range(channel_status_list_length):
            channel_status_identifier.append(
                ChannelStatusIdentifier().parse(s))
            channel_noise_floor.append(s.read("uint:8"))

        return PhyStatusFile(
            up_time=up_time,
            rx_time=rx_time,
            tx_time=tx_time,
            tx_duty_cycle=tx_duty_cycle,
            channel_status_list_length=channel_status_list_length,
            channel_status_identifier=channel_status_identifier,
            channel_noise_floor=channel_noise_floor)

    def __iter__(self):
        for byte in bytearray(struct.pack(">I", self.up_time)):
            yield byte
        for byte in bytearray(struct.pack(">I", self.rx_time)):
            yield byte
        for byte in bytearray(struct.pack(">I", self.tx_time)):
            yield byte
        for byte in bytearray(struct.pack(">H", self.tx_duty_cycle)):
            yield byte
        yield self.channel_status_list_length
        for counter in range(self.channel_status_list_length):
            for byte in self.channel_status_identifier[counter]:
                yield byte
            yield self.channel_noise_floor[counter]

    def __str__(self):
        channel_status = ""
        for counter in range(self.channel_status_list_length):
            channel_status = channel_status + "identifier={}, noise_floor={}; ".format(
                str(self.channel_status_identifier[counter]),
                self.channel_noise_floor[counter])
        channel_status = "[{}]".format(channel_status[:-2])

        return "up_time={}, rx_time={}, tx_time={}, tx_duty_cycle={}, channel_status_list_length={}, list={}".format(
            self.up_time, self.rx_time, self.tx_time, self.tx_duty_cycle,
            self.channel_status_list_length, channel_status)
Esempio n. 3
0
class Command(Validatable):

    SCHEMA = [{
        "actions": Types.LIST(Action),
        "interface_status": Types.OBJECT(
            StatusAction,
            nullable=True)  # can be null for example when parsing DLL frames
    }]

    def __init__(self,
                 actions=[],
                 generate_tag_request_action=True,
                 tag_id=None,
                 send_tag_response_when_completed=True):
        self.actions = []
        self.interface_status = None
        self.generate_tag_request_action = generate_tag_request_action
        self.tag_id = tag_id
        self.send_tag_response_when_completed = send_tag_response_when_completed
        self.execution_completed = False

        for action in actions:
            if type(
                    action
            ) == StatusAction and action.status_operand_extension == StatusActionOperandExtensions.INTERFACE_STATUS:
                if self.interface_status != None:
                    raise ParseError(
                        "An ALP command can contain one and only one Interface Status action"
                    )
                self.interface_status = action
            elif type(action) == TagRequestAction:
                if self.tag_id != None:
                    raise ParseError(
                        "An ALP command can contain one and only one Tag Request Action"
                    )
                self.tag_id = action.operand.tag_id
                self.send_tag_response_when_completed = action.respond_when_completed
                # we don't add this to self.actions but prepend it on serializing
            elif type(action) == TagResponseAction:
                if self.tag_id != None:
                    raise ParseError(
                        "An ALP command can contain one and only one Tag Response Action"
                    )
                self.tag_id = action.operand.tag_id
                self.completed_with_error = action.error  # TODO distinguish between commands and responses?
                self.execution_completed = action.eop
            else:
                self.actions.append(action)

        if self.generate_tag_request_action and self.tag_id == None:
            self.tag_id = random.randint(0, 255)

        super(Command, self).__init__()

    def add_action(self, action):
        self.actions.append(action)

    def add_forward_action(self,
                           interface_type=InterfaceType.HOST,
                           interface_configuration=None):
        if interface_configuration is not None and interface_type == InterfaceType.HOST:
            raise ValueError(
                "interface_configuration is not supported for interface_type HOST"
            )

        if interface_type == InterfaceType.D7ASP:
            if interface_configuration is None:
                interface_configuration = Configuration()

            self.actions.append(
                RegularAction(operation=Forward(operand=InterfaceConfiguration(
                    interface_id=InterfaceType.D7ASP,
                    interface_configuration=interface_configuration))))

    @staticmethod
    def create_with_read_file_action_system_file(
            file,
            interface_type=InterfaceType.HOST,
            interface_configuration=None):
        # default to host interface, when D7ASP interface is used prepend with Forward action
        cmd = Command()
        cmd.add_forward_action(interface_type, interface_configuration)
        cmd.add_action(
            RegularAction(operation=ReadFileData(operand=DataRequest(
                offset=Offset(id=file.id, offset=0),  # TODO offset size
                length=file.length))))

        return cmd

    @staticmethod
    def create_with_read_file_action(file_id,
                                     length,
                                     offset=0,
                                     interface_type=InterfaceType.HOST,
                                     interface_configuration=None):
        # default to host interface, when D7ASP interface is used prepend with Forward action
        cmd = Command()
        cmd.add_forward_action(interface_type, interface_configuration)
        cmd.add_action(
            RegularAction(operation=ReadFileData(operand=DataRequest(
                offset=Offset(id=file_id, offset=offset),  # TODO offset size
                length=length))))

        return cmd

    @staticmethod
    def create_with_write_file_action(file_id,
                                      data,
                                      offset=0,
                                      interface_type=InterfaceType.HOST,
                                      interface_configuration=None):
        # default to host interface, when D7ASP interface is used prepend with Forward action
        cmd = Command()
        cmd.add_forward_action(interface_type, interface_configuration)
        cmd.add_action(
            RegularAction(operation=WriteFileData(operand=Data(
                offset=Offset(id=file_id, offset=offset),  # TODO offset size
                data=data))))

        return cmd

    @staticmethod
    def create_with_write_file_action_system_file(
            file,
            interface_type=InterfaceType.HOST,
            interface_configuration=None):
        # default to host interface, when D7ASP interface is used prepend with Forward action
        cmd = Command()
        cmd.add_forward_action(interface_type, interface_configuration)
        cmd.add_action(
            RegularAction(operation=WriteFileData(operand=Data(
                offset=Offset(id=file.id, offset=0),  # TODO offset size
                data=list(file)))))

        return cmd

    @staticmethod
    def create_with_return_file_data_action(file_id,
                                            data,
                                            interface_type=InterfaceType.HOST,
                                            interface_configuration=None):
        # default to host interface, when D7ASP interface is used prepend with Forward action
        cmd = Command()
        cmd.add_forward_action(interface_type, interface_configuration)
        cmd.add_action(
            RegularAction(operation=ReturnFileData(
                operand=Data(data=data, offset=Offset(id=file_id)))))

        return cmd

    def __iter__(self):
        if self.generate_tag_request_action:
            tag_request_action = TagRequestAction(
                respond_when_completed=self.send_tag_response_when_completed,
                operation=TagRequest(operand=TagId(tag_id=self.tag_id)))
            for byte in tag_request_action:
                yield byte

        if self.interface_status is not None:
            for byte in self.interface_status:
                yield byte

        for action in self.actions:
            for byte in action:
                yield byte

    def describe_actions(self):
        description = ""
        for action in self.actions:
            description = description + "{}, ".format(action)

        return description.strip(", ")

    def get_d7asp_interface_status(self):
        if self.interface_status is None or self.interface_status.operand.interface_id != 0xD7:
            return None

        return self.interface_status.operation.operand.interface_status

    def __str__(self):
        output = "Command with tag {} ".format(self.tag_id)
        if (self.execution_completed):
            status = "completed"
            if (self.completed_with_error):
                status += ", with error"
            else:
                status += ", without error"
        else:
            status = "executing"

        output += "({})".format(status)

        if (len(self.actions) > 0):
            output += "\n\tactions:\n"
            for action in self.actions:
                output += "\t\taction: {}\n".format(action)

        if self.interface_status is not None:
            output += "\tinterface status: {}\n".format(self.interface_status)
        return output