C library with utilities for AX.25 / APRS TNCs and apps interacting with them
  • C 98.9%
  • CMake 0.7%
  • Makefile 0.4%
Find a file
pw 87725ca366 cut project to amateur radio only;
move all buffer and common c code to their respective headers
2026-02-04 20:48:00 +01:00
include cut project to amateur radio only; 2026-02-04 20:48:00 +01:00
src cut project to amateur radio only; 2026-02-04 20:48:00 +01:00
test cut project to amateur radio only; 2026-02-04 20:48:00 +01:00
.clinerules cut project to amateur radio only; 2026-02-04 20:48:00 +01:00
.gitignore add 2 client test for tcp server broadcast 2026-01-25 22:15:15 +01:00
CMakeLists.txt cut project to amateur radio only; 2026-02-04 20:48:00 +01:00
LICENSE Initial commit 2026-01-25 07:38:11 +00:00
Makefile cut project to amateur radio only; 2026-02-04 20:48:00 +01:00
README.md cut project to amateur radio only; 2026-02-04 20:48:00 +01:00

libtnc

TNC-related utilities library for AX.25 packet radio. Contains utilities both intended for use in a TNC program as well as others interfacing with a TNC.

Features

  • AX.25: Packet and address structs and basic functions
  • HDLC: Framing and deframing with NRZI, bit stuffing, checksums
  • KISS: Binary protocol for TNC communication similar to SLIP
  • TNC2: Human-readable packet representation (STATION>DEST,PATH:DATA)
  • CRC-CCITT: 16-bit CRC calculation
  • Line parsing: Buffered line reader with callback

Build

make build    # Debug build
make release  # Release build
make test     # Run unit tests
make install  # Install to system
make clean    # Clean build artifacts

Usage

ax25_packet_t packet;
ax25_packet_init(&packet);
ax25_addr_init_with(&packet.destination, "NOCALL", 0, false);
ax25_addr_init_with(&packet.source, "MYCALL", 1, false);
packet.control = 0x03;  // UI frame
packet.protocol = 0xf0;  // No layer 3
packet.info_len = 5;
memcpy(packet.info, "HELLO", 5);

buffer_t tnc2_buf;
buffer_init(&tnc2_buf, tnc2_out, sizeof(tnc2_out));
tnc2_packet_to_string(&packet, &tnc2_buf);

kiss_message_t kiss;
kiss_encode(&kiss, kiss_out, sizeof(kiss_out));

hldc_framer_t framer;
hldc_framer_init(&framer, 16, 16);  // 16 flag bytes pre/postamble
hldc_framer_process(&framer, &kiss_buf, &hdlc_out, NULL);

crc_ccitt_t crc;
crc_ccitt_init(&crc);
crc_ccitt_update_buffer(&crc, data, len);
uint16_t checksum = crc_ccitt_get(&crc);

line_reader_t lr;
line_reader_init(&lr, my_line_callback);
line_reader_process(&lr, ch);

hldc_deframer_t deframer;
hldc_deframer_init(&deframer);

for (int i = 0; i < bit_count; i++) {
    hldc_deframer_process(&deframer, bits[i], &frame_buf, NULL);
}

kiss_decoder_t decoder;
kiss_decoder_init(&decoder);
kiss_decoder_process(&decoder, byte, &kiss_msg);

ax25_packet_t packet;
ax25_packet_unpack(&packet, &kiss_msg.data_buf);

Dependencies

  • Standard C library