Пример #1
0
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())
Пример #2
0
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)
Пример #3
0
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
Пример #4
0
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
Пример #5
0
class Length(Validatable):

    SCHEMA = [{
        "length": Types.BITS(2),
        "value": Types.INTEGER(min=0, max=0x3FFFFFFF)
    }]

    def __init__(self, value=0):
        self.value = value
        super(Length, self).__init__()

    @staticmethod
    def parse(s):
        size = s.read("uint:2")  # + 1 = already read
        value = s.read("uint:" + str(6 + (size * 8)))
        return Length(value=value)

    def __iter__(self):
        byte = 0
        size = 1
        if self.value > 0x3F:
            size = 2
        if self.value > 0x3FFF:
            size = 3
        if self.value > 0x3FFFFF:
            size = 4

        byte += (size - 1) << 6

        if size == 1:
            byte += self.value
            yield byte
        else:
            length_bytes = bytearray(struct.pack(">I", self.value))
            if size == 2: length_bytes = length_bytes[2:]
            elif size == 3: length_bytes = length_bytes[1:]

            byte += length_bytes[0]
            yield byte
            for byte in length_bytes[1:]:
                yield byte

    def __str__(self):
        return str(self.value)

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.value == other.value
        elif isinstance(other, int):
            return self.value == other
        else:
            return False

    def __ne__(self, other):
        return not self.__eq__(other)
Пример #6
0
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 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
Пример #8
0
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
Пример #9
0
class SecurityKeyFile(File, Validatable):

  SCHEMA = [{
    "key": Types.BITS(length=128)
  }]

  def __init__(self, key=0):
    self.key = key
    Validatable.__init__(self)
    File.__init__(self, SystemFileIds.NWL_SECURITY_KEY.value, 16)

  @staticmethod
  def parse(s):
    key = s.read("bytes:16")
    return SecurityKeyFile(key)

  def __iter__(self):
    for byte in [(self.key & (0xff << pos * 8)) >> pos * 8 for pos in range(16)]:
      yield byte

  def __str__(self):
    return "key={}".format(self.key)
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
Пример #11
0
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
Пример #12
0
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
Пример #13
0
class Addressee(Validatable):

    # addressee ID length
    ID_LENGTH_BROADCAST = 0
    ID_LENGTH_VID = 2
    ID_LENGTH_UID = 8

    SCHEMA = [
        {
            # broadcast
            "id_type": Types.INTEGER([IdType.BCAST]),
            "access_class": Types.BITS(4),
            "id_length": Types.INTEGER([0]),
            "id": Types.INTEGER([None])
        },
        {
            # virtual
            "id_type": Types.INTEGER([IdType.VID]),
            "access_class": Types.BITS(4),
            "id_length": Types.INTEGER([2]),
            "id": Types.INTEGER(min=0, max=0xFFFF)
        },
        {
            # unicast
            "id_type": Types.INTEGER([IdType.UID]),
            "access_class": Types.BITS(4),
            "id_length": Types.INTEGER([8]),
            "id": Types.INTEGER(min=0, max=0xFFFFFFFFFFFFFFFF)
        }
    ]

    #  SCHEMA = [
    #    {
    #      "id_type"   : Types.INTEGER(IdType.ALL),
    #      "cl"        : Types.BITS(4),
    #      "id_length" : Types.INTEGER([0, 2, 8]),
    #      "id"        : Types.INTEGER(min=0, max=0xFFFFFFFFFFFFFFFF)
    #    }
    #  ]

    def __init__(self, access_class=0, id_type=IdType.BCAST, id=None):
        self.id_type = id_type
        self.access_class = access_class
        self.id = id
        super(Addressee, self).__init__()

    @property
    def id_length(self):
        return Addressee.length_for(id_type=self.id_type)

    @classmethod
    def length_for(self, id_type):
        if id_type == IdType.BCAST: return Addressee.ID_LENGTH_BROADCAST
        if id_type == IdType.VID: return Addressee.ID_LENGTH_VID
        if id_type == IdType.UID: return Addressee.ID_LENGTH_UID

    @staticmethod
    def parse(s):
        _ = s.read("pad:2")
        id_type = s.read("uint:2")
        cl = s.read("uint:4")
        l = Addressee.length_for(id_type)
        id = s.read("uint:" + str(l * 8)) if l > 0 else None
        return Addressee(id_type=id_type, access_class=cl, id=id)

    def __iter__(self):
        byte = 0
        # pad 2 << 7 << 6
        byte |= self.id_type << 4
        byte += self.access_class
        yield byte

        if self.id_length > 0:
            id = bytearray(struct.pack(">Q", self.id))[8 - self.id_length:]
            for byte in id:
                yield byte

    def __str__(self):
        return "ac={}, id_type={}, id={}".format(self.access_class,
                                                 self.id_type, hex(self.id))