* Add KISS TNC external app for APRS RX/TX over USB serial
Adds a KISS TNC (Terminal Node Controller) app that bridges APRS
packets between the HackRF radio and a connected PC over USB CDC
serial using the KISS protocol.
Features:
- APRS receive at 144.390 MHz (configurable), decoding packets via
the existing APRS RX baseband (PAPR.bin)
- Received AX.25 frames forwarded to host as KISS-framed data over
USB serial
- KISS frames received from host transmitted as AFSK audio using the
existing AFSK TX baseband (PAFT.bin)
- Clean RX->TX->RX baseband switching with proper timing delays
- USB connection status indicator with periodic refresh
- Compatible with standard KISS TNC clients (Xastir, APRSISCE/32,
Dire Wolf, etc.)
Firmware changes required to support the external app:
- baseband_api.cpp: mark set_aprs() __attribute__((used)) so it is
retained by the linker for external app use
- protocols/ax25: add make_frame_from_raw() to build NRZI bitstream
from raw AX.25 bytes, marked __attribute__((used))
- usb_serial_host_to_device: add kiss_raw_handler hook to route
incoming USB bytes directly to a registered callback, bypassing
the shell; marked __attribute__((used))
- baseband/proc_aprsrx: add constructor that auto-configures at
1200 baud so external apps do not need to call set_aprs() at init
* Address PR review: generic RAII USB handler, fix TX cutoff and buffer overflow
- Replace KISS-specific set_kiss_raw_handler() in shared USB code with a
generic UsbSerialInputHandler RAII class; any app can now register a
handler via the ctor and it auto-clears in the dtor — no app-specific
'if' checks in shared code, no __attribute__((used)) needed
- Remove __attribute__((used)) from set_aprs() — it is referenced directly
by ui_aprs_rx.cpp so it will never be dead-stripped
- Fix send_kiss_frame() buffer overflow: per-byte bounds check prevents
2-byte escape sequences from writing past the end of the output buffer
- Replace fillOBuffer(TIME_INFINITE) with chOQWriteTimeout(TIME_IMMEDIATE)
to drop bytes instead of blocking the event loop
- Remove chThdSleepMilliseconds() calls from start_tx() and finish_tx()
- Fix TX cutoff bug: call start_tx() directly from process_kiss_frame()
instead of deferring via tx_pending_ flag (deferral caused kiss_idx_
to be 0 by the time start_tx() fired, producing an empty frame)
* Move USB write into UsbSerialInputHandler class
Add a write() method to UsbSerialInputHandler so all USB I/O
(both input callback and output) is encapsulated in the class.
KISS TNC now uses usb_input_handler_->write() instead of calling
chOQWriteTimeout(&SUSBD1.oqueue, ...) directly, keeping raw USB
details out of app code.
* Address PR review: remove auto-configure from APRSRxProcessor, add timeout param to write()
- Remove default_config from APRSRxProcessor() constructor; baseband should
start unconfigured and wait for APRSRxConfigureMessage from the app side
(already sent via baseband::set_aprs() in KISS TNC and APRS RX app)
- Remove stray #include "stdio.h" from proc_aprsrx.cpp
- Add systime_t timeout parameter with default TIME_IMMEDIATE to
UsbSerialInputHandler::write() so callers can choose blocking behaviour
Several old bugs squashed.
On the APRS side, most notably, SSID numbers where shifted left twice, instead of once, and bits 5,6 where not properly set.
On AX.25 side, the bit stuffing part of the encoder was not placing the zero bit on the right place.
Finally, I changed APRS icon from ORANGE to GREEN, since even this may be a simple app, now it's doing its work as intended.