def parse_pprz_msg(callback, ivy_msg): """ Parse an Ivy message into a PprzMessage. :param callback: function to call with ac_id and parsed PprzMessage as params :param ivy_msg: Ivy message string to parse into PprzMessage """ # normal format is "sender_name msg_name msg_payload..." # advanced format has requests and answers (with request_id as 'pid_index') # request: "sender_name request_id msg_name_REQ msg_payload..." # answer: "request_id sender_name msg_name msg_payload..." data = re.search("(\S+) +(\S+) +(.*)", ivy_msg) # check for request_id in first or second string (-> advanced format with msg_name in third string) if data is None: return if re.search("[0-9]+_[0-9]+", data.group(1)) or re.search("[0-9]+_[0-9]+", data.group(2)): if re.search("[0-9]+_[0-9]+", data.group(1)): sender_name = data.group(2) else: sender_name = data.group(1) # this is an advanced type, split again data = re.search("(\S+) +(.*)", data.group(3)) msg_name = data.group(1) payload = data.group(2) else: # this was a normal message sender_name = data.group(1) msg_name = data.group(2) payload = data.group(3) # check which message class it is msg_class, msg_name = messages_xml_map.find_msg_by_name(msg_name) if msg_class is None: print("Ignoring unknown message " + ivy_msg) return msg = PprzMessage(msg_class, msg_name) msg.ivy_string_to_payload(payload) # pass non-telemetry messages with ac_id 0 or ac_id attrib value if msg_class == "telemetry": try: if(sender_name[0:6] == 'replay'): ac_id = int(sender_name[6:]) else: ac_id = int(sender_name) except ValueError: print("ignoring message " + ivy_msg) sys.stdout.flush() else: if 'ac_id' in msg.fieldnames: ac_id_idx = msg.fieldnames.index('ac_id') ac_id = msg.fieldvalues[ac_id_idx] else: ac_id = 0 # finally call the callback, passing the aircraft id and parsed message callback(ac_id, msg)