def GetPayload(self, eds_id):
        '''
        From a given eds_id this checks if a payload is present.  If so, payload structure
        fuctions are called which are used in the Viewer to get all the appropriate user
        input widgets as well as creating the Payload structure itself.

        Inputs:
        eds_id - The EdsId associated with the command object

        Outputs:
        The payload structure of the EDS object associated with the input EdsId
        '''
        self.cmd_entry = EdsLib.DatabaseEntry(self.mission, eds_id)
        self.cmd = self.cmd_entry()
        payload_item = None

        for item in self.cmd_entry:
            if item[0] == 'Payload':
                payload_item = item

        if payload_item is not None:
            self.payload_entry = EdsLib.DatabaseEntry(payload_item[1],
                                                      payload_item[2])
            self.payload = self.payload_entry()
            self.payload_struct = self.GetPayloadStruct(
                self.payload_entry, self.payload, payload_item[0])

        else:
            self.payload_entry = None
            self.payload = None
            self.payload_struct = None

        return self.payload_struct
Example #2
0
def main():
    '''
    With a series of prompts to select the instance, topic, and subcommand, along with prompts to
    fill in relevant payload values, this function allows a user to send a packed EDS command via
    UDP to a core flight instance.
    '''

    mission = "@CFS_EDS_GS_MISSION_NAME@".lower()
    try:
        # Initialize databases
        eds_db = EdsLib.Database(mission)
        intf_db = CFE_MissionLib.Database(mission, eds_db)
        interface = intf_db.Interface("CFE_SB/Telecommand")
    except RuntimeError:
        print("cmdUtil.py is not properly configured")
        sys.exit(2)

    # Get the instance and topic from user input
    instance_id = get_instance_id(intf_db)
    topic_id = get_topic_id(interface)

    # Get the topic from the interface database to check for subcommands
    topic = interface.Topic(topic_id)

    # Get the associated command with the desired topic/subcommand
    cmd_entry = get_cmd_entry(eds_db, topic)
    cmd = cmd_entry()

    # Call set_pubsub to set the relevant header parameters
    set_pubsub(intf_db, instance_id, topic_id, cmd)

    # Fill in the payload if required
    payload = get_payload(cmd_entry)

    if not payload is None:
        cmd['Payload'] = payload

    cmd_packed = EdsLib.PackedObject(cmd)

    port = 1234 + instance_id

    while True:
        dest = input("\nEnter destination IP (Press Enter for 127.0.0.1) > ")
        if dest == '':
            dest = '127.0.0.1'

        try:
            opened_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            opened_socket.sendto(bytes(cmd_packed), (dest, port))

            print(f"\nSending data to '{dest}'; port {port}")
            print("Data to send:")
            print(hex_string(cmd_packed.hex(), 8))
            break
        except socket.error:
            print("Invalid IP address")
    def GetPayloadStruct(self, base_entry, base_object, base_name):
        '''
        Recursive function that goes through an EDS object structure (arrays and structs)
        To get down to the fundamental objects (ints, strings, and enumerations).

        Inputs:
        base_entry - EDS fucntion to create the base_object
        base_object - EDS Object that is iterated over to find the structure
        base_name - Name used in the recursion to get the full name of a fundamental object

        Outputs:
        EDS Object data structure
        '''
        try:
            # Test if array indexing works
            array_type_split = str(type(base_object[0])).split("'")
            array_entry = EdsLib.DatabaseEntry(array_type_split[1],
                                               array_type_split[3])
            array_object = array_entry()

            struct = []
            struct_name = base_name + array_entry.Name
            for i in range(len(base_object)):
                struct_name = f"{base_name}[{i}]"
                array_struct = self.GetPayloadStruct(array_entry, array_object,
                                                     struct_name)
                struct.append(array_struct)

        except TypeError:
            struct = {}
            # Test if base_object is a structure
            try:
                for subobj in base_object:
                    for subentry in base_entry:
                        if subobj[0] == subentry[0]:
                            entry_eds = EdsLib.DatabaseEntry(
                                subentry[1], subentry[2])
                            struct_name = f"{base_name}.{subobj[0]}"
                            struct[subobj[0]] = self.GetPayloadStruct(
                                entry_eds, subobj[1], struct_name)

            # Neither an array nor structure
            except TypeError:
                # Test if base_object is an enumeration
                try:
                    enum_dict = {}
                    for enum in base_entry:
                        enum_dict[enum[0]] = enum[1]
                        struct = (base_name, base_entry, 'enum', enum_dict)
                except TypeError:
                    struct = (base_name, base_entry, 'entry', None)

        return struct
    def DecodeMessage(self, raw_message):
        '''
        Decodes a raw bytes message into an EDS object

        Inputs:
        raw_message - received bytes message

        Outputs:
        topic_id - The Telemetry TopicId associated with the raw_message
        eds_entry - The EDS function to create the associated telemetry object
        eds_object - The decoded EDS object
        '''
        eds_id, topic_id = self.intf_db.DecodeEdsId(raw_message)
        eds_entry = EdsLib.DatabaseEntry(self.mission, eds_id)
        eds_object = eds_entry(EdsLib.PackedObject(raw_message))
        return (topic_id, eds_entry, eds_object)
    def InitializeDatabases(self, mission):
        '''
        Initialize the EDS and MissionLib databases as well as useful Interfaces
        and associated lists

        Inputs:
        mission - mission name
        '''
        if not self.initialized:
            try:
                # If the mission name is invlaid a RuntimeError will occur here
                self.eds_db = EdsLib.Database(mission)

                # Set the mission name and the rest of the CFE_MissionLib objects
                self.mission = mission
                self.intf_db = CFE_MissionLib.Database(self.mission,
                                                       self.eds_db)
                self.telecommand = self.intf_db.Interface('CFE_SB/Telecommand')
                self.telemetry = self.intf_db.Interface('CFE_SB/Telemetry')

                # Call Data Model initialization function
                GS_Model.data.InitializeLists()

                self.initialized = True
                return True
            except RuntimeError:
                return False
        else:
            return True
