mirror of
https://github.com/craigerl/aprsd.git
synced 2026-02-24 10:10:50 -05:00
make consumer call signature consistent.
This commit is contained in:
parent
2b7e42802b
commit
6ea9889369
@ -131,10 +131,19 @@ class KISSDriver(metaclass=trace.TraceWrapperMetaclass):
|
||||
"""Start consuming frames with the given callback.
|
||||
|
||||
Args:
|
||||
callback: Function to call with received packets
|
||||
callback: Function to call with received packets.
|
||||
Called with frame=<frame> keyword argument to match
|
||||
the signature used by other drivers (packet=<packet>).
|
||||
raw: If True, callback receives raw frame data.
|
||||
If False, callback receives decoded packet.
|
||||
|
||||
Raises:
|
||||
Exception: If not connected to KISS TNC
|
||||
|
||||
Note:
|
||||
The callback signature should accept keyword arguments:
|
||||
- For raw frames: callback(frame=frame_obj)
|
||||
- For decoded packets: callback(packet=packet_obj)
|
||||
"""
|
||||
# Ensure connection
|
||||
if not self._connected:
|
||||
@ -144,7 +153,14 @@ class KISSDriver(metaclass=trace.TraceWrapperMetaclass):
|
||||
frame = self.read_frame()
|
||||
if frame:
|
||||
LOG.info(f'GOT FRAME: {frame} calling {callback}')
|
||||
callback(frame)
|
||||
if raw:
|
||||
# Pass raw frame with keyword argument for consistency
|
||||
callback(frame=frame)
|
||||
else:
|
||||
# Decode frame to packet and pass with keyword argument
|
||||
packet = self.decode_packet(frame)
|
||||
if packet:
|
||||
callback(packet=packet)
|
||||
|
||||
def read_frame(self):
|
||||
"""Read a frame from the KISS interface.
|
||||
|
||||
@ -89,7 +89,16 @@ class SerialKISSDriver(KISSDriver):
|
||||
pass
|
||||
|
||||
def setup_connection(self):
|
||||
"""Set up the KISS interface."""
|
||||
"""Set up the KISS interface.
|
||||
|
||||
This is the Protocol-defined method that initializes the connection.
|
||||
It internally calls connect() to establish the actual serial connection.
|
||||
|
||||
Note:
|
||||
This method follows the ClientDriver Protocol. Use this method
|
||||
for standard connection setup. The connect() method is an internal
|
||||
KISS-specific helper for establishing the serial port connection.
|
||||
"""
|
||||
if not self.is_enabled():
|
||||
LOG.error('KISS is not enabled in configuration')
|
||||
return
|
||||
@ -99,7 +108,7 @@ class SerialKISSDriver(KISSDriver):
|
||||
return
|
||||
|
||||
try:
|
||||
# Configure for TCP KISS
|
||||
# Configure for Serial KISS
|
||||
if self.is_enabled():
|
||||
LOG.info(
|
||||
f'Serial KISS Connection to {CONF.kiss_serial.device}:{CONF.kiss_serial.baudrate}'
|
||||
@ -116,7 +125,16 @@ class SerialKISSDriver(KISSDriver):
|
||||
self._connected = False
|
||||
|
||||
def connect(self):
|
||||
"""Connect to the KISS interface."""
|
||||
"""Establish serial connection to the KISS device.
|
||||
|
||||
This is a KISS-specific internal method that handles the low-level
|
||||
serial port connection. It is called by setup_connection().
|
||||
|
||||
Note:
|
||||
This method is NOT part of the ClientDriver Protocol. It is specific
|
||||
to KISS drivers and handles serial port establishment and configuration.
|
||||
External code should use setup_connection() instead.
|
||||
"""
|
||||
if not self.is_enabled():
|
||||
LOG.error('KISS is not enabled in configuration')
|
||||
return
|
||||
|
||||
@ -145,7 +145,16 @@ class TCPKISSDriver(KISSDriver):
|
||||
return True
|
||||
|
||||
def setup_connection(self):
|
||||
"""Set up the KISS interface."""
|
||||
"""Set up the KISS interface.
|
||||
|
||||
This is the Protocol-defined method that initializes the connection.
|
||||
It internally calls connect() to establish the actual TCP connection.
|
||||
|
||||
Note:
|
||||
This method follows the ClientDriver Protocol. Use this method
|
||||
for standard connection setup. The connect() method is an internal
|
||||
KISS-specific helper for establishing the TCP socket connection.
|
||||
"""
|
||||
if not self.is_enabled():
|
||||
LOG.error('KISS is not enabled in configuration')
|
||||
return
|
||||
@ -186,6 +195,14 @@ class TCPKISSDriver(KISSDriver):
|
||||
def connect(self) -> bool:
|
||||
"""Establish TCP connection to the KISS host.
|
||||
|
||||
This is a KISS-specific internal method that handles the low-level
|
||||
socket connection. It is called by setup_connection().
|
||||
|
||||
Note:
|
||||
This method is NOT part of the ClientDriver Protocol. It is specific
|
||||
to KISS drivers and handles TCP socket establishment and configuration.
|
||||
External code should use setup_connection() instead.
|
||||
|
||||
Returns:
|
||||
bool: True if connection successful, False otherwise
|
||||
"""
|
||||
|
||||
@ -94,12 +94,26 @@ class APRSDRXThread(APRSDThread):
|
||||
"""Put the raw packet on the queue.
|
||||
|
||||
The processing of the packet will happen in a separate thread.
|
||||
|
||||
Accepts packets/frames as either:
|
||||
- Positional arg: process_packet(frame)
|
||||
- Keyword args: process_packet(raw=frame), process_packet(frame=frame), or process_packet(packet=pkt)
|
||||
"""
|
||||
if not args:
|
||||
# Extract the packet/frame from either args or kwargs
|
||||
if args:
|
||||
data = args[0]
|
||||
elif 'raw' in kwargs:
|
||||
data = kwargs['raw']
|
||||
elif 'frame' in kwargs:
|
||||
data = kwargs['frame']
|
||||
elif 'packet' in kwargs:
|
||||
data = kwargs['packet']
|
||||
else:
|
||||
LOG.warning('No frame received to process?!?!')
|
||||
return
|
||||
|
||||
self.pkt_count += 1
|
||||
self.packet_queue.put(args[0])
|
||||
self.packet_queue.put(data)
|
||||
|
||||
|
||||
class APRSDFilterThread(APRSDThread):
|
||||
|
||||
@ -175,11 +175,15 @@ class TestKISSDriver(unittest.TestCase):
|
||||
self.driver._connected = True
|
||||
callback = mock.MagicMock()
|
||||
mock_frame = b'test_frame'
|
||||
mock_packet = mock.MagicMock()
|
||||
|
||||
with mock.patch.object(self.driver, 'read_frame', return_value=mock_frame):
|
||||
with mock.patch('aprsd.client.drivers.kiss_common.LOG'):
|
||||
self.driver.consumer(callback)
|
||||
callback.assert_called()
|
||||
with mock.patch.object(
|
||||
self.driver, 'decode_packet', return_value=mock_packet
|
||||
):
|
||||
with mock.patch('aprsd.client.drivers.kiss_common.LOG'):
|
||||
self.driver.consumer(callback)
|
||||
callback.assert_called_once_with(packet=mock_packet)
|
||||
|
||||
def test_read_frame_not_implemented(self):
|
||||
"""Test read_frame() raises NotImplementedError."""
|
||||
|
||||
@ -373,6 +373,7 @@ class TestTCPKISSDriver(unittest.TestCase):
|
||||
"""Test consumer processes frames and calls callback."""
|
||||
mock_callback = mock.MagicMock()
|
||||
mock_frame = mock.MagicMock()
|
||||
mock_packet = mock.MagicMock()
|
||||
|
||||
# Configure driver for test
|
||||
self.driver._connected = True
|
||||
@ -386,10 +387,13 @@ class TestTCPKISSDriver(unittest.TestCase):
|
||||
with mock.patch.object(
|
||||
self.driver, 'read_frame', side_effect=side_effect
|
||||
) as mock_read_frame:
|
||||
self.driver.consumer(mock_callback)
|
||||
with mock.patch.object(
|
||||
self.driver, 'decode_packet', return_value=mock_packet
|
||||
):
|
||||
self.driver.consumer(mock_callback)
|
||||
|
||||
mock_read_frame.assert_called_once()
|
||||
mock_callback.assert_called_once_with(mock_frame)
|
||||
mock_read_frame.assert_called_once()
|
||||
mock_callback.assert_called_once_with(packet=mock_packet)
|
||||
|
||||
@mock.patch('aprsd.client.drivers.tcpkiss.LOG')
|
||||
def test_read_frame_success(self, mock_log):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user