Exemple #1
0
    def send_command(self, command, args):
        command_template = self.dictionaries.command_id[command]
        cmd_data = CmdData(tuple(args), command_template)
        self.histories.commands.data_callback(cmd_data)
        for hist in self.coders.command_subscribers:
            hist.data_callback(cmd_data)

        ev_temp = self.dictionaries.event_name["CommandReceived"]
        event = EventData((U32Type(cmd_data.get_id()), ),
                          self.t0 + time.time(), ev_temp)
        self.enqueue_event(event)

        ev_temp = self.dictionaries.event_name["HistorySizeUpdate"]
        evr_size = U32Type(len(self.histories.events.retrieve()))
        cmd_size = U32Type(len(self.histories.commands.retrieve()))
        ch_size = U32Type(len(self.histories.channels.retrieve()))
        event = EventData((evr_size, cmd_size, ch_size), self.t0 + time.time(),
                          ev_temp)
        self.enqueue_event(event)

        self.command_count += 1
        ch_temp = self.dictionaries.channel_name["CommandCounter"]
        update = ChData(U32Type(self.command_count), self.t0 + time.time(),
                        ch_temp)
        self.enqueue_telemetry(update)
Exemple #2
0
    def encode_api(self, data):
        """
        Encodes the given CmdData object as binary data and returns the result.

        Args:
            data: CmdData object to encode

        Returns:
            Encoded version of the data argument as binary data
        """
        assert isinstance(data, CmdData), "Encoder handling incorrect type"
        cmd_temp = data.get_template()

        desc = U32Type(0x5A5A5A5A).serialize()

        descriptor = U32Type(
            DataDescType["FW_PACKET_COMMAND"].value).serialize()

        op_code = U32Type(cmd_temp.get_op_code()).serialize()

        arg_data = b""
        for arg in data.get_args():
            arg_data += arg.serialize()

        length_val = len(descriptor) + len(op_code) + len(arg_data)
        self.len_obj.val = length_val
        length = self.len_obj.serialize()

        binary_data = desc + length + descriptor + op_code + arg_data

        return binary_data
Exemple #3
0
    def encode_api(self, data):
        """
        Encodes specific file packets. This will allow the data to be sent out.

        :param data: FilePacket type to send.
        :return: encoded bytes data
        """
        out_data = struct.pack(">BI", int(data.packetType.value), data.seqID)
        # Packet Type determines the variables following the seqID
        if data.packetType == FilePacketType.START:
            file_src_enc = data.sourcePath.encode(DATA_ENCODING)
            file_dst_enc = data.destPath.encode(DATA_ENCODING)
            out_data += struct.pack(">IB", data.size, len(file_src_enc))
            out_data += file_src_enc
            out_data += struct.pack(">B", len(file_dst_enc))
            out_data += file_dst_enc
        elif data.packetType == FilePacketType.DATA:
            out_data += struct.pack(">IH", data.offset, data.length)
            out_data += data.dataVar
        elif data.packetType == FilePacketType.END:
            out_data += struct.pack(">I", data.hashValue)
        elif data.packetType != FilePacketType.CANCEL:
            raise Exception(
                "Invalid packet type found while encoding: {}".format(data.packetType)
            )
        descriptor = U32Type(DataDescType["FW_PACKET_FILE"].value).serialize()
        length_obj = self.config.get_type("msg_len")
        length_obj.val = len(descriptor) + len(out_data)
        header = U32Type(0x5A5A5A5A).serialize() + length_obj.serialize() + descriptor
        return header + out_data
Exemple #4
0
 def __command(cmd_obj):
     command = U32Type(0).serialize(
     )  # serialize combuffer type enum: FW_PACKET_COMMAND
     command += U32Type(
         cmd_obj.getOpCode()).serialize()  # serialize opcode
     # Command arguments
     for arg in cmd_obj.getArgs():
         command += arg[2].serialize()
     return command
Exemple #5
0
 def __time_tag(cmd_obj):
     """
     TODO: support a timebase in the cmd obj? This is mission specific, so it is tough to handle. For now
     I am hardcoding this to 2 which is TB_NONE
     """
     # return TimeType(timeBase=2, seconds=cmd_obj.getSeconds(), useconds=cmd_obj.getUseconds()).serialize()
     # TKC - new command time format
     return (U32Type(cmd_obj.getSeconds()).serialize() +
             U32Type(cmd_obj.getUseconds()).serialize())
