mirror of
https://github.com/craigerl/aprsd.git
synced 2024-11-21 15:51:52 -05:00
Compare commits
2 Commits
9f7d169c18
...
1c50c39e61
Author | SHA1 | Date | |
---|---|---|---|
1c50c39e61 | |||
06c1fb985e |
@ -23,13 +23,24 @@ class APRSISClient(base.APRSClient):
|
|||||||
max_timeout = {"hours": 0.0, "minutes": 2, "seconds": 0}
|
max_timeout = {"hours": 0.0, "minutes": 2, "seconds": 0}
|
||||||
self.max_delta = datetime.timedelta(**max_timeout)
|
self.max_delta = datetime.timedelta(**max_timeout)
|
||||||
|
|
||||||
def stats(self) -> dict:
|
def stats(self, serializable=False) -> dict:
|
||||||
stats = {}
|
stats = {}
|
||||||
if self.is_configured():
|
if self.is_configured():
|
||||||
|
if self._client:
|
||||||
|
keepalive = self._client.aprsd_keepalive
|
||||||
|
server_string = self._client.server_string
|
||||||
|
if serializable:
|
||||||
|
keepalive = keepalive.isoformat()
|
||||||
|
else:
|
||||||
|
keepalive = "None"
|
||||||
|
server_string = "None"
|
||||||
stats = {
|
stats = {
|
||||||
"server_string": self._client.server_string,
|
"connected": self.is_connected,
|
||||||
"sever_keepalive": self._client.aprsd_keepalive,
|
|
||||||
"filter": self.filter,
|
"filter": self.filter,
|
||||||
|
"keepalive": keepalive,
|
||||||
|
"login_status": self.login_status,
|
||||||
|
"server_string": server_string,
|
||||||
|
"transport": self.transport(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return stats
|
return stats
|
||||||
@ -99,22 +110,31 @@ class APRSISClient(base.APRSClient):
|
|||||||
self.connected = False
|
self.connected = False
|
||||||
backoff = 1
|
backoff = 1
|
||||||
aprs_client = None
|
aprs_client = None
|
||||||
|
retries = 3
|
||||||
|
retry_count = 0
|
||||||
while not self.connected:
|
while not self.connected:
|
||||||
|
retry_count += 1
|
||||||
|
if retry_count >= retries:
|
||||||
|
break
|
||||||
try:
|
try:
|
||||||
LOG.info(f"Creating aprslib client({host}:{port}) and logging in {user}.")
|
LOG.info(f"Creating aprslib client({host}:{port}) and logging in {user}.")
|
||||||
aprs_client = aprsis.Aprsdis(user, passwd=password, host=host, port=port)
|
aprs_client = aprsis.Aprsdis(user, passwd=password, host=host, port=port)
|
||||||
# Force the log to be the same
|
# Force the log to be the same
|
||||||
aprs_client.logger = LOG
|
aprs_client.logger = LOG
|
||||||
aprs_client.connect()
|
aprs_client.connect()
|
||||||
self.connected = True
|
self.connected = self.login_status["success"] = True
|
||||||
|
self.login_status["message"] = aprs_client.server_string
|
||||||
backoff = 1
|
backoff = 1
|
||||||
except LoginError as e:
|
except LoginError as e:
|
||||||
LOG.error(f"Failed to login to APRS-IS Server '{e}'")
|
LOG.error(f"Failed to login to APRS-IS Server '{e}'")
|
||||||
self.connected = False
|
self.connected = self.login_status["success"] = False
|
||||||
|
self.login_status["message"] = e.message
|
||||||
|
LOG.error(e.message)
|
||||||
time.sleep(backoff)
|
time.sleep(backoff)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(f"Unable to connect to APRS-IS server. '{e}' ")
|
LOG.error(f"Unable to connect to APRS-IS server. '{e}' ")
|
||||||
self.connected = False
|
self.connected = self.login_status["success"] = False
|
||||||
|
self.login_status["message"] = e.message
|
||||||
time.sleep(backoff)
|
time.sleep(backoff)
|
||||||
# Don't allow the backoff to go to inifinity.
|
# Don't allow the backoff to go to inifinity.
|
||||||
if backoff > 5:
|
if backoff > 5:
|
||||||
@ -135,5 +155,7 @@ class APRSISClient(base.APRSClient):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(e)
|
LOG.error(e)
|
||||||
LOG.info(e.__cause__)
|
LOG.info(e.__cause__)
|
||||||
|
raise e
|
||||||
else:
|
else:
|
||||||
LOG.warning("client is None, might be resetting.")
|
LOG.warning("client is None, might be resetting.")
|
||||||
|
self.connected = False
|
||||||
|
@ -19,6 +19,10 @@ class APRSClient:
|
|||||||
_client = None
|
_client = None
|
||||||
|
|
||||||
connected = False
|
connected = False
|
||||||
|
login_status = {
|
||||||
|
"success": False,
|
||||||
|
"message": None,
|
||||||
|
}
|
||||||
filter = None
|
filter = None
|
||||||
lock = threading.Lock()
|
lock = threading.Lock()
|
||||||
|
|
||||||
@ -38,6 +42,18 @@ class APRSClient:
|
|||||||
dict: Statistics about the connection and packet handling
|
dict: Statistics about the connection and packet handling
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_connected(self):
|
||||||
|
return self.connected
|
||||||
|
|
||||||
|
@property
|
||||||
|
def login_success(self):
|
||||||
|
return self.login_status.get("success", False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def login_failure(self):
|
||||||
|
return self.login_status["message"]
|
||||||
|
|
||||||
def set_filter(self, filter):
|
def set_filter(self, filter):
|
||||||
self.filter = filter
|
self.filter = filter
|
||||||
if self._client:
|
if self._client:
|
||||||
|
@ -27,6 +27,9 @@ class Aprsdis(aprslib.IS):
|
|||||||
# date for last time we heard from the server
|
# date for last time we heard from the server
|
||||||
aprsd_keepalive = datetime.datetime.now()
|
aprsd_keepalive = datetime.datetime.now()
|
||||||
|
|
||||||
|
# Which server we are connected to?
|
||||||
|
server_string = "None"
|
||||||
|
|
||||||
# timeout in seconds
|
# timeout in seconds
|
||||||
select_timeout = 1
|
select_timeout = 1
|
||||||
lock = threading.Lock()
|
lock = threading.Lock()
|
||||||
|
@ -14,8 +14,11 @@ LOG = logging.getLogger("APRSD")
|
|||||||
|
|
||||||
class APRSDFakeClient(base.APRSClient, metaclass=trace.TraceWrapperMetaclass):
|
class APRSDFakeClient(base.APRSClient, metaclass=trace.TraceWrapperMetaclass):
|
||||||
|
|
||||||
def stats(self) -> dict:
|
def stats(self, serializable=False) -> dict:
|
||||||
return {}
|
return {
|
||||||
|
"transport": "Fake",
|
||||||
|
"connected": True,
|
||||||
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_enabled():
|
def is_enabled():
|
||||||
|
@ -17,12 +17,18 @@ class KISSClient(base.APRSClient):
|
|||||||
|
|
||||||
_client = None
|
_client = None
|
||||||
|
|
||||||
def stats(self) -> dict:
|
def stats(self, serializable=False) -> dict:
|
||||||
stats = {}
|
stats = {}
|
||||||
if self.is_configured():
|
if self.is_configured():
|
||||||
return {
|
stats = {
|
||||||
|
"connected": self.is_connected,
|
||||||
"transport": self.transport(),
|
"transport": self.transport(),
|
||||||
}
|
}
|
||||||
|
if self.transport() == client.TRANSPORT_TCPKISS:
|
||||||
|
stats["host"] = CONF.kiss_tcp.host
|
||||||
|
stats["port"] = CONF.kiss_tcp.port
|
||||||
|
elif self.transport() == client.TRANSPORT_SERIALKISS:
|
||||||
|
stats["device"] = CONF.kiss_serial.device
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -17,22 +17,4 @@ class APRSClientStats:
|
|||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
def stats(self, serializable=False):
|
def stats(self, serializable=False):
|
||||||
cl = client.client_factory.create()
|
return client.client_factory.create().stats(serializable=serializable)
|
||||||
stats = {
|
|
||||||
"transport": cl.transport(),
|
|
||||||
"filter": cl.filter,
|
|
||||||
"connected": cl.connected,
|
|
||||||
}
|
|
||||||
|
|
||||||
if cl.transport() == client.TRANSPORT_APRSIS:
|
|
||||||
stats["server_string"] = cl.client.server_string
|
|
||||||
keepalive = cl.client.aprsd_keepalive
|
|
||||||
if serializable:
|
|
||||||
keepalive = keepalive.isoformat()
|
|
||||||
stats["server_keepalive"] = keepalive
|
|
||||||
elif cl.transport() == client.TRANSPORT_TCPKISS:
|
|
||||||
stats["host"] = CONF.kiss_tcp.host
|
|
||||||
stats["port"] = CONF.kiss_tcp.port
|
|
||||||
elif cl.transport() == client.TRANSPORT_SERIALKISS:
|
|
||||||
stats["device"] = CONF.kiss_serial.device
|
|
||||||
return stats
|
|
||||||
|
@ -256,6 +256,12 @@ def listen(
|
|||||||
LOG.info("Creating client connection")
|
LOG.info("Creating client connection")
|
||||||
aprs_client = client_factory.create()
|
aprs_client = client_factory.create()
|
||||||
LOG.info(aprs_client)
|
LOG.info(aprs_client)
|
||||||
|
if not aprs_client.login_success:
|
||||||
|
# We failed to login, will just quit!
|
||||||
|
msg = f"Login Failure: {aprs_client.login_failure}"
|
||||||
|
LOG.error(msg)
|
||||||
|
print(msg)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
LOG.debug(f"Filter by '{filter}'")
|
LOG.debug(f"Filter by '{filter}'")
|
||||||
aprs_client.set_filter(filter)
|
aprs_client.set_filter(filter)
|
||||||
|
@ -54,10 +54,27 @@ def server(ctx, flush):
|
|||||||
LOG.error("No Clients are enabled in config.")
|
LOG.error("No Clients are enabled in config.")
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# Make sure we have 1 client transport enabled
|
||||||
|
if not client_factory.is_client_enabled():
|
||||||
|
LOG.error("No Clients are enabled in config.")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
if not client_factory.is_client_configured():
|
||||||
|
LOG.error("APRS client is not properly configured in config file.")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
# Creates the client object
|
# Creates the client object
|
||||||
LOG.info("Creating client connection")
|
LOG.info("Creating client connection")
|
||||||
aprs_client = client_factory.create()
|
aprs_client = client_factory.create()
|
||||||
LOG.info(aprs_client)
|
LOG.info(aprs_client)
|
||||||
|
if not aprs_client.login_success:
|
||||||
|
# We failed to login, will just quit!
|
||||||
|
msg = f"Login Failure: {aprs_client.login_failure}"
|
||||||
|
LOG.error(msg)
|
||||||
|
print(msg)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# Check to make sure the login worked.
|
||||||
|
|
||||||
# Create the initial PM singleton and Register plugins
|
# Create the initial PM singleton and Register plugins
|
||||||
# We register plugins first here so we can register each
|
# We register plugins first here so we can register each
|
||||||
@ -78,15 +95,6 @@ def server(ctx, flush):
|
|||||||
for p in watchlist_plugins:
|
for p in watchlist_plugins:
|
||||||
LOG.info(p)
|
LOG.info(p)
|
||||||
|
|
||||||
# Make sure we have 1 client transport enabled
|
|
||||||
if not client_factory.is_client_enabled():
|
|
||||||
LOG.error("No Clients are enabled in config.")
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
if not client_factory.is_client_configured():
|
|
||||||
LOG.error("APRS client is not properly configured in config file.")
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
if not CONF.enable_seen_list:
|
if not CONF.enable_seen_list:
|
||||||
# just deregister the class from the packet collector
|
# just deregister the class from the packet collector
|
||||||
packet_collector.PacketCollector().unregister(seen_list.SeenList)
|
packet_collector.PacketCollector().unregister(seen_list.SeenList)
|
||||||
|
@ -24,7 +24,9 @@ from aprsd import utils as aprsd_utils
|
|||||||
from aprsd.client import client_factory, kiss
|
from aprsd.client import client_factory, kiss
|
||||||
from aprsd.main import cli
|
from aprsd.main import cli
|
||||||
from aprsd.threads import aprsd as aprsd_threads
|
from aprsd.threads import aprsd as aprsd_threads
|
||||||
from aprsd.threads import keep_alive, rx, tx
|
from aprsd.threads import keep_alive, rx
|
||||||
|
from aprsd.threads import stats as stats_thread
|
||||||
|
from aprsd.threads import tx
|
||||||
from aprsd.utils import trace
|
from aprsd.utils import trace
|
||||||
|
|
||||||
|
|
||||||
@ -614,10 +616,24 @@ def webchat(ctx, flush, port):
|
|||||||
LOG.error("APRS client is not properly configured in config file.")
|
LOG.error("APRS client is not properly configured in config file.")
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# Creates the client object
|
||||||
|
LOG.info("Creating client connection")
|
||||||
|
aprs_client = client_factory.create()
|
||||||
|
LOG.info(aprs_client)
|
||||||
|
if not aprs_client.login_success:
|
||||||
|
# We failed to login, will just quit!
|
||||||
|
msg = f"Login Failure: {aprs_client.login_failure}"
|
||||||
|
LOG.error(msg)
|
||||||
|
print(msg)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
keepalive = keep_alive.KeepAliveThread()
|
keepalive = keep_alive.KeepAliveThread()
|
||||||
LOG.info("Start KeepAliveThread")
|
LOG.info("Start KeepAliveThread")
|
||||||
keepalive.start()
|
keepalive.start()
|
||||||
|
|
||||||
|
stats_store_thread = stats_thread.APRSDStatsStoreThread()
|
||||||
|
stats_store_thread.start()
|
||||||
|
|
||||||
socketio = init_flask(loglevel, quiet)
|
socketio = init_flask(loglevel, quiet)
|
||||||
rx_thread = rx.APRSDPluginRXThread(
|
rx_thread = rx.APRSDPluginRXThread(
|
||||||
packet_queue=threads.packet_queue,
|
packet_queue=threads.packet_queue,
|
||||||
|
@ -5,6 +5,7 @@ import tracemalloc
|
|||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
import timeago
|
||||||
|
|
||||||
from aprsd import packets, utils
|
from aprsd import packets, utils
|
||||||
from aprsd.client import client_factory
|
from aprsd.client import client_factory
|
||||||
@ -98,6 +99,9 @@ class KeepAliveThread(APRSDThread):
|
|||||||
|
|
||||||
# check the APRS connection
|
# check the APRS connection
|
||||||
cl = client_factory.create()
|
cl = client_factory.create()
|
||||||
|
cl_stats = cl.stats()
|
||||||
|
keepalive = timeago.format(cl_stats.get("keepalive", None))
|
||||||
|
LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>")
|
||||||
# Reset the connection if it's dead and this isn't our
|
# Reset the connection if it's dead and this isn't our
|
||||||
# First time through the loop.
|
# First time through the loop.
|
||||||
# The first time through the loop can happen at startup where
|
# The first time through the loop can happen at startup where
|
||||||
|
@ -18,6 +18,8 @@ LOG = logging.getLogger("APRSD")
|
|||||||
|
|
||||||
|
|
||||||
class APRSDRXThread(APRSDThread):
|
class APRSDRXThread(APRSDThread):
|
||||||
|
_client = None
|
||||||
|
|
||||||
def __init__(self, packet_queue):
|
def __init__(self, packet_queue):
|
||||||
super().__init__("RX_PKT")
|
super().__init__("RX_PKT")
|
||||||
self.packet_queue = packet_queue
|
self.packet_queue = packet_queue
|
||||||
@ -33,6 +35,12 @@ class APRSDRXThread(APRSDThread):
|
|||||||
self._client = client_factory.create()
|
self._client = client_factory.create()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
if not self._client.is_connected:
|
||||||
|
self._client = client_factory.create()
|
||||||
|
time.sleep(1)
|
||||||
|
return True
|
||||||
|
|
||||||
# setup the consumer of messages and block until a messages
|
# setup the consumer of messages and block until a messages
|
||||||
try:
|
try:
|
||||||
# This will register a packet consumer with aprslib
|
# This will register a packet consumer with aprslib
|
||||||
|
Loading…
Reference in New Issue
Block a user