mirror of
https://github.com/craigerl/aprsd.git
synced 2026-02-22 17:20:14 -05:00
Got the serial KISS driver working
This commit is contained in:
parent
6bd0f50dc0
commit
50022e1e9e
@ -2,9 +2,11 @@
|
||||
from aprsd.client.drivers.aprsis import APRSISDriver
|
||||
from aprsd.client.drivers.fake import APRSDFakeDriver
|
||||
from aprsd.client.drivers.registry import DriverRegistry
|
||||
from aprsd.client.drivers.serialkiss import SerialKISSDriver
|
||||
from aprsd.client.drivers.tcpkiss import TCPKISSDriver
|
||||
|
||||
driver_registry = DriverRegistry()
|
||||
driver_registry.register(APRSDFakeDriver)
|
||||
driver_registry.register(APRSISDriver)
|
||||
driver_registry.register(TCPKISSDriver)
|
||||
driver_registry.register(SerialKISSDriver)
|
||||
|
||||
@ -27,6 +27,9 @@ class KISSDriver(metaclass=trace.TraceWrapperMetaclass):
|
||||
last_packet_received = None
|
||||
keepalive = None
|
||||
|
||||
# timeout in seconds
|
||||
select_timeout = 1
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the KISS client.
|
||||
|
||||
@ -85,7 +88,6 @@ class KISSDriver(metaclass=trace.TraceWrapperMetaclass):
|
||||
frame = kissutil.recover_special_codes(kissutil.strip_nmea(bytes(buffer)))
|
||||
if strip_df_start:
|
||||
frame = kissutil.strip_df_start(frame)
|
||||
LOG.warning(f'handle_fend {" ".join(f"{b:02X}" for b in bytes(frame))}')
|
||||
return bytes(frame)
|
||||
|
||||
def fix_raw_frame(self, raw_frame: bytes) -> bytes:
|
||||
@ -145,6 +147,7 @@ class KISSDriver(metaclass=trace.TraceWrapperMetaclass):
|
||||
"""
|
||||
raise NotImplementedError('read_frame is not implemented for KISS')
|
||||
|
||||
@trace.no_trace
|
||||
def stats(self, serializable: bool = False) -> Dict[str, Any]:
|
||||
"""Get client statistics.
|
||||
|
||||
|
||||
@ -7,7 +7,8 @@ non-asyncio KISSInterface implementation.
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import select
|
||||
|
||||
# import select
|
||||
from typing import Any, Dict
|
||||
|
||||
import serial
|
||||
@ -24,6 +25,7 @@ from aprsd import ( # noqa
|
||||
)
|
||||
from aprsd.client.drivers.kiss_common import KISSDriver
|
||||
from aprsd.packets import core
|
||||
from aprsd.utils import trace
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger('APRSD')
|
||||
@ -80,6 +82,11 @@ class SerialKISSDriver(KISSDriver):
|
||||
def close(self):
|
||||
"""Close the connection."""
|
||||
self._connected = False
|
||||
if self.socket and self.socket.is_open:
|
||||
try:
|
||||
self.socket.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def setup_connection(self):
|
||||
"""Set up the KISS interface."""
|
||||
@ -118,11 +125,26 @@ class SerialKISSDriver(KISSDriver):
|
||||
LOG.warning('KISS interface already connected')
|
||||
return
|
||||
|
||||
# Close existing socket if it exists
|
||||
if self.socket and self.socket.is_open:
|
||||
try:
|
||||
self.socket.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
# serial.Serial() automatically opens the port, so we don't need to call open()
|
||||
self.socket = serial.Serial(
|
||||
CONF.kiss_serial.device, CONF.kiss_serial.baudrate
|
||||
CONF.kiss_serial.device,
|
||||
timeout=1,
|
||||
baudrate=CONF.kiss_serial.baudrate,
|
||||
# bytesize=8,
|
||||
# parity='N',
|
||||
# stopbits=1,
|
||||
# xonxoff=False,
|
||||
# rtscts=False,
|
||||
# dsrdtr=False,
|
||||
)
|
||||
self.socket.open()
|
||||
self._connected = True
|
||||
except serial.SerialException as e:
|
||||
LOG.error(f'Failed to connect to KISS interface: {e}')
|
||||
@ -142,21 +164,21 @@ class SerialKISSDriver(KISSDriver):
|
||||
return None
|
||||
|
||||
while self._connected:
|
||||
try:
|
||||
readable, _, _ = select.select(
|
||||
[self.socket],
|
||||
[],
|
||||
[],
|
||||
self.select_timeout,
|
||||
)
|
||||
if not readable:
|
||||
continue
|
||||
except Exception as e:
|
||||
# No need to log if we are not running.
|
||||
# this happens when the client is stopped/closed.
|
||||
LOG.error(f'Error in read loop: {e}')
|
||||
self._connected = False
|
||||
break
|
||||
# try:
|
||||
# readable, _, _ = select.select(
|
||||
# [self.socket],
|
||||
## [],
|
||||
# [],
|
||||
# self.select_timeout,
|
||||
# )
|
||||
# if not readable:
|
||||
# continue
|
||||
# except Exception as e:
|
||||
# # No need to log if we are not running.
|
||||
# # this happens when the client is stopped/closed.
|
||||
# LOG.error(f'Error in read loop: {e}')
|
||||
# self._connected = False
|
||||
# break
|
||||
|
||||
try:
|
||||
short_buf = self.socket.read(1024)
|
||||
@ -208,12 +230,13 @@ class SerialKISSDriver(KISSDriver):
|
||||
frame_kiss = b''.join(
|
||||
[kiss_constants.FEND, command.value, frame_escaped, kiss_constants.FEND]
|
||||
)
|
||||
self.socket.send(frame_kiss)
|
||||
self.socket.write(frame_kiss)
|
||||
# Update last packet sent time
|
||||
self.last_packet_sent = datetime.datetime.now()
|
||||
# Increment packets sent counter
|
||||
self.packets_sent += 1
|
||||
|
||||
@trace.no_trace
|
||||
def stats(self, serializable: bool = False) -> Dict[str, Any]:
|
||||
"""Get client statistics.
|
||||
|
||||
|
||||
@ -39,8 +39,6 @@ class TCPKISSDriver(KISSDriver):
|
||||
# Class level attributes required by Client protocol
|
||||
client_name = None
|
||||
socket = None
|
||||
# timeout in seconds
|
||||
select_timeout = 1
|
||||
path = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user