1
0
mirror of https://github.com/craigerl/aprsd.git synced 2025-07-02 17:05:18 -04:00

Add ability to change path on every TX packet

This patch adds the ability to webchat to set the path
on every outbound packet for the KISS clients as well as
the fake client.  The path dropdown includes the options for
Default path (which will default to the config setting)
WIDE1-1,WIDE2-1
ARISS
This commit is contained in:
Hemna 2023-10-05 10:33:07 -04:00
parent e2f89a6043
commit ddd4d25e9d
6 changed files with 107 additions and 32 deletions

View File

@ -2,6 +2,7 @@ import logging
import threading import threading
import time import time
import aprslib
from oslo_config import cfg from oslo_config import cfg
import wrapt import wrapt
@ -21,6 +22,11 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
thread_stop = False thread_stop = False
lock = threading.Lock() lock = threading.Lock()
path = []
def __init__(self):
LOG.info("Starting APRSDFakeClient client.")
self.path = ["WIDE1-1", "WIDE2-1"]
def stop(self): def stop(self):
self.thread_stop = True self.thread_stop = True
@ -34,16 +40,34 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
def send(self, packet: core.Packet): def send(self, packet: core.Packet):
"""Send an APRS Message object.""" """Send an APRS Message object."""
LOG.info(f"Sending packet: {packet}") 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): def consumer(self, callback, blocking=False, immortal=False, raw=False):
LOG.debug("Start non blocking FAKE consumer") LOG.debug("Start non blocking FAKE consumer")
# Generate packets here? # Generate packets here?
pkt = core.MessagePacket( raw = "GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW"
from_call="N0CALL", pkt_raw = aprslib.parse(raw)
to_call=CONF.callsign, pkt = core.Packet.factory(pkt_raw)
message_text="Hello World",
msgNo=13,
)
callback(packet=pkt) callback(packet=pkt)
LOG.debug(f"END blocking FAKE consumer {self}") LOG.debug(f"END blocking FAKE consumer {self}")
time.sleep(8) time.sleep(8)

View File