Exemple #6
0
def test_pkt_encoder():
    """
    Tests the encoding of the packet encoder
    """
    config = ConfigManager()
    config.set("types", "msg_len", "U16")

    enc = PktEncoder()
    enc_config = PktEncoder(config)

    ch_temp_1 = ChTemplate(101, "test_ch", "test_comp", U32Type())
    ch_temp_2 = ChTemplate(102, "test_ch2", "test_comp2", U8Type())
    ch_temp_3 = ChTemplate(103, "test_ch3", "test_comp3", U16Type())

    pkt_temp = PktTemplate(64, "test_pkt", [ch_temp_1, ch_temp_2, ch_temp_3])

    time_obj = TimeType(2, 0, 1533758629, 123456)

    ch_obj_1 = ChData(U32Type(1356), time_obj, ch_temp_1)
    ch_obj_2 = ChData(U8Type(143), time_obj, ch_temp_2)
    ch_obj_3 = ChData(U16Type(1509), time_obj, ch_temp_3)

    pkt_obj = PktData([ch_obj_1, ch_obj_2, ch_obj_3], time_obj, pkt_temp)

    desc_bin = b"\x00\x00\x00\x04"
    id_bin = b"\x00\x40"
    time_bin = b"\x00\x02\x00\x5b\x6b\x4c\xa5\x00\x01\xe2\x40"
    ch_bin = b"\x00\x00\x05\x4c\x8F\x05\xe5"
    long_len_bin = b"\x00\x00\x00\x18"
    short_len_bin = b"\x00\x18"

    reg_expected = long_len_bin + desc_bin + id_bin + time_bin + ch_bin
    config_expected = short_len_bin + desc_bin + id_bin + time_bin + ch_bin

    reg_output = enc.encode_api(pkt_obj)

    assert (reg_output == reg_expected
            ), "FAIL: expected regular output to be %s, but found %s" % (
                list(reg_expected),
                list(reg_output),
            )

    config_output = enc_config.encode_api(pkt_obj)

    assert (config_output == config_expected
            ), "FAIL: expected configured output to be %s, but found %s" % (
                list(config_expected),
                list(config_output),
            )
Exemple #7
0
    def serialize(self):
        """
        Serializes command arguments
        """
        ## first, serialize opcode
        opcode = U32Type(self.__opcode)
        ser_data = opcode.serialize()

        ## then, serialize arguments
        for (arg_name, arg_desc, arg_type) in self.__arguments:
            ser_data += arg_type.serialize()
        return ser_data
Exemple #8
0
    def get_handshake(packet: bytes) -> bytes:
        """Gets a handshake raw frame from the last packet

        Creates a handshake raw-frame by repeating the contents of the last packet with a handshake descriptor at the
        front.

        Args:
            packet: packet to repeat back out as handshake

        Returns:
            handshake packet
        """
        return U32Type(
            DataDescType["FW_PACKET_HAND"].value).serialize() + packet
Exemple #9
0
    def write(self, seq_cmds_list):
        """
        Write out each command record
        """
        num_records = len(seq_cmds_list)
        sequence = b""
        for cmd in seq_cmds_list:
            sequence += self.__binaryCmdRecord(cmd)
        size = len(sequence)
        if self.__timebase == 0xFFFF:
            tb_txt = b"ANY"
        else:
            tb_txt = bytes(self.__timebase)

        print("Sequence is %d bytes with timebase %s" % (size, tb_txt))

        header = b""
        header += U32Type(
            size +
            4).serialize()  # Write out size of the sequence file in bytes here
        header += U32Type(num_records).serialize()  # Write number of records
        header += U16Type(self.__timebase).serialize()  # Write time base
        header += U8Type(0xFF).serialize()  # write time context
        sequence = header + sequence  # Write the list of command records here
        # compute CRC. Ported from Utils/Hassh/libcrc/libcrc.h (update_crc_32)
        crc = self.computeCrc(sequence)

        print("CRC: %d (0x%04X)" % (crc, crc))
        try:
            sequence += U32Type(crc).serialize()
        except TypeMismatchException as typeErr:
            print("Exception: %s" % typeErr.getMsg())
            raise

        # Write the list of command records here
        self.__fd.write(sequence)
