mirror of
https://github.com/craigerl/aprsd.git
synced 2024-11-18 06:11:49 -05:00
Use new aprsd.callsign as the main callsign
This patch changes how aprsd identifies itself when connected to any client, which is not relying on the login for each client. There are 3 supported clients currently aprsis, tcpkiss serialkiss. Each client has their own potential login/callsign to connect to the remote. This patch tells aprsd to use the new config option aprsd.callsign as a means to identify itself. It will accept packets as <aprsd.callsign> and reply as <aprsd.callsign> regardless of which client object is being used to connect to the remote. Note: this breaks backwards compatibility. This patch now requires the new config option aprsd: callsign: <callsign>
This commit is contained in:
parent
5f28788180
commit
ad79ed1261
@ -156,8 +156,8 @@ class KISSClient(Client):
|
|||||||
# Ensure that the config vars are correctly set
|
# Ensure that the config vars are correctly set
|
||||||
if KISSClient.is_enabled(config):
|
if KISSClient.is_enabled(config):
|
||||||
config.check_option(
|
config.check_option(
|
||||||
"kiss.callsign",
|
"aprsd.callsign",
|
||||||
default_fail=aprsd_config.DEFAULT_CONFIG_DICT["kiss"]["callsign"],
|
default_fail=aprsd_config.DEFAULT_CONFIG_DICT["aprsd"]["callsign"],
|
||||||
)
|
)
|
||||||
transport = KISSClient.transport(config)
|
transport = KISSClient.transport(config)
|
||||||
if transport == TRANSPORT_SERIALKISS:
|
if transport == TRANSPORT_SERIALKISS:
|
||||||
|
@ -32,6 +32,7 @@ class Aioax25Client:
|
|||||||
device=self.config["kiss"]["serial"]["device"],
|
device=self.config["kiss"]["serial"]["device"],
|
||||||
baudrate=self.config["kiss"]["serial"].get("baudrate", 9600),
|
baudrate=self.config["kiss"]["serial"].get("baudrate", 9600),
|
||||||
loop=self.loop,
|
loop=self.loop,
|
||||||
|
log=LOG,
|
||||||
)
|
)
|
||||||
elif "tcp" in self.config["kiss"] and self.config["kiss"]["tcp"].get(
|
elif "tcp" in self.config["kiss"] and self.config["kiss"]["tcp"].get(
|
||||||
"enabled",
|
"enabled",
|
||||||
@ -50,30 +51,32 @@ class Aioax25Client:
|
|||||||
log=LOG,
|
log=LOG,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.kissdev.open()
|
|
||||||
self.kissport0 = self.kissdev[0]
|
|
||||||
|
|
||||||
LOG.debug("Creating AX25Interface")
|
LOG.debug("Creating AX25Interface")
|
||||||
self.ax25int = interface.AX25Interface(kissport=self.kissport0, loop=self.loop)
|
self.ax25int = interface.AX25Interface(
|
||||||
|
kissport=self.kissdev[0],
|
||||||
|
loop=self.loop,
|
||||||
|
log=LOG,
|
||||||
|
)
|
||||||
|
|
||||||
LOG.debug("Creating APRSInterface")
|
LOG.debug("Creating APRSInterface")
|
||||||
self.aprsint = APRSInterface(
|
self.aprsint = APRSInterface(
|
||||||
ax25int=self.ax25int,
|
ax25int=self.ax25int,
|
||||||
mycall=self.config["kiss"]["callsign"],
|
mycall=self.config["aprsd"]["callsign"],
|
||||||
log=LOG,
|
log=LOG,
|
||||||
)
|
)
|
||||||
|
self.kissdev.open()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
LOG.debug(self.kissdev)
|
LOG.debug(self.kissdev)
|
||||||
self.kissdev._close()
|
|
||||||
self.loop.stop()
|
self.loop.stop()
|
||||||
|
self.kissdev.close()
|
||||||
|
|
||||||
def set_filter(self, filter):
|
def set_filter(self, filter):
|
||||||
# This does nothing right now.
|
# This does nothing right now.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def consumer(self, callback, blocking=True, immortal=False, raw=False):
|
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
||||||
callsign = self.config["kiss"]["callsign"]
|
callsign = self.config["aprsd"]["callsign"]
|
||||||
call = callsign.split("-")
|
call = callsign.split("-")
|
||||||
if len(call) > 1:
|
if len(call) > 1:
|
||||||
callsign = call[0]
|
callsign = call[0]
|
||||||
@ -81,10 +84,28 @@ class Aioax25Client:
|
|||||||
else:
|
else:
|
||||||
ssid = 0
|
ssid = 0
|
||||||
self.aprsint.bind(callback=callback, callsign=callsign, ssid=ssid, regex=False)
|
self.aprsint.bind(callback=callback, callsign=callsign, ssid=ssid, regex=False)
|
||||||
|
|
||||||
|
# async def set_after(fut, delay, value):
|
||||||
|
# # Sleep for *delay* seconds.
|
||||||
|
# await asyncio.sleep(delay)
|
||||||
|
#
|
||||||
|
# # Set *value* as a result of *fut* Future.
|
||||||
|
# fut.set_result(value)
|
||||||
|
#
|
||||||
|
# async def my_wait(fut):
|
||||||
|
# await fut
|
||||||
|
#
|
||||||
|
# fut = self.loop.create_future()
|
||||||
|
# self.loop.create_task(
|
||||||
|
# set_after(fut, 5, "nothing")
|
||||||
|
# )
|
||||||
|
LOG.debug("RUN FOREVER")
|
||||||
self.loop.run_forever()
|
self.loop.run_forever()
|
||||||
|
# my_wait(fut)
|
||||||
|
|
||||||
def send(self, msg):
|
def send(self, msg):
|
||||||
"""Send an APRS Message object."""
|
"""Send an APRS Message object."""
|
||||||
|
LOG.debug(f"Send {msg} TO KISS")
|
||||||
payload = f"{msg._filter_for_send()}"
|
payload = f"{msg._filter_for_send()}"
|
||||||
self.aprsint.send_message(
|
self.aprsint.send_message(
|
||||||
addressee=msg.tocall,
|
addressee=msg.tocall,
|
||||||
|
@ -93,18 +93,21 @@ class SentMessages(objectstore.ObjectStoreMixin):
|
|||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
def set_status(self, id, status):
|
def set_status(self, id, status):
|
||||||
|
if id in self.data:
|
||||||
self.data[id]["last_update"] = str(datetime.datetime.now())
|
self.data[id]["last_update"] = str(datetime.datetime.now())
|
||||||
self.data[id]["status"] = status
|
self.data[id]["status"] = status
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
def ack(self, id):
|
def ack(self, id):
|
||||||
"""The message got an ack!"""
|
"""The message got an ack!"""
|
||||||
|
if id in self.data:
|
||||||
self.data[id]["last_update"] = str(datetime.datetime.now())
|
self.data[id]["last_update"] = str(datetime.datetime.now())
|
||||||
self.data[id]["ack"] = True
|
self.data[id]["ack"] = True
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
def reply(self, id, packet):
|
def reply(self, id, packet):
|
||||||
"""We got a packet back from the sent message."""
|
"""We got a packet back from the sent message."""
|
||||||
|
if id in self.data:
|
||||||
self.data[id]["reply"] = packet
|
self.data[id]["reply"] = packet
|
||||||
|
|
||||||
|
|
||||||
@ -126,7 +129,6 @@ class WebChatRXThread(rx.APRSDRXThread):
|
|||||||
self.connected = connected
|
self.connected = connected
|
||||||
|
|
||||||
def loop(self):
|
def loop(self):
|
||||||
|
|
||||||
# setup the consumer of messages and block until a messages
|
# setup the consumer of messages and block until a messages
|
||||||
msg = None
|
msg = None
|
||||||
try:
|
try:
|
||||||
@ -227,15 +229,16 @@ class WebChatTXThread(aprsd_thread.APRSDThread):
|
|||||||
self.got_ack = True
|
self.got_ack = True
|
||||||
|
|
||||||
def process_packet(self, packet):
|
def process_packet(self, packet):
|
||||||
|
LOG.info(f"process PACKET {packet}")
|
||||||
tocall = packet.get("addresse", None)
|
tocall = packet.get("addresse", None)
|
||||||
fromcall = packet["from"]
|
fromcall = packet["from"]
|
||||||
msg = packet.get("message_text", None)
|
msg = packet.get("message_text", None)
|
||||||
msg_id = packet.get("msgNo", "0")
|
msg_id = packet.get("msgNo", "0")
|
||||||
msg_response = packet.get("response", None)
|
msg_response = packet.get("response", None)
|
||||||
|
|
||||||
if tocall == self.config["aprs"]["login"] and msg_response == "ack":
|
if tocall == self.config["aprsd"]["callsign"] and msg_response == "ack":
|
||||||
self.process_ack_packet(packet)
|
self.process_ack_packet(packet)
|
||||||
elif tocall == self.config["aprs"]["login"]:
|
elif tocall == self.config["aprsd"]["callsign"]:
|
||||||
messaging.log_message(
|
messaging.log_message(
|
||||||
"Received Message",
|
"Received Message",
|
||||||
packet["raw"],
|
packet["raw"],
|
||||||
@ -246,11 +249,11 @@ class WebChatTXThread(aprsd_thread.APRSDThread):
|
|||||||
# let any threads do their thing, then ack
|
# let any threads do their thing, then ack
|
||||||
# send an ack last
|
# send an ack last
|
||||||
ack = messaging.AckMessage(
|
ack = messaging.AckMessage(
|
||||||
self.config["aprs"]["login"],
|
self.config["aprsd"]["callsign"],
|
||||||
fromcall,
|
fromcall,
|
||||||
msg_id=msg_id,
|
msg_id=msg_id,
|
||||||
)
|
)
|
||||||
self.msg_queues["tx"].put(ack)
|
ack.send()
|
||||||
|
|
||||||
packets.PacketList().add(packet)
|
packets.PacketList().add(packet)
|
||||||
stats.APRSDStats().msgs_rx_inc()
|
stats.APRSDStats().msgs_rx_inc()
|
||||||
@ -299,7 +302,7 @@ class WebChatFlask(flask_classful.FlaskView):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# We might be connected to a KISS socket?
|
# We might be connected to a KISS socket?
|
||||||
if client.KISSClient.kiss_enabled(self.config):
|
if client.KISSClient.is_enabled(self.config):
|
||||||
transport = client.KISSClient.transport(self.config)
|
transport = client.KISSClient.transport(self.config)
|
||||||
if transport == client.TRANSPORT_TCPKISS:
|
if transport == client.TRANSPORT_TCPKISS:
|
||||||
aprs_connection = (
|
aprs_connection = (
|
||||||
@ -324,7 +327,7 @@ class WebChatFlask(flask_classful.FlaskView):
|
|||||||
"index.html",
|
"index.html",
|
||||||
initial_stats=stats,
|
initial_stats=stats,
|
||||||
aprs_connection=aprs_connection,
|
aprs_connection=aprs_connection,
|
||||||
callsign=self.config["aprs"]["login"],
|
callsign=self.config["aprsd"]["callsign"],
|
||||||
version=aprsd.__version__,
|
version=aprsd.__version__,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -335,7 +338,6 @@ class WebChatFlask(flask_classful.FlaskView):
|
|||||||
info = msgs.get_all()
|
info = msgs.get_all()
|
||||||
return json.dumps(info)
|
return json.dumps(info)
|
||||||
|
|
||||||
@trace.trace
|
|
||||||
def _stats(self):
|
def _stats(self):
|
||||||
stats_obj = stats.APRSDStats()
|
stats_obj = stats.APRSDStats()
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
@ -406,8 +408,8 @@ class SendMessageNamespace(Namespace):
|
|||||||
"sent", SentMessages().get(self.msg.id),
|
"sent", SentMessages().get(self.msg.id),
|
||||||
namespace="/sendmsg",
|
namespace="/sendmsg",
|
||||||
)
|
)
|
||||||
|
msg.send()
|
||||||
self._msg_queues["tx"].put(msg)
|
# self._msg_queues["tx"].put(msg)
|
||||||
|
|
||||||
def handle_message(self, data):
|
def handle_message(self, data):
|
||||||
LOG.debug(f"WS Data {data}")
|
LOG.debug(f"WS Data {data}")
|
||||||
|
@ -57,13 +57,13 @@ DEFAULT_CONFIG_DICT = {
|
|||||||
"ham": {"callsign": "NOCALL"},
|
"ham": {"callsign": "NOCALL"},
|
||||||
"aprs": {
|
"aprs": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
|
# Only used as the login for aprsis.
|
||||||
"login": "CALLSIGN",
|
"login": "CALLSIGN",
|
||||||
"password": "00000",
|
"password": "00000",
|
||||||
"host": "rotate.aprs2.net",
|
"host": "rotate.aprs2.net",
|
||||||
"port": 14580,
|
"port": 14580,
|
||||||
},
|
},
|
||||||
"kiss": {
|
"kiss": {
|
||||||
"callsign": "NOCALL",
|
|
||||||
"tcp": {
|
"tcp": {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
"host": "direwolf.ip.address",
|
"host": "direwolf.ip.address",
|
||||||
@ -76,11 +76,14 @@ DEFAULT_CONFIG_DICT = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"aprsd": {
|
"aprsd": {
|
||||||
|
# Callsign to use for all packets to/from aprsd instance
|
||||||
|
# regardless of the client (aprsis vs kiss)
|
||||||
|
"callsign": "NOCALL",
|
||||||
"logfile": "/tmp/aprsd.log",
|
"logfile": "/tmp/aprsd.log",
|
||||||
"logformat": DEFAULT_LOG_FORMAT,
|
"logformat": DEFAULT_LOG_FORMAT,
|
||||||
"dateformat": DEFAULT_DATE_FORMAT,
|
"dateformat": DEFAULT_DATE_FORMAT,
|
||||||
"save_location": DEFAULT_CONFIG_DIR,
|
"save_location": DEFAULT_CONFIG_DIR,
|
||||||
"rich_logging": False,
|
"rich_logging": True,
|
||||||
"trace": False,
|
"trace": False,
|
||||||
"enabled_plugins": CORE_MESSAGE_PLUGINS,
|
"enabled_plugins": CORE_MESSAGE_PLUGINS,
|
||||||
"units": "imperial",
|
"units": "imperial",
|
||||||
@ -177,16 +180,35 @@ class Config(collections.UserDict):
|
|||||||
if not self.exists(path):
|
if not self.exists(path):
|
||||||
if type(path) is list:
|
if type(path) is list:
|
||||||
path = ".".join(path)
|
path = ".".join(path)
|
||||||
raise exception.MissingConfigOption(path)
|
raise exception.MissingConfigOptionException(path)
|
||||||
|
|
||||||
val = self.get(path)
|
val = self.get(path)
|
||||||
if val == default_fail:
|
if val == default_fail:
|
||||||
# We have to fail and bail if the user hasn't edited
|
# We have to fail and bail if the user hasn't edited
|
||||||
# this config option.
|
# this config option.
|
||||||
raise exception.ConfigOptionBogusDefaultException(path, default_fail)
|
raise exception.ConfigOptionBogusDefaultException(
|
||||||
|
path, default_fail,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def add_config_comments(raw_yaml):
|
def add_config_comments(raw_yaml):
|
||||||
|
end_idx = utils.end_substr(raw_yaml, "ham:")
|
||||||
|
if end_idx != -1:
|
||||||
|
# lets insert a comment
|
||||||
|
raw_yaml = utils.insert_str(
|
||||||
|
raw_yaml,
|
||||||
|
"\n # Callsign that owns this instance of APRSD.",
|
||||||
|
end_idx,
|
||||||
|
)
|
||||||
|
end_idx = utils.end_substr(raw_yaml, "aprsd:")
|
||||||
|
if end_idx != -1:
|
||||||
|
# lets insert a comment
|
||||||
|
raw_yaml = utils.insert_str(
|
||||||
|
raw_yaml,
|
||||||
|
"\n # Callsign to use for all APRSD Packets as the to/from."
|
||||||
|
"\n # regardless of client type (aprsis vs tcpkiss vs serial)",
|
||||||
|
end_idx,
|
||||||
|
)
|
||||||
end_idx = utils.end_substr(raw_yaml, "aprs:")
|
end_idx = utils.end_substr(raw_yaml, "aprs:")
|
||||||
if end_idx != -1:
|
if end_idx != -1:
|
||||||
# lets insert a comment
|
# lets insert a comment
|
||||||
@ -326,6 +348,11 @@ def parse_config(config_file):
|
|||||||
config,
|
config,
|
||||||
["aprsd"],
|
["aprsd"],
|
||||||
)
|
)
|
||||||
|
check_option(
|
||||||
|
config,
|
||||||
|
"aprsd.callsign",
|
||||||
|
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["callsign"],
|
||||||
|
)
|
||||||
|
|
||||||
# Ensure they change the admin password
|
# Ensure they change the admin password
|
||||||
if config.get("aprsd.web.enabled") is True:
|
if config.get("aprsd.web.enabled") is True:
|
||||||
|
@ -41,7 +41,7 @@ class KeepAliveThread(APRSDThread):
|
|||||||
stats_obj.set_memory_peak(peak)
|
stats_obj.set_memory_peak(peak)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
login = self.config["aprs"]["login"]
|
login = self.config["aprsd"]["callsign"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
login = self.config["ham"]["callsign"]
|
login = self.config["ham"]["callsign"]
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ class APRSDProcessPacketThread(APRSDThread):
|
|||||||
|
|
||||||
# We don't put ack packets destined for us through the
|
# We don't put ack packets destined for us through the
|
||||||
# plugins.
|
# plugins.
|
||||||
if tocall == self.config["aprs"]["login"] and msg_response == "ack":
|
if tocall == self.config["aprsd"]["callsign"] and msg_response == "ack":
|
||||||
self.process_ack_packet(packet)
|
self.process_ack_packet(packet)
|
||||||
else:
|
else:
|
||||||
# It's not an ACK for us, so lets run it through
|
# It's not an ACK for us, so lets run it through
|
||||||
@ -115,12 +115,12 @@ class APRSDProcessPacketThread(APRSDThread):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Only ack messages that were sent directly to us
|
# Only ack messages that were sent directly to us
|
||||||
if tocall == self.config["aprs"]["login"]:
|
if tocall == self.config["aprsd"]["callsign"]:
|
||||||
stats.APRSDStats().msgs_rx_inc()
|
stats.APRSDStats().msgs_rx_inc()
|
||||||
# let any threads do their thing, then ack
|
# let any threads do their thing, then ack
|
||||||
# send an ack last
|
# send an ack last
|
||||||
ack = messaging.AckMessage(
|
ack = messaging.AckMessage(
|
||||||
self.config["aprs"]["login"],
|
self.config["aprsd"]["callsign"],
|
||||||
fromcall,
|
fromcall,
|
||||||
msg_id=msg_id,
|
msg_id=msg_id,
|
||||||
)
|
)
|
||||||
@ -142,7 +142,7 @@ class APRSDProcessPacketThread(APRSDThread):
|
|||||||
subreply.send()
|
subreply.send()
|
||||||
else:
|
else:
|
||||||
msg = messaging.TextMessage(
|
msg = messaging.TextMessage(
|
||||||
self.config["aprs"]["login"],
|
self.config["aprsd"]["callsign"],
|
||||||
fromcall,
|
fromcall,
|
||||||
subreply,
|
subreply,
|
||||||
)
|
)
|
||||||
@ -162,7 +162,7 @@ class APRSDProcessPacketThread(APRSDThread):
|
|||||||
LOG.debug(f"Sending '{reply}'")
|
LOG.debug(f"Sending '{reply}'")
|
||||||
|
|
||||||
msg = messaging.TextMessage(
|
msg = messaging.TextMessage(
|
||||||
self.config["aprs"]["login"],
|
self.config["aprsd"]["callsign"],
|
||||||
fromcall,
|
fromcall,
|
||||||
reply,
|
reply,
|
||||||
)
|
)
|
||||||
@ -170,10 +170,10 @@ class APRSDProcessPacketThread(APRSDThread):
|
|||||||
|
|
||||||
# If the message was for us and we didn't have a
|
# If the message was for us and we didn't have a
|
||||||
# response, then we send a usage statement.
|
# response, then we send a usage statement.
|
||||||
if tocall == self.config["aprs"]["login"] and not replied:
|
if tocall == self.config["aprsd"]["callsign"] and not replied:
|
||||||
LOG.warning("Sending help!")
|
LOG.warning("Sending help!")
|
||||||
msg = messaging.TextMessage(
|
msg = messaging.TextMessage(
|
||||||
self.config["aprs"]["login"],
|
self.config["aprsd"]["callsign"],
|
||||||
fromcall,
|
fromcall,
|
||||||
"Unknown command! Send 'help' message for help",
|
"Unknown command! Send 'help' message for help",
|
||||||
)
|
)
|
||||||
@ -182,10 +182,10 @@ class APRSDProcessPacketThread(APRSDThread):
|
|||||||
LOG.error("Plugin failed!!!")
|
LOG.error("Plugin failed!!!")
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
# Do we need to send a reply?
|
# Do we need to send a reply?
|
||||||
if tocall == self.config["aprs"]["login"]:
|
if tocall == self.config["aprsd"]["callsign"]:
|
||||||
reply = "A Plugin failed! try again?"
|
reply = "A Plugin failed! try again?"
|
||||||
msg = messaging.TextMessage(
|
msg = messaging.TextMessage(
|
||||||
self.config["aprs"]["login"],
|
self.config["aprsd"]["callsign"],
|
||||||
fromcall,
|
fromcall,
|
||||||
reply,
|
reply,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user