diff --git a/aprsd/clients/fake.py b/aprsd/clients/fake.py index 87e8d0b..b468808 100644 --- a/aprsd/clients/fake.py +++ b/aprsd/clients/fake.py @@ -2,6 +2,7 @@ import logging import threading import time +import aprslib from oslo_config import cfg import wrapt @@ -21,6 +22,11 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass): thread_stop = False lock = threading.Lock() + path = [] + + def __init__(self): + LOG.info("Starting APRSDFakeClient client.") + self.path = ["WIDE1-1", "WIDE2-1"] def stop(self): self.thread_stop = True @@ -34,16 +40,34 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass): def send(self, packet: core.Packet): """Send an APRS Message object.""" LOG.info(f"Sending packet: {packet}") + payload = None + if isinstance(packet, core.Packet): + packet.prepare() + payload = packet.payload.encode("US-ASCII") + if packet.path: + packet.path + else: + self.path + else: + msg_payload = f"{packet.raw}{{{str(packet.msgNo)}" + payload = ( + ":{:<9}:{}".format( + packet.to_call, + msg_payload, + ) + ).encode("US-ASCII") + + LOG.debug( + f"FAKE::Send '{payload}' TO '{packet.to_call}' From " + f"'{packet.from_call}' with PATH \"{self.path}\"", + ) def consumer(self, callback, blocking=False, immortal=False, raw=False): LOG.debug("Start non blocking FAKE consumer") # Generate packets here? - pkt = core.MessagePacket( - from_call="N0CALL", - to_call=CONF.callsign, - message_text="Hello World", - msgNo=13, - ) + raw = "GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW" + pkt_raw = aprslib.parse(raw) + pkt = core.Packet.factory(pkt_raw) callback(packet=pkt) LOG.debug(f"END blocking FAKE consumer {self}") time.sleep(8) diff --git a/aprsd/clients/kiss.py b/aprsd/clients/kiss.py index 8a7dffa..76bd8dd 100644 --- a/aprsd/clients/kiss.py +++ b/aprsd/clients/kiss.py @@ -14,6 +14,8 @@ LOG = logging.getLogger("APRSD") class KISS3Client: + path = [] + def __init__(self): self.setup() @@ -34,6 +36,7 @@ class KISS3Client: speed=CONF.kiss_serial.baudrate, strip_df_start=True, ) + self.path = CONF.kiss_serial.path elif CONF.kiss_tcp.enabled: LOG.debug( "KISS({}) TCP Connection to {}:{}".format( @@ -47,6 +50,7 @@ class KISS3Client: port=CONF.kiss_tcp.port, strip_df_start=True, ) + self.path = CONF.kiss_serial.path LOG.debug("Starting KISS interface connection") self.kiss.start() @@ -87,10 +91,12 @@ class KISS3Client: """Send an APRS Message object.""" payload = None - path = ["WIDE1-1", "WIDE2-1"] + self.path if isinstance(packet, core.Packet): packet.prepare() payload = packet.payload.encode("US-ASCII") + if packet.path: + packet.path else: msg_payload = f"{packet.raw}{{{str(packet.msgNo)}" payload = ( @@ -102,12 +108,12 @@ class KISS3Client: LOG.debug( f"KISS Send '{payload}' TO '{packet.to_call}' From " - f"'{packet.from_call}' with PATH '{path}'", + f"'{packet.from_call}' with PATH '{self.path}'", ) frame = Frame.ui( destination="APZ100", source=packet.from_call, - path=path, + path=self.path, info=payload, ) self.kiss.write(frame) diff --git a/aprsd/cmds/webchat.py b/aprsd/cmds/webchat.py index ff56a16..87c2cdc 100644 --- a/aprsd/cmds/webchat.py +++ b/aprsd/cmds/webchat.py @@ -157,25 +157,26 @@ def _get_transport(stats): "APRS-IS Server: " "{}".format(stats["stats"]["aprs-is"]["server"]) ) - else: - # We might be connected to a KISS socket? - if client.KISSClient.is_enabled(): - transport = client.KISSClient.transport() - if transport == client.TRANSPORT_TCPKISS: - aprs_connection = ( - "TCPKISS://{}:{}".format( - CONF.kiss_tcp.host, - CONF.kiss_tcp.port, - ) - ) - elif transport == client.TRANSPORT_SERIALKISS: - # for pep8 violation - aprs_connection = ( - "SerialKISS://{}@{} baud".format( - CONF.kiss_serial.device, - CONF.kiss_serial.baudrate, - ), + elif client.KISSClient.is_enabled(): + transport = client.KISSClient.transport() + if transport == client.TRANSPORT_TCPKISS: + aprs_connection = ( + "TCPKISS://{}:{}".format( + CONF.kiss_tcp.host, + CONF.kiss_tcp.port, ) + ) + elif transport == client.TRANSPORT_SERIALKISS: + # for pep8 violation + aprs_connection = ( + "SerialKISS://{}@{} baud".format( + CONF.kiss_serial.device, + CONF.kiss_serial.baudrate, + ), + ) + elif CONF.fake_client.enabled: + transport = client.TRANSPORT_FAKE + aprs_connection = "Fake Client" return transport, aprs_connection @@ -279,10 +280,18 @@ class SendMessageNamespace(Namespace): LOG.debug(f"WS: on_send {data}") self.request = data data["from"] = CONF.callsign + path = data.get("path", None) + if "," in path: + path_opts = path.split(",") + path = [x.strip() for x in path_opts] + else: + path = [path] + pkt = packets.MessagePacket( from_call=data["from"], to_call=data["to"].upper(), message_text=data["message"], + path=path, ) pkt.prepare() self.msg = pkt diff --git a/aprsd/conf/client.py b/aprsd/conf/client.py index cb77e09..9697783 100644 --- a/aprsd/conf/client.py +++ b/aprsd/conf/client.py @@ -11,10 +11,12 @@ aprs_group = cfg.OptGroup( name="aprs_network", title="APRS-IS Network settings", ) + kiss_serial_group = cfg.OptGroup( name="kiss_serial", title="KISS Serial device connection", ) + kiss_tcp_group = cfg.OptGroup( name="kiss_tcp", title="KISS TCP/IP Device connection", @@ -70,6 +72,11 @@ kiss_serial_opts = [ default=9600, help="The Serial device baud rate for communication", ), + cfg.MultiStrOpt( + "path", + default=["WIDE1-1", "WIDE2-1"], + help="The APRS path to use for wide area coverage.", + ), ] kiss_tcp_opts = [ @@ -87,6 +94,11 @@ kiss_tcp_opts = [ default=8001, help="The KISS TCP/IP network port", ), + cfg.MultiStrOpt( + "path", + default=["WIDE1-1", "WIDE2-1"], + help="The APRS path to use for wide area coverage.", + ), ] fake_client_opts = [ diff --git a/aprsd/web/chat/static/js/send-message.js b/aprsd/web/chat/static/js/send-message.js index 6b2d3f2..8645a50 100644 --- a/aprsd/web/chat/static/js/send-message.js +++ b/aprsd/web/chat/static/js/send-message.js @@ -61,6 +61,7 @@ function init_chat() { event.preventDefault(); to_call = $('#to_call').val(); message = $('#message').val(); + path = $('#pkt_path option:selected').val(); if (to_call == "") { raise_error("You must enter a callsign to send a message") return false; @@ -69,7 +70,8 @@ function init_chat() { raise_error("You must enter a message to send") return false; } - msg = {'to': to_call, 'message': message, } + msg = {'to': to_call, 'message': message, 'path': path}; + console.log(msg); socket.emit("send", msg); $('#message').val(''); } @@ -294,7 +296,7 @@ function delete_tab(callsign) { save_data(); } -function add_callsign(callsign) { +function add_callsign(callsign, msg) { /* Ensure a callsign exists in the left hand nav */ if (callsign in callsign_list) { return false @@ -306,10 +308,19 @@ function add_callsign(callsign) { active = false; } create_callsign_tab(callsign, active); - callsign_list[callsign] = true; + callsign_list[callsign] = ''; return true; } +function update_callsign_path(callsign, path) { + //Get the selected path to save for this callsign + path = msg['path'] + console.log("Path is " + path); + $('#pkt_path').val(path); + callsign_list[callsign] = path; + +} + function append_message(callsign, msg, msg_html) { new_callsign = false if (!message_list.hasOwnProperty(callsign)) { @@ -330,7 +341,9 @@ function append_message(callsign, msg, msg_html) { } // Find the right div to place the html - new_callsign = add_callsign(callsign); + + new_callsign = add_callsign(callsign, msg); + update_callsign_path(callsign, msg['path']); append_message_html(callsign, msg_html, new_callsign); if (new_callsign) { //Now click the tab @@ -486,4 +499,6 @@ function callsign_select(callsign) { tab_notify_id = tab_notification_id(callsign, true); $(tab_notify_id).addClass('visually-hidden'); $(tab_notify_id).text(0); + // Now update the path + $('#pkt_path').val(callsign_list[callsign]); } diff --git a/aprsd/web/chat/templates/index.html b/aprsd/web/chat/templates/index.html index b18bdac..decf09f 100644 --- a/aprsd/web/chat/templates/index.html +++ b/aprsd/web/chat/templates/index.html @@ -90,10 +90,19 @@