Example #6
0
def get_payload(cmd_entry):
    '''
    Iterating over the command entry object, check to see if a payload is needed.
    If so, the user is prompted to fill in the required payload values.

    Inputs:
    cmd_entry - EDS function to create the command object associated with the topic/subcommand

    Outputs:
    payload - EDS object of the command's payload filled in by the user
    '''
    is_payload = False
    for item in cmd_entry:
        if item[0] == 'Payload':
            payload_item = item
            is_payload = True

    if is_payload:
        # Use the information from the database entry iterator to get a payload Entry and object
        payload_entry = EdsLib.DatabaseEntry(payload_item[1], payload_item[2])
        payload = payload_entry()

        payload_struct = get_payload_struct(payload_entry, payload, 'Payload')
        eds_payload = set_payload_values(payload_struct)
        payload = payload_entry(eds_payload)
    else:
        payload = None

    return payload
def decode_message(mission, intf_db, raw_message):
    '''
    Decodes a raw input message into an EdsObject

    Inputs:
    mission - User specified mission name
    intf_db - CFE_MissionLib Interface Database
    raw_message - Packed Bytes message

    Outputs:
    eds_entry - The EdsDb function to create the EDS object associated with the input message
    eds_object - The Unpacked EdsDb Object
    '''
    eds_id, topic_id = intf_db.DecodeEdsId(raw_message)
    eds_entry = EdsLib.DatabaseEntry(mission, eds_id)
    eds_object = eds_entry(EdsLib.PackedObject(raw_message))
    return (eds_entry, eds_object)
def main(argv):
    """
    Gets the mission name and port number from command line arguments
    Opens up the receive port and listens for telemetry messages
    Each message is decoded into an EDS Object and the object's contents are printed to the screen
    """
    try:
        opts, args = getopt.getopt(argv, "hp:", ["port="])
    except getopt.GetoptError:
        print("tlm_decode.py -p <port number=5021>")
        sys.exit(2)

    udp_recv_port = 5021
    mission = "@CFS_EDS_GS_MISSION_NAME@".lower()
    for opt, arg in opts:
        if opt == '-h':
            print("tlm_decode.py -p <port number=5021>")
            sys.exit()
        elif opt in ('-p', '--port'):
            udp_recv_port = int(arg)

    try:
        # Initialize databases
        eds_db = EdsLib.Database(mission)
        intf_db = CFE_MissionLib.Database(mission, eds_db)
    except RuntimeError:
        print("tlm_decode is not properly configured")
        sys.exit(2)

    print("Listening in on port {} for messages".format(udp_recv_port))

    # Init udp socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('', udp_recv_port))

    # Wait for UDP messages
    while True:
        try:
            # Receive message
            datagram, host = sock.recvfrom(4096)  # buffer size is 1024 bytes

            # Ignore datagram if it is not long enough (i.e it doesnt contain tlm header)
            if len(datagram) < 6:
                continue

            print(
                f"Telemetry Packet From: {host[0]}:UDP{host[1]}, {8*len(datagram)} bits :"
            )
            print(hex_string(datagram.hex(), 16))
            eds_entry, eds_object = decode_message(mission, intf_db, datagram)
            display_entries(eds_object, eds_entry.Name)
            print()
            print()

        # Handle errors
        except socket.error:
            print('Ignored socket error.')
            time.sleep(1)
    def SendCommand(self, ip_address, instance_name, topic_name,
                    subcommand_name, payload_values):
        '''
        Sends a command message to an instance of core flight
            - Checks to make sure all required parameters are set
            - Creates the EDS command object and sets the necessary header parameters
            - Generates and sets the payload values (if necessary)
            - opens up a socket and sends the packed message

        Inputs:
        ip_address - The destination IP Address
        instance_name - The name of the core flight instance to send the command message
        topic_name - The name of the Telecommand topic to send
        subcommand_name - The name of the subcommand to the telecommand topic
        payload_values - list of user supplied payload values

        Outputs:
        A packed bytes message sent via UDP to an instance of core flight
        Tuple that contains:
            A flag if the message was successful
            A hex representation of the command message that was sent
            A timestamp of when the message was sent
            The port the command message was sent to
        '''

        if instance_name == GS_Model.data.instance_chooser:
            return (False, "Please Choose an Instance")
        if topic_name == GS_Model.data.topic_chooser:
            return (False, "Please Choose a Topic")
        if (subcommand_name == GS_Model.data.subcommand_chooser
                and len(GS_Model.data.subcommand_keys) > 1):
            return (False, "Please Choose a Subcommand")

        instance_id = GS_Model.data.instance_dict[instance_name]
        topic_id = GS_Model.data.telecommand_topic_dict[topic_name]

        self.cmd = self.cmd_entry()
        self.SetPubSub(instance_id, topic_id)

        self.payload_values = payload_values
        if len(self.payload_values) != 0:

            eds_payload = self.SetPayloadValues(self.payload_struct)
            self.payload = self.payload_entry(eds_payload)

            self.cmd['Payload'] = self.payload

        cmd_packed = EdsLib.PackedObject(self.cmd)
        port = 1234 + instance_id

        try:
            opened_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            opened_socket.sendto(bytes(cmd_packed), (ip_address, port))
            time_str = time.strftime("%Y-%m-%d__%H_%M_%S", time.gmtime())
            return (True, cmd_packed.hex(), time_str, port)
        except socket.error:
            return (False, "Failed to send message.")
