aprsd 4.1.2__py3-none-any.whl → 4.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aprsd/client/__init__.py +5 -13
- aprsd/client/client.py +156 -0
- aprsd/client/drivers/__init__.py +10 -0
- aprsd/client/drivers/aprsis.py +174 -255
- aprsd/client/drivers/fake.py +59 -11
- aprsd/client/drivers/lib/__init__.py +0 -0
- aprsd/client/drivers/lib/aprslib.py +296 -0
- aprsd/client/drivers/registry.py +86 -0
- aprsd/client/drivers/tcpkiss.py +423 -0
- aprsd/client/stats.py +2 -2
- aprsd/cmds/dev.py +6 -4
- aprsd/cmds/fetch_stats.py +2 -0
- aprsd/cmds/list_plugins.py +6 -133
- aprsd/cmds/listen.py +5 -3
- aprsd/cmds/send_message.py +8 -5
- aprsd/cmds/server.py +7 -11
- aprsd/conf/common.py +7 -1
- aprsd/exception.py +7 -0
- aprsd/log/log.py +1 -1
- aprsd/main.py +0 -7
- aprsd/packets/core.py +168 -169
- aprsd/packets/log.py +69 -59
- aprsd/plugin.py +3 -2
- aprsd/plugin_utils.py +2 -2
- aprsd/plugins/weather.py +2 -2
- aprsd/stats/collector.py +5 -4
- aprsd/threads/rx.py +13 -11
- aprsd/threads/tx.py +32 -31
- aprsd/utils/keepalive_collector.py +7 -5
- aprsd/utils/package.py +176 -0
- {aprsd-4.1.2.dist-info → aprsd-4.2.1.dist-info}/METADATA +48 -48
- {aprsd-4.1.2.dist-info → aprsd-4.2.1.dist-info}/RECORD +37 -37
- {aprsd-4.1.2.dist-info → aprsd-4.2.1.dist-info}/WHEEL +1 -1
- aprsd/client/aprsis.py +0 -183
- aprsd/client/base.py +0 -156
- aprsd/client/drivers/kiss.py +0 -144
- aprsd/client/factory.py +0 -91
- aprsd/client/fake.py +0 -49
- aprsd/client/kiss.py +0 -143
- {aprsd-4.1.2.dist-info → aprsd-4.2.1.dist-info}/entry_points.txt +0 -0
- {aprsd-4.1.2.dist-info → aprsd-4.2.1.dist-info/licenses}/AUTHORS +0 -0
- {aprsd-4.1.2.dist-info → aprsd-4.2.1.dist-info/licenses}/LICENSE +0 -0
- {aprsd-4.1.2.dist-info → aprsd-4.2.1.dist-info}/top_level.txt +0 -0
aprsd/client/base.py
DELETED
@@ -1,156 +0,0 @@
|
|
1
|
-
import abc
|
2
|
-
import logging
|
3
|
-
import threading
|
4
|
-
|
5
|
-
import wrapt
|
6
|
-
from oslo_config import cfg
|
7
|
-
|
8
|
-
from aprsd.packets import core
|
9
|
-
from aprsd.utils import keepalive_collector
|
10
|
-
|
11
|
-
CONF = cfg.CONF
|
12
|
-
LOG = logging.getLogger('APRSD')
|
13
|
-
|
14
|
-
|
15
|
-
class APRSClient:
|
16
|
-
"""Singleton client class that constructs the aprslib connection."""
|
17
|
-
|
18
|
-
_instance = None
|
19
|
-
_client = None
|
20
|
-
|
21
|
-
connected = False
|
22
|
-
login_status = {
|
23
|
-
'success': False,
|
24
|
-
'message': None,
|
25
|
-
}
|
26
|
-
filter = None
|
27
|
-
lock = threading.Lock()
|
28
|
-
|
29
|
-
def __new__(cls, *args, **kwargs):
|
30
|
-
"""This magic turns this into a singleton."""
|
31
|
-
if cls._instance is None:
|
32
|
-
cls._instance = super().__new__(cls)
|
33
|
-
keepalive_collector.KeepAliveCollector().register(cls)
|
34
|
-
# Put any initialization here.
|
35
|
-
cls._instance._create_client()
|
36
|
-
return cls._instance
|
37
|
-
|
38
|
-
@abc.abstractmethod
|
39
|
-
def stats(self) -> dict:
|
40
|
-
"""Return statistics about the client connection.
|
41
|
-
|
42
|
-
Returns:
|
43
|
-
dict: Statistics about the connection and packet handling
|
44
|
-
"""
|
45
|
-
|
46
|
-
@abc.abstractmethod
|
47
|
-
def keepalive_check(self) -> None:
|
48
|
-
"""Called during keepalive run to check status."""
|
49
|
-
...
|
50
|
-
|
51
|
-
@abc.abstractmethod
|
52
|
-
def keepalive_log(self) -> None:
|
53
|
-
"""Log any keepalive information."""
|
54
|
-
...
|
55
|
-
|
56
|
-
@property
|
57
|
-
def is_connected(self):
|
58
|
-
return self.connected
|
59
|
-
|
60
|
-
@property
|
61
|
-
def login_success(self):
|
62
|
-
return self.login_status.get('success', False)
|
63
|
-
|
64
|
-
@property
|
65
|
-
def login_failure(self):
|
66
|
-
return self.login_status['message']
|
67
|
-
|
68
|
-
def set_filter(self, filter):
|
69
|
-
self.filter = filter
|
70
|
-
if self._client:
|
71
|
-
self._client.set_filter(filter)
|
72
|
-
|
73
|
-
def get_filter(self):
|
74
|
-
return self.filter
|
75
|
-
|
76
|
-
@property
|
77
|
-
def client(self):
|
78
|
-
if not self._client:
|
79
|
-
self._create_client()
|
80
|
-
return self._client
|
81
|
-
|
82
|
-
def _create_client(self):
|
83
|
-
try:
|
84
|
-
self._client = self.setup_connection()
|
85
|
-
if self.filter:
|
86
|
-
LOG.info('Creating APRS client filter')
|
87
|
-
self._client.set_filter(self.filter)
|
88
|
-
except Exception as e:
|
89
|
-
LOG.error(f'Failed to create APRS client: {e}')
|
90
|
-
self._client = None
|
91
|
-
raise
|
92
|
-
|
93
|
-
def stop(self):
|
94
|
-
if self._client:
|
95
|
-
LOG.info('Stopping client connection.')
|
96
|
-
self._client.stop()
|
97
|
-
|
98
|
-
def send(self, packet: core.Packet) -> None:
|
99
|
-
"""Send a packet to the network.
|
100
|
-
|
101
|
-
Args:
|
102
|
-
packet: The APRS packet to send
|
103
|
-
"""
|
104
|
-
self.client.send(packet)
|
105
|
-
|
106
|
-
@wrapt.synchronized(lock)
|
107
|
-
def reset(self) -> None:
|
108
|
-
"""Call this to force a rebuild/reconnect."""
|
109
|
-
LOG.info('Resetting client connection.')
|
110
|
-
if self._client:
|
111
|
-
self._client.close()
|
112
|
-
del self._client
|
113
|
-
self._create_client()
|
114
|
-
else:
|
115
|
-
LOG.warning('Client not initialized, nothing to reset.')
|
116
|
-
|
117
|
-
# Recreate the client
|
118
|
-
LOG.info(f'Creating new client {self.client}')
|
119
|
-
|
120
|
-
@abc.abstractmethod
|
121
|
-
def setup_connection(self):
|
122
|
-
"""Initialize and return the underlying APRS connection.
|
123
|
-
|
124
|
-
Returns:
|
125
|
-
object: The initialized connection object
|
126
|
-
"""
|
127
|
-
|
128
|
-
@staticmethod
|
129
|
-
@abc.abstractmethod
|
130
|
-
def is_enabled():
|
131
|
-
pass
|
132
|
-
|
133
|
-
@staticmethod
|
134
|
-
@abc.abstractmethod
|
135
|
-
def transport():
|
136
|
-
pass
|
137
|
-
|
138
|
-
@abc.abstractmethod
|
139
|
-
def decode_packet(self, *args, **kwargs):
|
140
|
-
"""Decode raw APRS packet data into a Packet object.
|
141
|
-
|
142
|
-
Returns:
|
143
|
-
Packet: Decoded APRS packet
|
144
|
-
"""
|
145
|
-
|
146
|
-
@abc.abstractmethod
|
147
|
-
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
148
|
-
pass
|
149
|
-
|
150
|
-
@abc.abstractmethod
|
151
|
-
def is_alive(self):
|
152
|
-
pass
|
153
|
-
|
154
|
-
@abc.abstractmethod
|
155
|
-
def close(self):
|
156
|
-
pass
|
aprsd/client/drivers/kiss.py
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
import datetime
|
2
|
-
import logging
|
3
|
-
|
4
|
-
import kiss
|
5
|
-
from ax253 import Frame
|
6
|
-
from oslo_config import cfg
|
7
|
-
|
8
|
-
from aprsd import conf # noqa
|
9
|
-
from aprsd.packets import core
|
10
|
-
from aprsd.utils import trace
|
11
|
-
|
12
|
-
CONF = cfg.CONF
|
13
|
-
LOG = logging.getLogger('APRSD')
|
14
|
-
|
15
|
-
|
16
|
-
class KISS3Client:
|
17
|
-
path = []
|
18
|
-
|
19
|
-
# date for last time we heard from the server
|
20
|
-
aprsd_keepalive = datetime.datetime.now()
|
21
|
-
_connected = False
|
22
|
-
|
23
|
-
def __init__(self):
|
24
|
-
self.setup()
|
25
|
-
|
26
|
-
def is_alive(self):
|
27
|
-
return self._connected
|
28
|
-
|
29
|
-
def setup(self):
|
30
|
-
# we can be TCP kiss or Serial kiss
|
31
|
-
if CONF.kiss_serial.enabled:
|
32
|
-
LOG.debug(
|
33
|
-
'KISS({}) Serial connection to {}'.format(
|
34
|
-
kiss.__version__,
|
35
|
-
CONF.kiss_serial.device,
|
36
|
-
),
|
37
|
-
)
|
38
|
-
self.kiss = kiss.SerialKISS(
|
39
|
-
port=CONF.kiss_serial.device,
|
40
|
-
speed=CONF.kiss_serial.baudrate,
|
41
|
-
strip_df_start=True,
|
42
|
-
)
|
43
|
-
self.path = CONF.kiss_serial.path
|
44
|
-
elif CONF.kiss_tcp.enabled:
|
45
|
-
LOG.debug(
|
46
|
-
'KISS({}) TCP Connection to {}:{}'.format(
|
47
|
-
kiss.__version__,
|
48
|
-
CONF.kiss_tcp.host,
|
49
|
-
CONF.kiss_tcp.port,
|
50
|
-
),
|
51
|
-
)
|
52
|
-
self.kiss = kiss.TCPKISS(
|
53
|
-
host=CONF.kiss_tcp.host,
|
54
|
-
port=CONF.kiss_tcp.port,
|
55
|
-
strip_df_start=True,
|
56
|
-
)
|
57
|
-
self.path = CONF.kiss_tcp.path
|
58
|
-
|
59
|
-
LOG.debug('Starting KISS interface connection')
|
60
|
-
try:
|
61
|
-
self.kiss.start()
|
62
|
-
if self.kiss.protocol.transport.is_closing():
|
63
|
-
LOG.warning('KISS transport is closing, not setting consumer callback')
|
64
|
-
self._connected = False
|
65
|
-
else:
|
66
|
-
self._connected = True
|
67
|
-
except Exception:
|
68
|
-
LOG.error('Failed to start KISS interface.')
|
69
|
-
self._connected = False
|
70
|
-
|
71
|
-
@trace.trace
|
72
|
-
def stop(self):
|
73
|
-
if not self._connected:
|
74
|
-
# do nothing since we aren't connected
|
75
|
-
return
|
76
|
-
|
77
|
-
try:
|
78
|
-
self.kiss.stop()
|
79
|
-
self.kiss.loop.call_soon_threadsafe(
|
80
|
-
self.kiss.protocol.transport.close,
|
81
|
-
)
|
82
|
-
except Exception:
|
83
|
-
LOG.error('Failed to stop KISS interface.')
|
84
|
-
|
85
|
-
def close(self):
|
86
|
-
self.stop()
|
87
|
-
|
88
|
-
def set_filter(self, filter):
|
89
|
-
# This does nothing right now.
|
90
|
-
pass
|
91
|
-
|
92
|
-
def parse_frame(self, frame_bytes):
|
93
|
-
try:
|
94
|
-
frame = Frame.from_bytes(frame_bytes)
|
95
|
-
# Now parse it with aprslib
|
96
|
-
kwargs = {
|
97
|
-
'frame': frame,
|
98
|
-
}
|
99
|
-
self._parse_callback(**kwargs)
|
100
|
-
self.aprsd_keepalive = datetime.datetime.now()
|
101
|
-
except Exception as ex:
|
102
|
-
LOG.error('Failed to parse bytes received from KISS interface.')
|
103
|
-
LOG.exception(ex)
|
104
|
-
|
105
|
-
def consumer(self, callback):
|
106
|
-
if not self._connected:
|
107
|
-
raise Exception('KISS transport is not connected')
|
108
|
-
|
109
|
-
self._parse_callback = callback
|
110
|
-
if not self.kiss.protocol.transport.is_closing():
|
111
|
-
self.kiss.read(callback=self.parse_frame, min_frames=1)
|
112
|
-
else:
|
113
|
-
self._connected = False
|
114
|
-
|
115
|
-
def send(self, packet):
|
116
|
-
"""Send an APRS Message object."""
|
117
|
-
|
118
|
-
payload = None
|
119
|
-
path = self.path
|
120
|
-
if isinstance(packet, core.Packet):
|
121
|
-
packet.prepare()
|
122
|
-
payload = packet.payload.encode('US-ASCII')
|
123
|
-
if packet.path:
|
124
|
-
path = packet.path
|
125
|
-
else:
|
126
|
-
msg_payload = f'{packet.raw}{{{str(packet.msgNo)}'
|
127
|
-
payload = (
|
128
|
-
':{:<9}:{}'.format(
|
129
|
-
packet.to_call,
|
130
|
-
msg_payload,
|
131
|
-
)
|
132
|
-
).encode('US-ASCII')
|
133
|
-
|
134
|
-
LOG.debug(
|
135
|
-
f"KISS Send '{payload}' TO '{packet.to_call}' From "
|
136
|
-
f"'{packet.from_call}' with PATH '{path}'",
|
137
|
-
)
|
138
|
-
frame = Frame.ui(
|
139
|
-
destination='APZ100',
|
140
|
-
source=packet.from_call,
|
141
|
-
path=path,
|
142
|
-
info=payload,
|
143
|
-
)
|
144
|
-
self.kiss.write(frame)
|
aprsd/client/factory.py
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
from typing import Callable, Protocol, runtime_checkable
|
3
|
-
|
4
|
-
from aprsd import exception
|
5
|
-
from aprsd.packets import core
|
6
|
-
|
7
|
-
LOG = logging.getLogger("APRSD")
|
8
|
-
|
9
|
-
|
10
|
-
@runtime_checkable
|
11
|
-
class Client(Protocol):
|
12
|
-
def __init__(self):
|
13
|
-
pass
|
14
|
-
|
15
|
-
def connect(self) -> bool:
|
16
|
-
pass
|
17
|
-
|
18
|
-
def disconnect(self) -> bool:
|
19
|
-
pass
|
20
|
-
|
21
|
-
def decode_packet(self, *args, **kwargs) -> type[core.Packet]:
|
22
|
-
pass
|
23
|
-
|
24
|
-
def is_enabled(self) -> bool:
|
25
|
-
pass
|
26
|
-
|
27
|
-
def is_configured(self) -> bool:
|
28
|
-
pass
|
29
|
-
|
30
|
-
def transport(self) -> str:
|
31
|
-
pass
|
32
|
-
|
33
|
-
def send(self, message: str) -> bool:
|
34
|
-
pass
|
35
|
-
|
36
|
-
def setup_connection(self) -> None:
|
37
|
-
pass
|
38
|
-
|
39
|
-
|
40
|
-
class ClientFactory:
|
41
|
-
_instance = None
|
42
|
-
clients = []
|
43
|
-
client = None
|
44
|
-
|
45
|
-
def __new__(cls, *args, **kwargs):
|
46
|
-
"""This magic turns this into a singleton."""
|
47
|
-
if cls._instance is None:
|
48
|
-
cls._instance = super().__new__(cls)
|
49
|
-
# Put any initialization here.
|
50
|
-
return cls._instance
|
51
|
-
|
52
|
-
def __init__(self):
|
53
|
-
self.clients: list[Callable] = []
|
54
|
-
|
55
|
-
def register(self, aprsd_client: Callable):
|
56
|
-
if isinstance(aprsd_client, Client):
|
57
|
-
raise ValueError("Client must be a subclass of Client protocol")
|
58
|
-
|
59
|
-
self.clients.append(aprsd_client)
|
60
|
-
|
61
|
-
def create(self, key=None):
|
62
|
-
for client in self.clients:
|
63
|
-
if client.is_enabled():
|
64
|
-
self.client = client()
|
65
|
-
return self.client
|
66
|
-
raise Exception("No client is configured!!")
|
67
|
-
|
68
|
-
def client_exists(self):
|
69
|
-
return bool(self.client)
|
70
|
-
|
71
|
-
def is_client_enabled(self):
|
72
|
-
"""Make sure at least one client is enabled."""
|
73
|
-
enabled = False
|
74
|
-
for client in self.clients:
|
75
|
-
if client.is_enabled():
|
76
|
-
enabled = True
|
77
|
-
return enabled
|
78
|
-
|
79
|
-
def is_client_configured(self):
|
80
|
-
enabled = False
|
81
|
-
for client in self.clients:
|
82
|
-
try:
|
83
|
-
if client.is_configured():
|
84
|
-
enabled = True
|
85
|
-
except exception.MissingConfigOptionException as ex:
|
86
|
-
LOG.error(ex.message)
|
87
|
-
return False
|
88
|
-
except exception.ConfigOptionBogusDefaultException as ex:
|
89
|
-
LOG.error(ex.message)
|
90
|
-
return False
|
91
|
-
return enabled
|
aprsd/client/fake.py
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
|
3
|
-
from oslo_config import cfg
|
4
|
-
|
5
|
-
from aprsd import client
|
6
|
-
from aprsd.client import base
|
7
|
-
from aprsd.client.drivers import fake as fake_driver
|
8
|
-
from aprsd.utils import trace
|
9
|
-
|
10
|
-
CONF = cfg.CONF
|
11
|
-
LOG = logging.getLogger("APRSD")
|
12
|
-
|
13
|
-
|
14
|
-
class APRSDFakeClient(base.APRSClient, metaclass=trace.TraceWrapperMetaclass):
|
15
|
-
def stats(self, serializable=False) -> dict:
|
16
|
-
return {
|
17
|
-
"transport": "Fake",
|
18
|
-
"connected": True,
|
19
|
-
}
|
20
|
-
|
21
|
-
@staticmethod
|
22
|
-
def is_enabled():
|
23
|
-
if CONF.fake_client.enabled:
|
24
|
-
return True
|
25
|
-
return False
|
26
|
-
|
27
|
-
@staticmethod
|
28
|
-
def is_configured():
|
29
|
-
return APRSDFakeClient.is_enabled()
|
30
|
-
|
31
|
-
def is_alive(self):
|
32
|
-
return True
|
33
|
-
|
34
|
-
def close(self):
|
35
|
-
pass
|
36
|
-
|
37
|
-
def setup_connection(self):
|
38
|
-
self.connected = True
|
39
|
-
return fake_driver.APRSDFakeClient()
|
40
|
-
|
41
|
-
@staticmethod
|
42
|
-
def transport():
|
43
|
-
return client.TRANSPORT_FAKE
|
44
|
-
|
45
|
-
def decode_packet(self, *args, **kwargs):
|
46
|
-
LOG.debug(f"kwargs {kwargs}")
|
47
|
-
pkt = kwargs["packet"]
|
48
|
-
LOG.debug(f"Got an APRS Fake Packet '{pkt}'")
|
49
|
-
return pkt
|
aprsd/client/kiss.py
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
import datetime
|
2
|
-
import logging
|
3
|
-
|
4
|
-
import aprslib
|
5
|
-
import timeago
|
6
|
-
from loguru import logger
|
7
|
-
from oslo_config import cfg
|
8
|
-
|
9
|
-
from aprsd import client, exception
|
10
|
-
from aprsd.client import base
|
11
|
-
from aprsd.client.drivers import kiss
|
12
|
-
from aprsd.packets import core
|
13
|
-
|
14
|
-
CONF = cfg.CONF
|
15
|
-
LOG = logging.getLogger('APRSD')
|
16
|
-
LOGU = logger
|
17
|
-
|
18
|
-
|
19
|
-
class KISSClient(base.APRSClient):
|
20
|
-
_client = None
|
21
|
-
keepalive = datetime.datetime.now()
|
22
|
-
|
23
|
-
def stats(self, serializable=False) -> dict:
|
24
|
-
stats = {}
|
25
|
-
if self.is_configured():
|
26
|
-
keepalive = self.keepalive
|
27
|
-
if serializable:
|
28
|
-
keepalive = keepalive.isoformat()
|
29
|
-
stats = {
|
30
|
-
'connected': self.is_connected,
|
31
|
-
'connection_keepalive': keepalive,
|
32
|
-
'transport': self.transport(),
|
33
|
-
}
|
34
|
-
if self.transport() == client.TRANSPORT_TCPKISS:
|
35
|
-
stats['host'] = CONF.kiss_tcp.host
|
36
|
-
stats['port'] = CONF.kiss_tcp.port
|
37
|
-
elif self.transport() == client.TRANSPORT_SERIALKISS:
|
38
|
-
stats['device'] = CONF.kiss_serial.device
|
39
|
-
return stats
|
40
|
-
|
41
|
-
@staticmethod
|
42
|
-
def is_enabled():
|
43
|
-
"""Return if tcp or serial KISS is enabled."""
|
44
|
-
if CONF.kiss_serial.enabled:
|
45
|
-
return True
|
46
|
-
|
47
|
-
if CONF.kiss_tcp.enabled:
|
48
|
-
return True
|
49
|
-
|
50
|
-
return False
|
51
|
-
|
52
|
-
@staticmethod
|
53
|
-
def is_configured():
|
54
|
-
# Ensure that the config vars are correctly set
|
55
|
-
if KISSClient.is_enabled():
|
56
|
-
transport = KISSClient.transport()
|
57
|
-
if transport == client.TRANSPORT_SERIALKISS:
|
58
|
-
if not CONF.kiss_serial.device:
|
59
|
-
LOG.error('KISS serial enabled, but no device is set.')
|
60
|
-
raise exception.MissingConfigOptionException(
|
61
|
-
'kiss_serial.device is not set.',
|
62
|
-
)
|
63
|
-
elif transport == client.TRANSPORT_TCPKISS:
|
64
|
-
if not CONF.kiss_tcp.host:
|
65
|
-
LOG.error('KISS TCP enabled, but no host is set.')
|
66
|
-
raise exception.MissingConfigOptionException(
|
67
|
-
'kiss_tcp.host is not set.',
|
68
|
-
)
|
69
|
-
|
70
|
-
return True
|
71
|
-
return False
|
72
|
-
|
73
|
-
def is_alive(self):
|
74
|
-
if self._client:
|
75
|
-
return self._client.is_alive()
|
76
|
-
else:
|
77
|
-
return False
|
78
|
-
|
79
|
-
def close(self):
|
80
|
-
if self._client:
|
81
|
-
self._client.stop()
|
82
|
-
|
83
|
-
def keepalive_check(self):
|
84
|
-
# Don't check the first time through.
|
85
|
-
if not self.is_alive() and self._checks:
|
86
|
-
LOG.warning("Resetting client. It's not alive.")
|
87
|
-
self.reset()
|
88
|
-
self._checks = True
|
89
|
-
|
90
|
-
def keepalive_log(self):
|
91
|
-
if ka := self._client.aprsd_keepalive:
|
92
|
-
keepalive = timeago.format(ka)
|
93
|
-
else:
|
94
|
-
keepalive = 'N/A'
|
95
|
-
LOGU.opt(colors=True).info(f'<green>Client keepalive {keepalive}</green>')
|
96
|
-
|
97
|
-
@staticmethod
|
98
|
-
def transport():
|
99
|
-
if CONF.kiss_serial.enabled:
|
100
|
-
return client.TRANSPORT_SERIALKISS
|
101
|
-
|
102
|
-
if CONF.kiss_tcp.enabled:
|
103
|
-
return client.TRANSPORT_TCPKISS
|
104
|
-
|
105
|
-
def decode_packet(self, *args, **kwargs):
|
106
|
-
"""We get a frame, which has to be decoded."""
|
107
|
-
LOG.debug(f'kwargs {kwargs}')
|
108
|
-
frame = kwargs['frame']
|
109
|
-
LOG.debug(f"Got an APRS Frame '{frame}'")
|
110
|
-
# try and nuke the * from the fromcall sign.
|
111
|
-
# frame.header._source._ch = False
|
112
|
-
# payload = str(frame.payload.decode())
|
113
|
-
# msg = f"{str(frame.header)}:{payload}"
|
114
|
-
# msg = frame.tnc2
|
115
|
-
# LOG.debug(f"Decoding {msg}")
|
116
|
-
|
117
|
-
try:
|
118
|
-
raw = aprslib.parse(str(frame))
|
119
|
-
packet = core.factory(raw)
|
120
|
-
if isinstance(packet, core.ThirdPartyPacket):
|
121
|
-
return packet.subpacket
|
122
|
-
else:
|
123
|
-
return packet
|
124
|
-
except Exception as ex:
|
125
|
-
LOG.error(f'Error decoding packet: {ex}')
|
126
|
-
|
127
|
-
def setup_connection(self):
|
128
|
-
try:
|
129
|
-
self._client = kiss.KISS3Client()
|
130
|
-
self.connected = self.login_status['success'] = True
|
131
|
-
except Exception as ex:
|
132
|
-
self.connected = self.login_status['success'] = False
|
133
|
-
self.login_status['message'] = str(ex)
|
134
|
-
return self._client
|
135
|
-
|
136
|
-
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
137
|
-
try:
|
138
|
-
self._client.consumer(callback)
|
139
|
-
self.keepalive = datetime.datetime.now()
|
140
|
-
except Exception as ex:
|
141
|
-
LOG.error(f'Consumer failed {ex}')
|
142
|
-
LOG.error(ex)
|
143
|
-
raise ex
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|