@ -14,6 +14,8 @@ LOG = logging.getLogger("APRSD")
class KISS3Client: class KISS3Client:
path = []
def __init__(self): def __init__(self):
self.setup() self.setup()
@ -34,6 +36,7 @@ class KISS3Client:
speed=CONF.kiss_serial.baudrate, speed=CONF.kiss_serial.baudrate,
strip_df_start=True, strip_df_start=True,
) )
self.path = CONF.kiss_serial.path
elif CONF.kiss_tcp.enabled: elif CONF.kiss_tcp.enabled:
LOG.debug( LOG.debug(
"KISS({}) TCP Connection to {}:{}".format( "KISS({}) TCP Connection to {}:{}".format(
@ -47,6 +50,7 @@ class KISS3Client:
port=CONF.kiss_tcp.port, port=CONF.kiss_tcp.port,
strip_df_start=True, strip_df_start=True,
) )
self.path = CONF.kiss_serial.path
LOG.debug("Starting KISS interface connection") LOG.debug("Starting KISS interface connection")
self.kiss.start() self.kiss.start()
@ -87,10 +91,12 @@ class KISS3Client:
"""Send an APRS Message object.""" """Send an APRS Message object."""
payload = None payload = None
path = ["WIDE1-1", "WIDE2-1"] self.path
if isinstance(packet, core.Packet): if isinstance(packet, core.Packet):
packet.prepare() packet.prepare()
payload = packet.payload.encode("US-ASCII") payload = packet.payload.encode("US-ASCII")
if packet.path:
packet.path
else: else:
msg_payload = f"{packet.raw}{{{str(packet.msgNo)}" msg_payload = f"{packet.raw}{{{str(packet.msgNo)}"
payload = ( payload = (
@ -102,12 +108,12 @@ class KISS3Client:
LOG.debug( LOG.debug(
f"KISS Send '{payload}' TO '{packet.to_call}' From " 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( frame = Frame.ui(
destination="APZ100", destination="APZ100",
source=packet.from_call, source=packet.from_call,
path=path, path=self.path,
info=payload, info=payload,
) )
self.kiss.write(frame) self.kiss.write(frame)

View File

@ -157,25 +157,26 @@ def _get_transport(stats):
"APRS-IS Server: <a href='http://status.aprs2.net' >" "APRS-IS Server: <a href='http://status.aprs2.net' >"
"{}</a>".format(stats["stats"]["aprs-is"]["server"]) "{}</a>".format(stats["stats"]["aprs-is"]["server"])
) )
else: elif client.KISSClient.is_enabled():
# We might be connected to a KISS socket? transport = client.KISSClient.transport()
if client.KISSClient.is_enabled(): if transport == client.TRANSPORT_TCPKISS:
transport = client.KISSClient.transport() aprs_connection = (
if transport == client.TRANSPORT_TCPKISS: "TCPKISS://{}:{}".format(
aprs_connection = ( CONF.kiss_tcp.host,
"TCPKISS://{}:{}".format( CONF.kiss_tcp.port,
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 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 return transport, aprs_connection
@ -279,10 +280,18 @@ class SendMessageNamespace(Namespace):
LOG.debug(f"WS: on_send {data}") LOG.debug(f"WS: on_send {data}")
self.request = data self.request = data
data["from"] = CONF.callsign 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( pkt = packets.MessagePacket(
from_call=data["from"], from_call=data["from"],
to_call=data["to"].upper(), to_call=data["to"].upper(),
message_text=data["message"], message_text=data["message"],
path=path,
) )
pkt.prepare() pkt.prepare()
self.msg = pkt self.msg = pkt

View File

@ -11,10 +11,12 @@ aprs_group = cfg.OptGroup(
name="aprs_network", name="aprs_network",
title="APRS-IS Network settings", title="APRS-IS Network settings",
) )
kiss_serial_group = cfg.OptGroup( kiss_serial_group = cfg.OptGroup(
name="kiss_serial", name="kiss_serial",
title="KISS Serial device connection", title="KISS Serial device connection",
) )
kiss_tcp_group = cfg.OptGroup( kiss_tcp_group = cfg.OptGroup(
name="kiss_tcp", name="kiss_tcp",
title="KISS TCP/IP Device connection", title="KISS TCP/IP Device connection",
@ -70,6 +72,11 @@ kiss_serial_opts = [
default=9600, default=9600,
help="The Serial device baud rate for communication", 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 = [ kiss_tcp_opts = [
@ -87,6 +94,11 @@ kiss_tcp_opts = [
default=8001, default=8001,
help="The KISS TCP/IP network port", 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 = [ fake_client_opts = [

View File

@ -61,6 +61,7 @@ function init_chat() {
event.preventDefault(); event.preventDefault();
to_call = $('#to_call').val(); to_call = $('#to_call').val();
message = $('#message').val(); message = $('#message').val();
path = $('#pkt_path option:selected').val();
if (to_call == "") { if (to_call == "") {
raise_error("You must enter a callsign to send a message") raise_error("You must enter a callsign to send a message")
return false; return false;
@ -69,7 +70,8 @@ function init_chat() {
raise_error("You must enter a message to send") raise_error("You must enter a message to send")
return false; return false;
} }
msg = {'to': to_call, 'message': message, } msg = {'to': to_call, 'message': message, 'path': path};
console.log(msg);
socket.emit("send", msg); socket.emit("send", msg);
$('#message').val(''); $('#message').val('');
} }
@ -294,7 +296,7 @@ function delete_tab(callsign) {
save_data(); save_data();
} }
function add_callsign(callsign) { function add_callsign(callsign, msg) {
/* Ensure a callsign exists in the left hand nav */ /* Ensure a callsign exists in the left hand nav */
if (callsign in callsign_list) { if (callsign in callsign_list) {
return false return false
@ -306,10 +308,19 @@ function add_callsign(callsign) {
active = false; active = false;
} }
create_callsign_tab(callsign, active); create_callsign_tab(callsign, active);
callsign_list[callsign] = true; callsign_list[callsign] = '';
return true; 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) { function append_message(callsign, msg, msg_html) {
new_callsign = false new_callsign = false
if (!message_list.hasOwnProperty(callsign)) { if (!message_list.hasOwnProperty(callsign)) {
@ -330,7 +341,9 @@ function append_message(callsign, msg, msg_html) {
} }
// Find the right div to place the 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); append_message_html(callsign, msg_html, new_callsign);
if (new_callsign) { if (new_callsign) {
//Now click the tab //Now click the tab
@ -486,4 +499,6 @@ function callsign_select(callsign) {
tab_notify_id = tab_notification_id(callsign, true); tab_notify_id = tab_notification_id(callsign, true);
$(tab_notify_id).addClass('visually-hidden'); $(tab_notify_id).addClass('visually-hidden');
$(tab_notify_id).text(0); $(tab_notify_id).text(0);
// Now update the path
$('#pkt_path').val(callsign_list[callsign]);
} }

View File

@ -90,10 +90,19 @@
</div> </div>
<div class="row"> <div class="row">
<form class="row gx-1 gy-1 justify-content-center align-items-center" id="sendform" name="sendmsg" action=""> <form class="row gx-1 gy-1 justify-content-center align-items-center" id="sendform" name="sendmsg" action="">
<div class="col-sm-3"> <div class="col-sm-2" style="width:150px;">
<label for="to_call" class="visually-hidden">Callsign</label> <label for="to_call" class="visually-hidden">Callsign</label>
<input type="search" class="form-control mb-2 mr-sm-2" name="to_call" id="to_call" placeholder="To Callsign" size="11" maxlength="9"> <input type="search" class="form-control mb-2 mr-sm-2" name="to_call" id="to_call" placeholder="To Callsign" size="11" maxlength="9">
</div> </div>
<div class="col-auto">
<label for="pkt_path" class="visually-hidden">PATH</label>
<select class="form-control mb-2 mr-sm-2" name="pkt_path" id="pkt_path" style="width:auto;">
<option value="">Default Path</option>
<option value="WIDE1-1,WIDE2-2" selected>WIDE1-1,WIDE2-2</option>
<option value="WIDE1-1">WIDE1-1</option>
<option value="ARISS">ARISS</option>
</select>
</div>
<div class="col-sm-3"> <div class="col-sm-3">
<label for="message" class="visually-hidden">Message</label> <label for="message" class="visually-hidden">Message</label>
<input type="search" class="form-control mb-2 mr-sm-2" name="message" id="message" size="40" maxlength="67" placeholder="Message"> <input type="search" class="form-control mb-2 mr-sm-2" name="message" id="message" size="40" maxlength="67" placeholder="Message">