Example #10
0
def get_cmd_entry(eds_db, topic):
    '''
    This routine checks if the input topic has any subcommands, and if so, prompts
    the user to select a command.  Otherwise, the command is based on the topic itself

    Inputs:
    eds_db - EDS Database object
    topic - a CFE_MissionLib interface topic

    Outputs:
    cmd_entry - EDS function to create the command object associated with the topic/subcommand
    '''
    try:
        subcommand_list = {}
        for subcommand in topic:
            subcommand_list[subcommand[0]] = subcommand[1]

        print("Subcommand List:")
        for subcommand in topic:
            print(subcommand[0])

        while True:
            subcommand_name = input("\nSelect Subcommand > ")
            try:
                subcommand_eds_id = subcommand_list[subcommand_name]
                break
            except KeyError:
                print("Invalid Subcommand")

        cmd_entry = EdsLib.DatabaseEntry(eds_db, subcommand_eds_id)

    # If the Topic doesn't have subcommands then the first for loop over will return
    # with a runtime error: use the EdsId from the Topic itself instead
    except RuntimeError:
        cmd_entry = EdsLib.DatabaseEntry(eds_db, topic.EdsId)

    return cmd_entry
Example #11
0
def main(argv):
    """
    Gets the telemetry filename from command line arguments
    Opens up the file and reads in the message length (4 byte unsigned int)
    Reads each message, decodes it into an EDS Object, and prints the object's
    contents to a csv file of the same base name
    """
    try:
        opts, args = getopt.getopt(argv, "hs", ["file="])
    except getopt.GetoptError:
        print("convert_tlm_file.py --file=<filename>")
        sys.exit(2)

    mission = "@CFS_EDS_GS_MISSION_NAME@".lower()
    labels_printed = False
    fout = None
    screen_flag = False
    for opt, arg in opts:
        if opt == '-h':
            print("convert_tlm_file.py --file=<filename>")
            print(" --file= : telemetry file name")
            print(" -h : help")
            print(" -s : print to screen")
            sys.exit()
        elif opt in ('--file'):
            filename = arg
        elif opt == '-s':
            screen_flag = True

    try:
        # Initialize databases
        eds_db = EdsLib.Database(mission)
        intf_db = CFE_MissionLib.Database(mission, eds_db)
    except RuntimeError:
        print("convert_tlm_file.py is not properly configured")
        sys.exit(2)

    try:
        fin = open(filename, 'rb')
    except RuntimeError:
        print("Invalid file name")
        print("convert_tlm_file.py -f <filename>")
        sys.exit(2)

    packet_length = int.from_bytes(fin.read(4), byteorder='big', signed=False)
    csv_filename = filename.replace('.bin', '.csv')
    fout = open(csv_filename, 'w')

    for packet in read_packet(fin, packet_length):
        topic_id, eds_entry, eds_object = decode_message(
            mission, intf_db, packet)
        if not labels_printed:
            csv_string = tlm_display_string('labels', eds_object,
                                            eds_entry.Name) + '\n'
            fout.write(csv_string)
            labels_printed = True
        csv_string = tlm_display_string('values', eds_object,
                                        eds_entry.Name) + '\n'
        fout.write(csv_string)

        # Print data to the screen if desired
        if screen_flag:
            print(hex_string(packet.hex(), 16))
            print(tlm_display_string('screen', eds_object, eds_entry.Name))

    fin.close()
    if fout is not None:
        fout.close()