Skip to main content

Pure Python implementation of AX.25 v2.2 Layer 2 protocol for amateur radio

Project description

PyAX25_22 – Pure Python AX.25 v2.2 Layer 2 Implementation

A complete, modern, and fully compliant AX.25 v2.2 Link Layer library for amateur packet radio.

Author: Kris Kirby, KE4AHR
License: GNU Lesser General Public License v3 or later (LGPL-3.0-or-later)
Version: 0.5.15
Release Date: January 05, 2026
Repository: https://github.com/ke4ahr/PyAX25_22

Overview

PyAX25_22 is a pure-Python implementation of the AX.25 v2.2 (July 1998) Link Layer protocol used in amateur packet radio. It provides a clean, well-tested, and production-ready foundation for applications including:

  • PACSAT ground stations (via future PyPACSAT)
  • Packet radio nodes and BBS systems
  • APRS monitoring and iGates
  • Software TNC integration (Dire Wolf, soundmodem)
  • Custom packet tools

The library focuses exclusively on Layer 2 – no higher-layer protocols (NET/ROM, FBB/B2F, etc.) are included, ensuring maximum reusability.

Key Features

  • Full AX.25 v2.2 compliance
    • All frame types: I, S (RR/RNR/REJ/SREJ), U (SABM/SABME/UA/DISC/DM/FRMR/UI/XID/TEST)
    • Modulo 8 and Modulo 128 operation
    • Up to 8 digipeaters with proper H-bit handling
    • Bit stuffing/destuffing and CRC-16/CCITT-FALSE FCS
    • XID parameter negotiation (modulo, window size k, max frame N1, SREJ)
  • Connected and unconnected modes
    • Complete state machine per SDL diagrams
    • Adaptive T1 timer with SRTT algorithm
    • Full flow control (RR/RNR/REJ/SREJ)
  • Transport interfaces
    • KISS with full multi-drop support (G8BPQ extension)
    • AGWPE TCP/IP API complete client (registration, monitoring, queue query)
  • Concurrency
    • Synchronous and asynchronous APIs
    • Thread-safe background I/O handling
  • Quality
    • Comprehensive error handling with custom exception hierarchy
    • Structured, configurable logging
    • 95% test coverage

    • Full type hints and Google-style docstrings

Installation

pip install pyax25-22

For development (includes testing and documentation tools):

pip install pyax25-22[dev]

Quick Examples

Send a UI Beacon

from pyax25_22.core.framing import AX25Frame, AX25Address

dest = AX25Address("APRS", ssid=0)
src = AX25Address("KE4AHR", ssid=1)

frame = AX25Frame(
    destination=dest,
    source=src,
    control=0x03,      # UI frame
    pid=0xF0,          # No Layer 3 protocol
    info=b"PyAX25_22 beacon test"
)

print(f"Encoded frame ({len(frame.encode())} bytes): {frame.encode().hex()}")

Monitor via Multi-Drop KISS

from pyax25_22.interfaces.kiss import KISSInterface

kiss = KISSInterface("/dev/ttyUSB0", baudrate=9600, tnc_address=1)

def on_frame(tnc_addr, port, frame):
    print(f"TNC {tnc_addr} | {frame.source.callsign}-{frame.source.ssid} → {frame.destination.callsign}")

kiss.register_callback(0x00, on_frame)  # Data frames
kiss.connect()

try:
    while True:
        tnc_addr, port, frame = kiss.receive()
        # Handled by callback
except KeyboardInterrupt:
    kiss.disconnect()

Monitor via AGWPE

from pyax25_22.interfaces.agwpe import AGWPEInterface

agwpe = AGWPEInterface()

def on_monitored(port, fr, to, data):
    print(f"[{port}] {fr} → {to}: {data.decode(errors='ignore')}")

agwpe.register_callback('M', on_monitored)
agwpe.connect()
agwpe.enable_monitoring()

try:
    while True:
        port, kind, fr, to, data = agwpe.receive()
        print(f"{kind}: {fr}->{to}")
except KeyboardInterrupt:
    agwpe.disconnect()

Documentation

References

Built from primary sources:

  • AX.25 Link Access Protocol for Amateur Packet Radio v2.2 (July 1998)
  • Multi-Drop KISS Operation – Karl Medcalf WK5M
  • AGW TCP/IP Socket Interface – George Rossopoulos SV2AGW (2000)
  • AGWPE TCP/IP API Tutorial – Pedro E. Colla LU7DID & SV2AGW
  • PACSAT File Header Definition – Jeff Ward G0/K8KA & Harold Price NK6K

Contributing

Contributions are welcome! Please:

  • Follow existing code style
  • Add tests for new features
  • Update documentation

License

Licensed under LGPL-3.0-or-later.

Full license text: LICENSE


73 de KE4AHR

Copyright (C) 2025-2026 Kris Kirby, KE4AHR

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyax25_22-0.5.97.tar.gz (51.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyax25_22-0.5.97-py3-none-any.whl (49.3 kB view details)

Uploaded Python 3

File details

Details for the file pyax25_22-0.5.97.tar.gz.

File metadata

  • Download URL: pyax25_22-0.5.97.tar.gz
  • Upload date:
  • Size: 51.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for pyax25_22-0.5.97.tar.gz
Algorithm Hash digest
SHA256 e01d12084f8648f87c3f39e170fe09cf538fd372d1aaa247828fcc1f9df0cdca
MD5 a2c86f6add3ab11419865c4eb139d9a8
BLAKE2b-256 ba097da3c8d51cd6f3958de3db9c51ee8ae197e1d5b9ca41ee7396ed78043535

See more details on using hashes here.

File details

Details for the file pyax25_22-0.5.97-py3-none-any.whl.

File metadata

  • Download URL: pyax25_22-0.5.97-py3-none-any.whl
  • Upload date:
  • Size: 49.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for pyax25_22-0.5.97-py3-none-any.whl
Algorithm Hash digest
SHA256 0128c772ab79274fd49b4a6805b3b31c369a7c840c49518455ad10c52d2f2b3b
MD5 8276d8abacfe32ff79678b5351202868
BLAKE2b-256 ef453f551c0e604e26dc1d17b536aec639803e275fb7a460b0914aa6a66a8d94

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page