diff --git a/aprsd/kissclient.py b/aprsd/kissclient.py index 9bd5d80..3db801e 100644 --- a/aprsd/kissclient.py +++ b/aprsd/kissclient.py @@ -1,7 +1,6 @@ import asyncio import logging -from aioax25 import frame as axframe from aioax25 import interface from aioax25 import kiss as kiss from aioax25.aprs import APRSInterface @@ -38,7 +37,7 @@ class KISSClient: return True if "tcp" in config["kiss"]: - if config["kiss"]["serial"].get("enabled", False): + if config["kiss"]["tcp"].get("enabled", False): return True @property @@ -88,14 +87,15 @@ class Aioax25Client: ): LOG.debug( "Setting up KISSTCP Connection to {}:{}".format( - self.config["kiss"]["host"], - self.config["kiss"]["port"], + self.config["kiss"]["tcp"]["host"], + self.config["kiss"]["tcp"]["port"], ), ) self.kissdev = kiss.TCPKISSDevice( - self.config["kiss"]["host"], - self.config["kiss"]["port"], + self.config["kiss"]["tcp"]["host"], + self.config["kiss"]["tcp"]["port"], loop=self.loop, + log=LOG, ) self.kissdev.open() @@ -107,7 +107,7 @@ class Aioax25Client: LOG.debug("Creating APRSInterface") self.aprsint = APRSInterface( ax25int=self.ax25int, - mycall=self.config["ham"]["callsign"], + mycall=self.config["kiss"]["callsign"], log=LOG, ) @@ -119,20 +119,17 @@ class Aioax25Client: def consumer(self, callback, callsign=None): if not callsign: callsign = self.config["ham"]["callsign"] - self.aprsint.bind(callback=callback, callsign=callsign, regex=True) + self.aprsint.bind(callback=callback, callsign="WB4BOR", ssid=12, regex=False) def send(self, msg): """Send an APRS Message object.""" - payload = msg._filter_for_send() - frame = axframe.AX25UnnumberedInformationFrame( - msg.tocall, - msg.fromcall.encode("UTF-8"), - pid=0xF0, - repeaters=b"WIDE2-1", - payload=payload, + payload = f"{msg._filter_for_send()}" + self.aprsint.send_message( + addressee=msg.tocall, + message=payload, + path=["WIDE1-1", "WIDE2-1"], + oneshot=True, ) - LOG.debug(frame) - self.ax25int.transmit(frame) def get_client(): diff --git a/aprsd/main.py b/aprsd/main.py index 05099e7..8a8f269 100644 --- a/aprsd/main.py +++ b/aprsd/main.py @@ -469,6 +469,12 @@ def server( cl.client except LoginError: sys.exit(-1) + + rx_thread = threads.APRSDRXThread( + msg_queues=threads.msg_queues, + config=config, + ) + rx_thread.start() else: LOG.info( "APRS network connection Not Enabled in config. This is" @@ -486,13 +492,6 @@ def server( packets.PacketList(config=config) - rx_thread = threads.APRSDRXThread( - msg_queues=threads.msg_queues, - config=config, - ) - - rx_thread.start() - if "watch_list" in config["aprsd"] and config["aprsd"]["watch_list"].get( "enabled", True, diff --git a/aprsd/messaging.py b/aprsd/messaging.py index 8186813..5a3db6d 100644 --- a/aprsd/messaging.py +++ b/aprsd/messaging.py @@ -489,6 +489,9 @@ class AckMessage(Message): self.id, ) + def _filter_for_send(self): + return f"ack{self.id}" + def send(self): LOG.debug(f"Send ACK({self.tocall}:{self.id}) to radio.") thread = SendAckThread(self) diff --git a/aprsd/threads.py b/aprsd/threads.py index bd7a4c5..8592aa5 100644 --- a/aprsd/threads.py +++ b/aprsd/threads.py @@ -8,9 +8,7 @@ import tracemalloc import aprslib -from aprsd import ( - client, kissclient, messaging, packets, plugin, stats, trace, utils, -) +from aprsd import client, kissclient, messaging, packets, plugin, stats, utils LOG = logging.getLogger("APRSD") @@ -182,9 +180,10 @@ class APRSDRXThread(APRSDThread): class APRSDProcessPacketThread(APRSDThread): - def __init__(self, packet, config): + def __init__(self, packet, config, transport="aprsis"): self.packet = packet self.config = config + self.transport = transport name = self.packet["raw"][:10] super().__init__(f"RX_PACKET-{name}") @@ -239,6 +238,7 @@ class APRSDProcessPacketThread(APRSDThread): self.config["aprs"]["login"], fromcall, msg_id=msg_id, + transport=self.transport, ) ack.send() @@ -257,6 +257,7 @@ class APRSDProcessPacketThread(APRSDThread): self.config["aprs"]["login"], fromcall, subreply, + transport=self.transport, ) msg.send() @@ -273,6 +274,7 @@ class APRSDProcessPacketThread(APRSDThread): self.config["aprs"]["login"], fromcall, reply, + transport=self.transport, ) msg.send() @@ -285,6 +287,7 @@ class APRSDProcessPacketThread(APRSDThread): self.config["aprs"]["login"], fromcall, reply, + transport=self.transport, ) msg.send() except Exception as ex: @@ -296,6 +299,7 @@ class APRSDProcessPacketThread(APRSDThread): self.config["aprs"]["login"], fromcall, reply, + transport=self.transport, ) msg.send() @@ -349,7 +353,7 @@ class KISSRXThread(APRSDThread): # and the aprslib developer didn't want to allow a PR to add # kwargs. :( # https://github.com/rossengeorgiev/aprs-python/pull/56 - kiss_client.consumer(self.process_packet, callsign="APN382") + kiss_client.consumer(self.process_packet, callsign=self.config["kiss"]["callsign"]) kiss_client.loop.run_forever() except aprslib.exceptions.ConnectionDrop: @@ -361,131 +365,21 @@ class KISSRXThread(APRSDThread): client.Client().reset() # Continue to loop - @trace.trace - def process_packet(self, interface, frame, match): + def process_packet(self, interface, frame): """Process a packet recieved from aprs-is server.""" LOG.debug(f"Got an APRS Frame '{frame}'") - + # try and nuke the * from the fromcall sign. + frame.header._source._ch = False payload = str(frame.payload.decode()) msg = f"{str(frame.header)}:{payload}" + LOG.debug(f"Decoding {msg}") packet = aprslib.parse(msg) LOG.debug(packet) - - try: - stats.APRSDStats().msgs_rx_inc() - - msg = packet.get("message_text", None) - msg_format = packet.get("format", None) - msg_response = packet.get("response", None) - if msg_format == "message" and msg: - # we want to send the message through the - # plugins - self.process_message_packet(packet) - return - elif msg_response == "ack": - self.process_ack_packet(packet) - return - - if msg_format == "mic-e": - # process a mic-e packet - self.process_mic_e_packet(packet) - return - - except (aprslib.ParseError, aprslib.UnknownFormat) as exp: - LOG.exception("Failed to parse packet from aprs-is", exp) - - @trace.trace - def process_message_packet(self, packet): - LOG.debug("Message packet rx") - fromcall = packet["from"] - message = packet.get("message_text", None) - msg_id = packet.get("msgNo", "0") - messaging.log_message( - "Received Message", - packet["raw"], - message, - fromcall=fromcall, - msg_num=msg_id, - ) - found_command = False - # Get singleton of the PM - pm = plugin.PluginManager() - try: - results = pm.run(fromcall=fromcall, message=message, ack=msg_id) - for reply in results: - found_command = True - # A plugin can return a null message flag which signals - # us that they processed the message correctly, but have - # nothing to reply with, so we avoid replying with a usage string - if reply is not messaging.NULL_MESSAGE: - LOG.debug(f"Sending '{reply}'") - - msg = messaging.TextMessage( - self.config["aprs"]["login"], - fromcall, - reply, - transport=messaging.MESSAGE_TRANSPORT_TCPKISS, - ) - self.msg_queues["tx"].put(msg) - else: - LOG.debug("Got NULL MESSAGE from plugin") - - if not found_command: - plugins = pm.get_plugins() - names = [x.command_name for x in plugins] - names.sort() - - # reply = "Usage: {}".format(", ".join(names)) - reply = "Usage: weather, locate [call], time, fortune, ping" - - msg = messaging.TextMessage( - self.config["aprs"]["login"], - fromcall, - reply, - transport=messaging.MESSAGE_TRANSPORT_TCPKISS, - ) - self.msg_queues["tx"].put(msg) - except Exception as ex: - LOG.exception("Plugin failed!!!", ex) - reply = "A Plugin failed! try again?" - msg = messaging.TextMessage( - self.config["aprs"]["login"], - fromcall, - reply, - transport=messaging.MESSAGE_TRANSPORT_TCPKISS, - ) - self.msg_queues["tx"].put(msg) - - # let any threads do their thing, then ack - # send an ack last - ack = messaging.AckMessage( - self.config["aprs"]["login"], - fromcall, - msg_id=msg_id, + thread = APRSDProcessPacketThread( + packet=packet, config=self.config, transport=messaging.MESSAGE_TRANSPORT_TCPKISS, ) - self.msg_queues["tx"].put(ack) - LOG.debug("Packet processing complete") - - def process_ack_packet(self, packet): - ack_num = packet.get("msgNo") - LOG.info(f"Got ack for message {ack_num}") - messaging.log_message( - "ACK", - packet["raw"], - None, - ack=ack_num, - fromcall=packet["from"], - ) - tracker = messaging.MsgTrack() - tracker.remove(ack_num) - stats.APRSDStats().ack_rx_inc() - return - - def process_mic_e_packet(self, packet): - LOG.info("Mic-E Packet detected. Currenlty unsupported.") - messaging.log_packet(packet) - stats.APRSDStats().msgs_mice_inc() + thread.start() return diff --git a/requirements.in b/requirements.in index 7d96198..7703126 100644 --- a/requirements.in +++ b/requirements.in @@ -1,4 +1,4 @@ -aioax25 +aioax25>=0.0.10 aprslib click click-completion diff --git a/requirements.txt b/requirements.txt index c02df9e..f044a69 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # # pip-compile requirements.in # -aioax25==0.0.9 +aioax25==0.0.10 # via -r requirements.in aprslib==0.6.47 # via -r requirements.in