aprsd 4.0.1__py3-none-any.whl → 4.1.0__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/drivers/aprsis.py +87 -35
- aprsd/client/drivers/fake.py +5 -0
- aprsd/client/drivers/kiss.py +45 -20
- aprsd/client/kiss.py +29 -25
- aprsd/cmds/listen.py +84 -91
- aprsd/cmds/server.py +1 -1
- aprsd/conf/common.py +100 -101
- aprsd/conf/log.py +27 -22
- aprsd/log/log.py +24 -14
- aprsd/packets/__init__.py +6 -0
- aprsd/packets/core.py +5 -2
- aprsd/packets/filter.py +58 -0
- aprsd/packets/filters/__init__.py +0 -0
- aprsd/packets/filters/dupe_filter.py +68 -0
- aprsd/packets/filters/packet_type.py +53 -0
- aprsd/packets/packet_list.py +33 -27
- aprsd/plugins/fortune.py +21 -15
- aprsd/threads/__init__.py +1 -2
- aprsd/threads/rx.py +83 -75
- aprsd/threads/stats.py +4 -9
- aprsd/utils/objectstore.py +12 -13
- {aprsd-4.0.1.dist-info → aprsd-4.1.0.dist-info}/METADATA +1 -1
- {aprsd-4.0.1.dist-info → aprsd-4.1.0.dist-info}/RECORD +28 -24
- {aprsd-4.0.1.dist-info → aprsd-4.1.0.dist-info}/AUTHORS +0 -0
- {aprsd-4.0.1.dist-info → aprsd-4.1.0.dist-info}/LICENSE +0 -0
- {aprsd-4.0.1.dist-info → aprsd-4.1.0.dist-info}/WHEEL +0 -0
- {aprsd-4.0.1.dist-info → aprsd-4.1.0.dist-info}/entry_points.txt +0 -0
- {aprsd-4.0.1.dist-info → aprsd-4.1.0.dist-info}/top_level.txt +0 -0
aprsd/client/drivers/aprsis.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import datetime
|
2
2
|
import logging
|
3
3
|
import select
|
4
|
+
import socket
|
4
5
|
import threading
|
5
6
|
|
6
7
|
import aprslib
|
@@ -18,7 +19,7 @@ from aprslib.exceptions import (
|
|
18
19
|
import aprsd
|
19
20
|
from aprsd.packets import core
|
20
21
|
|
21
|
-
LOG = logging.getLogger(
|
22
|
+
LOG = logging.getLogger('APRSD')
|
22
23
|
|
23
24
|
|
24
25
|
class Aprsdis(aprslib.IS):
|
@@ -31,7 +32,7 @@ class Aprsdis(aprslib.IS):
|
|
31
32
|
aprsd_keepalive = datetime.datetime.now()
|
32
33
|
|
33
34
|
# Which server we are connected to?
|
34
|
-
server_string =
|
35
|
+
server_string = 'None'
|
35
36
|
|
36
37
|
# timeout in seconds
|
37
38
|
select_timeout = 1
|
@@ -39,10 +40,10 @@ class Aprsdis(aprslib.IS):
|
|
39
40
|
|
40
41
|
def stop(self):
|
41
42
|
self.thread_stop = True
|
42
|
-
LOG.warning(
|
43
|
+
LOG.warning('Shutdown Aprsdis client.')
|
43
44
|
|
44
45
|
def close(self):
|
45
|
-
LOG.warning(
|
46
|
+
LOG.warning('Closing Aprsdis client.')
|
46
47
|
super().close()
|
47
48
|
|
48
49
|
@wrapt.synchronized(lock)
|
@@ -54,6 +55,57 @@ class Aprsdis(aprslib.IS):
|
|
54
55
|
"""If the connection is alive or not."""
|
55
56
|
return self._connected
|
56
57
|
|
58
|
+
def _connect(self):
|
59
|
+
"""
|
60
|
+
Attemps connection to the server
|
61
|
+
"""
|
62
|
+
|
63
|
+
self.logger.info(
|
64
|
+
'Attempting connection to %s:%s', self.server[0], self.server[1]
|
65
|
+
)
|
66
|
+
|
67
|
+
try:
|
68
|
+
self._open_socket()
|
69
|
+
|
70
|
+
peer = self.sock.getpeername()
|
71
|
+
|
72
|
+
self.logger.info('Connected to %s', str(peer))
|
73
|
+
|
74
|
+
# 5 second timeout to receive server banner
|
75
|
+
self.sock.setblocking(1)
|
76
|
+
self.sock.settimeout(5)
|
77
|
+
|
78
|
+
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
79
|
+
# MACOS doesn't have TCP_KEEPIDLE
|
80
|
+
if hasattr(socket, 'TCP_KEEPIDLE'):
|
81
|
+
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1)
|
82
|
+
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 3)
|
83
|
+
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
|
84
|
+
|
85
|
+
banner = self.sock.recv(512)
|
86
|
+
if is_py3:
|
87
|
+
banner = banner.decode('latin-1')
|
88
|
+
|
89
|
+
if banner[0] == '#':
|
90
|
+
self.logger.debug('Banner: %s', banner.rstrip())
|
91
|
+
else:
|
92
|
+
raise ConnectionError('invalid banner from server')
|
93
|
+
|
94
|
+
except ConnectionError as e:
|
95
|
+
self.logger.error(str(e))
|
96
|
+
self.close()
|
97
|
+
raise
|
98
|
+
except (socket.error, socket.timeout) as e:
|
99
|
+
self.close()
|
100
|
+
|
101
|
+
self.logger.error('Socket error: %s' % str(e))
|
102
|
+
if str(e) == 'timed out':
|
103
|
+
raise ConnectionError('no banner from server') from e
|
104
|
+
else:
|
105
|
+
raise ConnectionError(e) from e
|
106
|
+
|
107
|
+
self._connected = True
|
108
|
+
|
57
109
|
def _socket_readlines(self, blocking=False):
|
58
110
|
"""
|
59
111
|
Generator for complete lines, received from the server
|
@@ -61,12 +113,12 @@ class Aprsdis(aprslib.IS):
|
|
61
113
|
try:
|
62
114
|
self.sock.setblocking(0)
|
63
115
|
except OSError as e:
|
64
|
-
self.logger.error(f
|
65
|
-
raise aprslib.ConnectionDrop(
|
116
|
+
self.logger.error(f'socket error when setblocking(0): {str(e)}')
|
117
|
+
raise aprslib.ConnectionDrop('connection dropped') from e
|
66
118
|
|
67
119
|
while not self.thread_stop:
|
68
|
-
short_buf = b
|
69
|
-
newline = b
|
120
|
+
short_buf = b''
|
121
|
+
newline = b'\r\n'
|
70
122
|
|
71
123
|
# set a select timeout, so we get a chance to exit
|
72
124
|
# when user hits CTRL-C
|
@@ -91,11 +143,11 @@ class Aprsdis(aprslib.IS):
|
|
91
143
|
# We could just not be blocking, so empty is expected
|
92
144
|
continue
|
93
145
|
else:
|
94
|
-
self.logger.error(
|
95
|
-
raise aprslib.ConnectionDrop(
|
146
|
+
self.logger.error('socket.recv(): returned empty')
|
147
|
+
raise aprslib.ConnectionDrop('connection dropped')
|
96
148
|
except OSError as e:
|
97
149
|
# self.logger.error("socket error on recv(): %s" % str(e))
|
98
|
-
if
|
150
|
+
if 'Resource temporarily unavailable' in str(e):
|
99
151
|
if not blocking:
|
100
152
|
if len(self.buf) == 0:
|
101
153
|
break
|
@@ -111,22 +163,22 @@ class Aprsdis(aprslib.IS):
|
|
111
163
|
"""
|
112
164
|
Sends login string to server
|
113
165
|
"""
|
114
|
-
login_str =
|
166
|
+
login_str = 'user {0} pass {1} vers Python-APRSD {3}{2}\r\n'
|
115
167
|
login_str = login_str.format(
|
116
168
|
self.callsign,
|
117
169
|
self.passwd,
|
118
|
-
(
|
170
|
+
(' filter ' + self.filter) if self.filter != '' else '',
|
119
171
|
aprsd.__version__,
|
120
172
|
)
|
121
173
|
|
122
|
-
self.logger.debug(
|
174
|
+
self.logger.debug('Sending login information')
|
123
175
|
|
124
176
|
try:
|
125
177
|
self._sendall(login_str)
|
126
178
|
self.sock.settimeout(5)
|
127
179
|
test = self.sock.recv(len(login_str) + 100)
|
128
180
|
if is_py3:
|
129
|
-
test = test.decode(
|
181
|
+
test = test.decode('latin-1')
|
130
182
|
test = test.rstrip()
|
131
183
|
|
132
184
|
self.logger.debug("Server: '%s'", test)
|
@@ -134,26 +186,26 @@ class Aprsdis(aprslib.IS):
|
|
134
186
|
if not test:
|
135
187
|
raise LoginError(f"Server Response Empty: '{test}'")
|
136
188
|
|
137
|
-
_, _, callsign, status, e = test.split(
|
138
|
-
s = e.split(
|
189
|
+
_, _, callsign, status, e = test.split(' ', 4)
|
190
|
+
s = e.split(',')
|
139
191
|
if len(s):
|
140
|
-
server_string = s[0].replace(
|
192
|
+
server_string = s[0].replace('server ', '')
|
141
193
|
else:
|
142
|
-
server_string = e.replace(
|
194
|
+
server_string = e.replace('server ', '')
|
143
195
|
|
144
|
-
if callsign ==
|
145
|
-
raise LoginError(
|
196
|
+
if callsign == '':
|
197
|
+
raise LoginError('Server responded with empty callsign???')
|
146
198
|
if callsign != self.callsign:
|
147
|
-
raise LoginError(f
|
148
|
-
if status !=
|
149
|
-
raise LoginError(
|
199
|
+
raise LoginError(f'Server: {test}')
|
200
|
+
if status != 'verified,' and self.passwd != '-1':
|
201
|
+
raise LoginError('Password is incorrect')
|
150
202
|
|
151
|
-
if self.passwd ==
|
152
|
-
self.logger.info(
|
203
|
+
if self.passwd == '-1':
|
204
|
+
self.logger.info('Login successful (receive only)')
|
153
205
|
else:
|
154
|
-
self.logger.info(
|
206
|
+
self.logger.info('Login successful')
|
155
207
|
|
156
|
-
self.logger.info(f
|
208
|
+
self.logger.info(f'Connected to {server_string}')
|
157
209
|
self.server_string = server_string
|
158
210
|
|
159
211
|
except LoginError as e:
|
@@ -164,7 +216,7 @@ class Aprsdis(aprslib.IS):
|
|
164
216
|
self.close()
|
165
217
|
self.logger.error(f"Failed to login '{e}'")
|
166
218
|
self.logger.exception(e)
|
167
|
-
raise LoginError(
|
219
|
+
raise LoginError('Failed to login') from e
|
168
220
|
|
169
221
|
def consumer(self, callback, blocking=True, immortal=False, raw=False):
|
170
222
|
"""
|
@@ -180,21 +232,21 @@ class Aprsdis(aprslib.IS):
|
|
180
232
|
"""
|
181
233
|
|
182
234
|
if not self._connected:
|
183
|
-
raise ConnectionError(
|
235
|
+
raise ConnectionError('not connected to a server')
|
184
236
|
|
185
|
-
line = b
|
237
|
+
line = b''
|
186
238
|
|
187
239
|
while True and not self.thread_stop:
|
188
240
|
try:
|
189
241
|
for line in self._socket_readlines(blocking):
|
190
|
-
if line[0:1] != b
|
242
|
+
if line[0:1] != b'#':
|
191
243
|
self.aprsd_keepalive = datetime.datetime.now()
|
192
244
|
if raw:
|
193
245
|
callback(line)
|
194
246
|
else:
|
195
247
|
callback(self._parse(line))
|
196
248
|
else:
|
197
|
-
self.logger.debug(
|
249
|
+
self.logger.debug('Server: %s', line.decode('utf8'))
|
198
250
|
self.aprsd_keepalive = datetime.datetime.now()
|
199
251
|
except ParseError as exp:
|
200
252
|
self.logger.log(
|
@@ -211,7 +263,7 @@ class Aprsdis(aprslib.IS):
|
|
211
263
|
exp.packet,
|
212
264
|
)
|
213
265
|
except LoginError as exp:
|
214
|
-
self.logger.error(
|
266
|
+
self.logger.error('%s: %s', exp.__class__.__name__, exp)
|
215
267
|
except (KeyboardInterrupt, SystemExit):
|
216
268
|
raise
|
217
269
|
except (ConnectionDrop, ConnectionError):
|
@@ -227,7 +279,7 @@ class Aprsdis(aprslib.IS):
|
|
227
279
|
except StopIteration:
|
228
280
|
break
|
229
281
|
except Exception:
|
230
|
-
self.logger.error(
|
282
|
+
self.logger.error('APRS Packet: %s', line)
|
231
283
|
raise
|
232
284
|
|
233
285
|
if not blocking:
|
aprsd/client/drivers/fake.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import datetime
|
1
2
|
import logging
|
2
3
|
import threading
|
3
4
|
import time
|
@@ -20,6 +21,9 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
|
|
20
21
|
# flag to tell us to stop
|
21
22
|
thread_stop = False
|
22
23
|
|
24
|
+
# date for last time we heard from the server
|
25
|
+
aprsd_keepalive = datetime.datetime.now()
|
26
|
+
|
23
27
|
lock = threading.Lock()
|
24
28
|
path = []
|
25
29
|
|
@@ -63,6 +67,7 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
|
|
63
67
|
raw = 'GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW'
|
64
68
|
pkt_raw = aprslib.parse(raw)
|
65
69
|
pkt = core.factory(pkt_raw)
|
70
|
+
self.aprsd_keepalive = datetime.datetime.now()
|
66
71
|
callback(packet=pkt)
|
67
72
|
LOG.debug(f'END blocking FAKE consumer {self}')
|
68
73
|
time.sleep(8)
|
aprsd/client/drivers/kiss.py
CHANGED
@@ -1,32 +1,36 @@
|
|
1
|
+
import datetime
|
1
2
|
import logging
|
2
3
|
|
3
|
-
from ax253 import Frame
|
4
4
|
import kiss
|
5
|
+
from ax253 import Frame
|
5
6
|
from oslo_config import cfg
|
6
7
|
|
7
8
|
from aprsd import conf # noqa
|
8
9
|
from aprsd.packets import core
|
9
10
|
from aprsd.utils import trace
|
10
11
|
|
11
|
-
|
12
12
|
CONF = cfg.CONF
|
13
|
-
LOG = logging.getLogger(
|
13
|
+
LOG = logging.getLogger('APRSD')
|
14
14
|
|
15
15
|
|
16
16
|
class KISS3Client:
|
17
17
|
path = []
|
18
18
|
|
19
|
+
# date for last time we heard from the server
|
20
|
+
aprsd_keepalive = datetime.datetime.now()
|
21
|
+
_connected = False
|
22
|
+
|
19
23
|
def __init__(self):
|
20
24
|
self.setup()
|
21
25
|
|
22
26
|
def is_alive(self):
|
23
|
-
return
|
27
|
+
return self._connected
|
24
28
|
|
25
29
|
def setup(self):
|
26
30
|
# we can be TCP kiss or Serial kiss
|
27
31
|
if CONF.kiss_serial.enabled:
|
28
32
|
LOG.debug(
|
29
|
-
|
33
|
+
'KISS({}) Serial connection to {}'.format(
|
30
34
|
kiss.__version__,
|
31
35
|
CONF.kiss_serial.device,
|
32
36
|
),
|
@@ -39,7 +43,7 @@ class KISS3Client:
|
|
39
43
|
self.path = CONF.kiss_serial.path
|
40
44
|
elif CONF.kiss_tcp.enabled:
|
41
45
|
LOG.debug(
|
42
|
-
|
46
|
+
'KISS({}) TCP Connection to {}:{}'.format(
|
43
47
|
kiss.__version__,
|
44
48
|
CONF.kiss_tcp.host,
|
45
49
|
CONF.kiss_tcp.port,
|
@@ -52,18 +56,34 @@ class KISS3Client:
|
|
52
56
|
)
|
53
57
|
self.path = CONF.kiss_tcp.path
|
54
58
|
|
55
|
-
LOG.debug(
|
56
|
-
|
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
|
57
70
|
|
58
71
|
@trace.trace
|
59
72
|
def stop(self):
|
73
|
+
if not self._connected:
|
74
|
+
# do nothing since we aren't connected
|
75
|
+
return
|
76
|
+
|
60
77
|
try:
|
61
78
|
self.kiss.stop()
|
62
79
|
self.kiss.loop.call_soon_threadsafe(
|
63
80
|
self.kiss.protocol.transport.close,
|
64
81
|
)
|
65
|
-
except Exception
|
66
|
-
LOG.
|
82
|
+
except Exception:
|
83
|
+
LOG.error('Failed to stop KISS interface.')
|
84
|
+
|
85
|
+
def close(self):
|
86
|
+
self.stop()
|
67
87
|
|
68
88
|
def set_filter(self, filter):
|
69
89
|
# This does nothing right now.
|
@@ -74,18 +94,23 @@ class KISS3Client:
|
|
74
94
|
frame = Frame.from_bytes(frame_bytes)
|
75
95
|
# Now parse it with aprslib
|
76
96
|
kwargs = {
|
77
|
-
|
97
|
+
'frame': frame,
|
78
98
|
}
|
79
99
|
self._parse_callback(**kwargs)
|
100
|
+
self.aprsd_keepalive = datetime.datetime.now()
|
80
101
|
except Exception as ex:
|
81
|
-
LOG.error(
|
102
|
+
LOG.error('Failed to parse bytes received from KISS interface.')
|
82
103
|
LOG.exception(ex)
|
83
104
|
|
84
105
|
def consumer(self, callback):
|
85
|
-
|
106
|
+
if not self._connected:
|
107
|
+
raise Exception('KISS transport is not connected')
|
108
|
+
|
86
109
|
self._parse_callback = callback
|
87
|
-
self.kiss.
|
88
|
-
|
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
|
89
114
|
|
90
115
|
def send(self, packet):
|
91
116
|
"""Send an APRS Message object."""
|
@@ -94,24 +119,24 @@ class KISS3Client:
|
|
94
119
|
path = self.path
|
95
120
|
if isinstance(packet, core.Packet):
|
96
121
|
packet.prepare()
|
97
|
-
payload = packet.payload.encode(
|
122
|
+
payload = packet.payload.encode('US-ASCII')
|
98
123
|
if packet.path:
|
99
124
|
path = packet.path
|
100
125
|
else:
|
101
|
-
msg_payload = f
|
126
|
+
msg_payload = f'{packet.raw}{{{str(packet.msgNo)}'
|
102
127
|
payload = (
|
103
|
-
|
128
|
+
':{:<9}:{}'.format(
|
104
129
|
packet.to_call,
|
105
130
|
msg_payload,
|
106
131
|
)
|
107
|
-
).encode(
|
132
|
+
).encode('US-ASCII')
|
108
133
|
|
109
134
|
LOG.debug(
|
110
135
|
f"KISS Send '{payload}' TO '{packet.to_call}' From "
|
111
136
|
f"'{packet.from_call}' with PATH '{path}'",
|
112
137
|
)
|
113
138
|
frame = Frame.ui(
|
114
|
-
destination=
|
139
|
+
destination='APZ100',
|
115
140
|
source=packet.from_call,
|
116
141
|
path=path,
|
117
142
|
info=payload,
|
aprsd/client/kiss.py
CHANGED
@@ -12,7 +12,7 @@ from aprsd.client.drivers import kiss
|
|
12
12
|
from aprsd.packets import core
|
13
13
|
|
14
14
|
CONF = cfg.CONF
|
15
|
-
LOG = logging.getLogger(
|
15
|
+
LOG = logging.getLogger('APRSD')
|
16
16
|
LOGU = logger
|
17
17
|
|
18
18
|
|
@@ -27,15 +27,15 @@ class KISSClient(base.APRSClient):
|
|
27
27
|
if serializable:
|
28
28
|
keepalive = keepalive.isoformat()
|
29
29
|
stats = {
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
'connected': self.is_connected,
|
31
|
+
'connection_keepalive': keepalive,
|
32
|
+
'transport': self.transport(),
|
33
33
|
}
|
34
34
|
if self.transport() == client.TRANSPORT_TCPKISS:
|
35
|
-
stats[
|
36
|
-
stats[
|
35
|
+
stats['host'] = CONF.kiss_tcp.host
|
36
|
+
stats['port'] = CONF.kiss_tcp.port
|
37
37
|
elif self.transport() == client.TRANSPORT_SERIALKISS:
|
38
|
-
stats[
|
38
|
+
stats['device'] = CONF.kiss_serial.device
|
39
39
|
return stats
|
40
40
|
|
41
41
|
@staticmethod
|
@@ -56,15 +56,15 @@ class KISSClient(base.APRSClient):
|
|
56
56
|
transport = KISSClient.transport()
|
57
57
|
if transport == client.TRANSPORT_SERIALKISS:
|
58
58
|
if not CONF.kiss_serial.device:
|
59
|
-
LOG.error(
|
59
|
+
LOG.error('KISS serial enabled, but no device is set.')
|
60
60
|
raise exception.MissingConfigOptionException(
|
61
|
-
|
61
|
+
'kiss_serial.device is not set.',
|
62
62
|
)
|
63
63
|
elif transport == client.TRANSPORT_TCPKISS:
|
64
64
|
if not CONF.kiss_tcp.host:
|
65
|
-
LOG.error(
|
65
|
+
LOG.error('KISS TCP enabled, but no host is set.')
|
66
66
|
raise exception.MissingConfigOptionException(
|
67
|
-
|
67
|
+
'kiss_tcp.host is not set.',
|
68
68
|
)
|
69
69
|
|
70
70
|
return True
|
@@ -91,8 +91,8 @@ class KISSClient(base.APRSClient):
|
|
91
91
|
if ka := self._client.aprsd_keepalive:
|
92
92
|
keepalive = timeago.format(ka)
|
93
93
|
else:
|
94
|
-
keepalive =
|
95
|
-
LOGU.opt(colors=True).info(f
|
94
|
+
keepalive = 'N/A'
|
95
|
+
LOGU.opt(colors=True).info(f'<green>Client keepalive {keepalive}</green>')
|
96
96
|
|
97
97
|
@staticmethod
|
98
98
|
def transport():
|
@@ -104,8 +104,8 @@ class KISSClient(base.APRSClient):
|
|
104
104
|
|
105
105
|
def decode_packet(self, *args, **kwargs):
|
106
106
|
"""We get a frame, which has to be decoded."""
|
107
|
-
LOG.debug(f
|
108
|
-
frame = kwargs[
|
107
|
+
LOG.debug(f'kwargs {kwargs}')
|
108
|
+
frame = kwargs['frame']
|
109
109
|
LOG.debug(f"Got an APRS Frame '{frame}'")
|
110
110
|
# try and nuke the * from the fromcall sign.
|
111
111
|
# frame.header._source._ch = False
|
@@ -114,20 +114,23 @@ class KISSClient(base.APRSClient):
|
|
114
114
|
# msg = frame.tnc2
|
115
115
|
# LOG.debug(f"Decoding {msg}")
|
116
116
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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}')
|
123
126
|
|
124
127
|
def setup_connection(self):
|
125
128
|
try:
|
126
129
|
self._client = kiss.KISS3Client()
|
127
|
-
self.connected = self.login_status[
|
130
|
+
self.connected = self.login_status['success'] = True
|
128
131
|
except Exception as ex:
|
129
|
-
self.connected = self.login_status[
|
130
|
-
self.login_status[
|
132
|
+
self.connected = self.login_status['success'] = False
|
133
|
+
self.login_status['message'] = str(ex)
|
131
134
|
return self._client
|
132
135
|
|
133
136
|
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
@@ -135,5 +138,6 @@ class KISSClient(base.APRSClient):
|
|
135
138
|
self._client.consumer(callback)
|
136
139
|
self.keepalive = datetime.datetime.now()
|
137
140
|
except Exception as ex:
|
138
|
-
LOG.error(f
|
141
|
+
LOG.error(f'Consumer failed {ex}')
|
139
142
|
LOG.error(ex)
|
143
|
+
raise ex
|