Exemple #10
0
def test_serializable_type():
    """
    Tests the SerializableType serialization and deserialization
    """
    u32Mem = U32Type(1000000)
    stringMem = StringType("something to say")
    members = {"MEMB1": 0, "MEMB2": 6, "MEMB3": 9}
    enumMem = EnumType("SomeEnum", members, "MEMB3")
    memList = [
        ("mem1", u32Mem, ">i"),
        ("mem2", stringMem, ">H"),
        ("mem3", enumMem, ">i"),
    ]
    serType1 = SerializableType("ASerType", memList)
    buff = serType1.serialize()
    serType2 = SerializableType("ASerType", memList)
    serType2.deserialize(buff, 0)
    check_cloned_member_list(serType1.mem_list, serType2.mem_list)

    assert serType1.val == serType2.val

    i32Mem = I32Type(-1000000)
    stringMem = StringType("something else to say")
    members = {"MEMB1": 4, "MEMB2": 2, "MEMB3": 0}
    enumMem = EnumType("SomeEnum", members, "MEMB3")
    memList = [
        ("mem1", i32Mem, ">i"),
        ("mem2", stringMem, ">H"),
        ("mem3", enumMem, ">i"),
    ]
    serType1 = SerializableType("ASerType", memList)
    buff = serType1.serialize()
    serType2 = SerializableType("ASerType", memList)
    serType2.deserialize(buff, 0)
    check_cloned_member_list(serType1.mem_list, serType2.mem_list)

    value_dict = {"mem1": 3, "mem2": "abc 123", "mem3": "MEMB1"}
    serType1.val = value_dict
    assert serType1.val == value_dict
    mem_list = serType1.mem_list
    memList = [(a, b, c, None) for a, b, c in memList]
    check_cloned_member_list(mem_list, memList)
Exemple #11
0
    def get_type(self, name):
        """
        Retrieve a type from the config file for parsing

        It is assumed the setting is in the types section

        Args:
            name (string): Name of the type to retrieve

        Returns:
            If the name is valid, returns an object of a type derived from
            TypeBase. Otherwise, raises ConfigBadTypeException
        """
        type_str = self.get("types", name)

        if type_str == "U8":
            return U8Type()
        elif type_str == "U16":
            return U16Type()
        elif type_str == "U32":
            return U32Type()
        elif type_str == "u64":
            return U64Type()
        elif type_str == "I8":
            return I8Type()
        elif type_str == "I16":
            return I16Type()
        elif type_str == "I32":
            return I32Type()
        elif type_str == "I64":
            return I64Type()
        elif type_str == "F32":
            return F32Type()
        elif type_str == "F64":
            return F64Type()
        else:
            # These are types for parsing, so they need to be number types
            # Other types can be added later
            raise ConfigBadTypeException(name, type_str)
Exemple #12
0
    def decode_api(self, data):
        """
        Decodes the given data and returns the result.

        This function allows for non-registered code to call the same decoding
        code as is used to parse data passed to the data_callback function.

        Args:
            data: Binary telemetry channel data to decode

        Returns:
            Parsed version of the channel telemetry data in the form of a
            ChData object or None if the data is not decodable
        """
        ptr = 0

        # Decode Ch ID here...
        id_obj = U32Type()
        id_obj.deserialize(data, ptr)
        ptr += id_obj.getSize()
        ch_id = id_obj.val

        # Decode time...
        ch_time = TimeType()
        ch_time.deserialize(data, ptr)
        ptr += ch_time.getSize()

        if ch_id in self.__dict:
            # Retrieve the template instance for this channel
            ch_temp = self.__dict[ch_id]

            val_obj = self.decode_ch_val(data, ptr, ch_temp)

            return ChData(val_obj, ch_time, ch_temp)
        else:
            print("Channel decode error: id %d not in dictionary" % ch_id)
            return None
Exemple #13
0
                                             len(values))

        # Set the new arguments by converting each value to an type:
        new_arg_list = list()
        for value, (arg_name, arg_desc,
                    arg_value) in zip(values, self.__arguments):
            new_value = copy.deepcopy(arg_value)
            new_value.val = value
            new_arg_list.append((arg_name, arg_desc, new_value))
        self.__arguments = new_arg_list


