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
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
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.")
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
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()