if __name__ == "__main__":

    arglist = [
        ("arg1", "some test argument", U32Type(0)),
        ("arg2", "some test argument2", F32Type(0.0)),
    ]

    try:
        testCommand = Command("SomeComponent", "TEST_CMD", 0x123,
                              "Test Command", arglist)
    except TypeException as e:
        print("Exception: %s" % e.getMsg())
    t = U32Type(3)
    t2 = F32Type(123.456)
    try:
        testCommand.setArg("arg1", t)
        testCommand.setArg("arg2", t2)
    except TypeException as e:
        print("Exception: %s" % e.getMsg())
Exemple #14
0
def test_event_encoder():
    """
    Tests the encoding of the event encoder
    """
    config = ConfigManager()
    config.set("types", "msg_len", "U16")

    enc = EventEncoder()
    enc_config = EventEncoder(config)

    temp = EventTemplate(
        101,
        "test_ch",
        "test_comp",
        [("a1", "a1", U32Type()), ("a2", "a2", U32Type())],
        EventSeverity["DIAGNOSTIC"],
        "%d %d",
    )

    time_obj = TimeType(2, 0, 1533758629, 123456)

    event_obj = EventData((U32Type(42), U32Type(10)), time_obj, temp)

    desc_bin = b"\x00\x00\x00\x02"
    id_bin = b"\x00\x00\x00\x65"
    time_bin = b"\x00\x02\x00\x5b\x6b\x4c\xa5\x00\x01\xe2\x40"
    arg_bin = b"\x00\x00\x00\x2a\x00\x00\x00\x0a"
    long_len_bin = b"\x00\x00\x00\x1b"
    short_len_bin = b"\x00\x1b"

    reg_expected = long_len_bin + desc_bin + id_bin + time_bin + arg_bin
    config_expected = short_len_bin + desc_bin + id_bin + time_bin + arg_bin

    reg_output = enc.encode_api(event_obj)

    assert (reg_output == reg_expected
            ), "FAIL: expected regular output to be %s, but found %s" % (
                list(reg_expected),
                list(reg_output),
            )

    config_output = enc_config.encode_api(event_obj)

    assert (config_output == config_expected
            ), "FAIL: expected configured output to be %s, but found %s" % (
                list(config_expected),
                list(config_output),
            )

    temp = EventTemplate(
        102,
        "test_ch2",
        "test_comp2",
        [("a1", "a1", U8Type()), ("a2", "a2", U16Type())],
        EventSeverity["DIAGNOSTIC"],
        "%d %d",
    )

    time_obj = TimeType(2, 0, 1533758628, 123457)

    event_obj = EventData((U8Type(128), U16Type(40)), time_obj, temp)

    desc_bin = b"\x00\x00\x00\x02"
    id_bin = b"\x00\x00\x00\x66"
    time_bin = b"\x00\x02\x00\x5b\x6b\x4c\xa4\x00\x01\xe2\x41"
    arg_bin = b"\x80\x00\x28"
    long_len_bin = b"\x00\x00\x00\x16"
    short_len_bin = b"\x00\x16"

    reg_expected = long_len_bin + desc_bin + id_bin + time_bin + arg_bin
    config_expected = short_len_bin + desc_bin + id_bin + time_bin + arg_bin

    reg_output = enc.encode_api(event_obj)

    assert (reg_output == reg_expected
            ), "FAIL: expected regular output to be %s, but found %s" % (
                list(reg_expected),
                list(reg_output),
            )

    config_output = enc_config.encode_api(event_obj)

    assert (config_output == config_expected
            ), "FAIL: expected configured output to be %s, but found %s" % (
                list(config_expected),
                list(config_output),
            )
Exemple #15
0
def test_ch_encoder():
    """
    Tests the encoding of the channel encoder
    """
    config = ConfigManager()
    config.set("types", "msg_len", "U16")

    enc = ChEncoder()
    enc_config = ChEncoder(config)

    temp = ChTemplate(101, "test_ch", "test_comp", U32Type())

    time_obj = TimeType(2, 0, 1533758629, 123456)

    ch_obj = ChData(U32Type(42), time_obj, temp)

    desc_bin = b"\x00\x00\x00\x01"
    id_bin = b"\x00\x00\x00\x65"
    time_bin = b"\x00\x02\x00\x5b\x6b\x4c\xa5\x00\x01\xe2\x40"
    val_bin = b"\x00\x00\x00\x2a"
    long_len_bin = b"\x00\x00\x00\x17"
    short_len_bin = b"\x00\x17"

    reg_expected = long_len_bin + desc_bin + id_bin + time_bin + val_bin
    config_expected = short_len_bin + desc_bin + id_bin + time_bin + val_bin

    reg_output = enc.encode_api(ch_obj)

    assert (reg_output == reg_expected
            ), "FAIL: expected regular output to be %s, but found %s" % (
                list(reg_expected),
                list(reg_output),
            )

    config_output = enc_config.encode_api(ch_obj)

    assert (config_output == config_expected
            ), "FAIL: expected configured output to be %s, but found %s" % (
                list(config_expected),
                list(config_output),
            )

    temp = ChTemplate(102, "test_ch2", "test_comp2", U16Type())

    time_obj = TimeType(2, 0, 1533758628, 123457)

    ch_obj = ChData(U16Type(40), time_obj, temp)

    desc_bin = b"\x00\x00\x00\x01"
    id_bin = b"\x00\x00\x00\x66"
    time_bin = b"\x00\x02\x00\x5b\x6b\x4c\xa4\x00\x01\xe2\x41"
    val_bin = b"\x00\x28"
    long_len_bin = b"\x00\x00\x00\x15"
    short_len_bin = b"\x00\x15"

    reg_expected = long_len_bin + desc_bin + id_bin + time_bin + val_bin
    config_expected = short_len_bin + desc_bin + id_bin + time_bin + val_bin

    reg_output = enc.encode_api(ch_obj)

    assert (reg_output == reg_expected
            ), "FAIL: expected regular output to be %s, but found %s" % (
                list(reg_expected),
                list(reg_output),
            )

    config_output = enc_config.encode_api(ch_obj)

    assert (config_output == config_expected
            ), "FAIL: expected configured output to be %s, but found %s" % (
                list(config_expected),
                list(config_output),
            )
Exemple #16
0
 def __length(command):
     return U32Type(len(command)).serialize()
Exemple #17
0
 def get_counter_sequence(self, length):
     seq = []
     for i in range(0, length):
         ch_temp = self.pipeline.dictionaries.channel_name["Counter"]
         seq.append(ChData(U32Type(i), TimeType(), ch_temp))
     return seq
Exemple #18
0
    def parse_type(self, type_name, xml_item, xml_tree):
        """
        Parses the given type string and returns a type object.

        Args:
            type_name (string): Name of the type in the xml
            xml_item (lxml etree root): Parsed xml object for the item
                      containing the type name being parsed. This is used to get
                      meta data such as string lenght.
            xml_tree (lxml etree root): Parsed Xml object containing enum and
                                        serializable type info (may not be used)

        Returns:
            Object of a class derived from the TypeBase class if successful,
            Raises an exception if the parsing fails. The caller will hold the
            only reference to the object.
        """

        if type_name == "I8":
            return I8Type()
        elif type_name == "I16":
            return I16Type()
        elif type_name == "I32":
            return I32Type()
        elif type_name == "I64":
            return I64Type()
        elif type_name == "U8":
            return U8Type()
        elif type_name == "U16":
            return U16Type()
        elif type_name == "U32":
            return U32Type()
        elif type_name == "U64":
            return U64Type()
        elif type_name == "F32":
            return F32Type()
        elif type_name == "F64":
            return F64Type()
        elif type_name == "bool":
            return BoolType()
        elif type_name == "string":
            if self.STR_LEN_TAG not in xml_item.attrib:
                print(
                    "Trying to parse string type, but found %s field" % self.STR_LEN_TAG
                )
                return None
            return StringType(max_string_len=int(xml_item.get(self.STR_LEN_TAG), 0))
        else:
            # First try Serialized types:
            result = self.get_serializable_type(type_name, xml_tree)
            if result is not None:
                return result

            # Now try enums:
            result = self.get_enum_type(type_name, xml_tree)
            if result is not None:
                return result

            # Now try arrays:
            result = self.get_array_type(type_name, xml_tree)
            if result is not None:
                return result

            # Abandon all hope
            raise exceptions.GseControllerParsingException(
                "Could not find type %s" % type_name
            )