#PacketRadio

Andreas DC6AP (JO43)andreas@mastodon.aventer.biz
2025-05-21

I small introduction of the current FlexPacket version on my #hamradio blog. There you will also find the latest AppImage for Linux. And yes, I changed the look and feel. 🙂

hamradiotech.de/posts/2025-05-

#hamradio #amateurradio #packetradio

2025-05-19

Hamfest packet radio goodie.
Suspected to be from the former Finnish packet radio network.
1200baud 1200MHz band backhaul link with TAPR TNC-2 clone.

#packetradio #packet #23cm #hamradio #hamfest

Building an AX.25 Messenger App with C#, a TNC, and a Bit of Madness

1,046 words, 6 minutes read time.

YT MD-UV390 Digital Dual Band VHF UHF DMR Radio Waterproof Dustproof IP67 Walkie Talkie

It started with a simple idea — or at least it seemed simple. I was chatting with AI about ways to send text messages from device to device using nothing but the speakers and microphones already built into our phones or laptops. The idea was to modulate the data into frequencies just outside the human hearing range and transmit them. AI made it sound easy — encode, send, decode. But once I actually started trying to do it, it quickly became clear: it wasn’t simple at all. It wasn’t even close.

That failure wasn’t the end — it was the beginning. Because during that process, I remembered that I already owned something built for this kind of thing: a Mobilinkd TNC3. It connects via Bluetooth or USB, speaks the AX.25 protocol over KISS, and communicates via AFSK. And so, a new plan was born — use existing amateur radio tech to send messages between devices. But I didn’t just want to use the TNC — I wanted to understand what it was doing. That meant learning AX.25, digging into KISS, and writing everything from scratch in C#.

The Stack: Tools and Hardware

For this build, I used:

  • C# as the language of choice.
  • A Mobilinkd TNC3, connected via USB.
  • A TYT MD-UV390 radio, operating in analog mode.
  • Cables to connect the TNC to the Radio.

Why AX.25?

The Mobilinkd TNC3 operates using the AX.25 protocol layered over KISS. If you want to send messages through this hardware, you have to understand those protocols. AX.25, originally developed for packet radio in amateur radio use, is efficient, compact, and battle-tested.

I dove into it because the hardware required it — but what I found was something elegant. The structure is simple enough to understand but flexible enough to do real work. That said, actually implementing it in C# was another story.

Writing the AX.25 Messenger

The goal of the app was simple: send and receive short text messages over radio using the Mobilinkd TNC3 and AX.25 protocol.

The project is open source. You can find the code here:

👉 GitHub Repository: AX25Messenger

Let’s walk through some of the key components.

1. Encoding an AX.25 Frame

Here’s what the code looks like when we build the raw AX.25 frame. We start with destination and source callsigns, then add control and protocol fields, and finally append the actual payload.

public byte[] CreateAX25Frame(string destination, string source, byte[] payload){    var frame = new List<byte>();    // Encode callsigns    frame.AddRange(EncodeCallsign(destination, false));    frame.AddRange(EncodeCallsign(source, true));    // Control field (0x03 = UI frame)    frame.Add(0x03);    // Protocol ID (0xF0 = no layer 3 protocol)    frame.Add(0xF0);    // Add payload    frame.AddRange(payload);    return frame.ToArray();}

This code constructs the complete AX.25 frame for a UI (Unnumbered Information) packet. The EncodeCallsign method handles shifting and bit manipulation, making it compatible with the standard.

2. Interfacing with the TNC over KISS

KISS is a framing protocol that wraps the AX.25 data for transmission over a serial port. Here’s how we encapsulate an AX.25 frame into a KISS frame.

public byte[] WrapKISSFrame(byte[] ax25Frame){    var kissFrame = new List<byte>();    kissFrame.Add(0xC0); // Start delimiter    kissFrame.Add(0x00); // Command byte: TNC Data frame    foreach (var b in ax25Frame)    {        if (b == 0xC0) { kissFrame.Add(0xDB); kissFrame.Add(0xDC); }        else if (b == 0xDB) { kissFrame.Add(0xDB); kissFrame.Add(0xDD); }        else { kissFrame.Add(b); }    }    kissFrame.Add(0xC0); // End delimiter    return kissFrame.ToArray();}

This makes the AX.25 message digestible by the TNC.

3. Sending the Data

Once the KISS frame is ready, it’s sent out the serial port like this:

_serialPort.Write(kissFrame, 0, kissFrame.Length);

Where _serialPort is an instance of SerialPort in .NET. Simple, fast, and effective.

The Frustrations of Learning While Building

There were many moments during this project that made me want to throw the whole setup out the window. Trying to learn AX.25 and KISS while building an app around them is painful. The documentation is scattered, and much of what’s out there is old, inconsistent, or assumes a Linux environment.

It didn’t help that most of the time, you can’t even tell if your code is broken or if the radio just didn’t key up fast enough. Debugging means digging into the bits of a failed frame, then trying again and hoping for a clean transmission.

And then there’s AI — which was extremely helpful in doing early code research, mocking up skeletons, and pointing me toward technical docs. But it also hallucinated like crazy when it came to niche protocols. AI tends to guess at how it should be coded when it doesn’t have enough training data, and this project was definitely in that category. I had to train the AI by teaching it the protocol myself before it became useful.

What Didn’t Work

One major limitation of this build: I wasn’t able to test incoming AX.25 messages yet. That part of the project is still under construction. The receive pipeline, decoding the AX.25 frame, and confirming messages are cleanly parsed is a work in progress. It’s the next big hurdle.

Conclusion: A Love Letter to Low-Level Protocols

This whole build was a reminder that sometimes the best learning comes from the weirdest places. I didn’t plan to learn how AX.25 worked. I definitely didn’t plan to write a whole C# interface to a hardware modem. But here we are.

This was a project of persistence, curiosity, and a refusal to let a good idea die. If you’re into coding, radios, or just learning things the hard way, I can’t recommend it enough.

Follow the project on GitHub: AX25Messenger.

And if you enjoyed this write-up or want to follow along as I dive deeper into protocols, microcontrollers, or strange networking ideas, be sure to subscribe to the newsletter.

D. Bryan King

Sources

Disclaimer:

The views and opinions expressed in this post are solely those of the author. The information provided is based on personal research, experience, and understanding of the subject matter at the time of writing. Readers should consult relevant experts or authorities for specific guidance related to their unique situations.

Related Posts

#AFSKModem #AIInRadioProjects #AmateurRadio #amateurRadioTNC #APRSMessaging #AX25 #AX25CCode #AX25Examples #AX25ForProgrammers #AX25LearnByCoding #AX25RawFrames #AX25WithMobilinkd #AX25CMessenger #AX25DigitalMode #AX25Modem #AX25ParserC_ #AX25Protocol #ax25TestSetup #buildingAX25Apps #CAFSKDecoding #CAndKissProtocol #CAndPacketRadio #CAX25 #CHamToolkit #CProjectAX25 #CRadioApp #digitalModeCCode #digitalRadioMessage #hamRadioAndProgramming #hamRadioCExamples #hamRadioCoding #hamRadioCodingTutorial #hamRadioProgramming #hamRadioProtocol #kissAndAfsk #kissCProtocol #kissDecoderTutorial #kissInterface #KISSProtocol #kissProtocolC_ #kissProtocolExample #kissTnc #learnAX25 #learningPacketRadio #MobilinkdTNC3 #packetRadio #packetRadioDev #packetRadioOverAudio #radioMessageApp #radioTextOverAfsk #radioToRadioMessaging #realTimeRadioMessaging #serialRadioCommunication #TNC3AndKiss #TNC3HardwareGuide

Ham Radio Coding Workspace
Stuart Longland (VK4MSL)stuartl@longlandclan.id.au
2025-05-18

A silly protocol idea has been brewing in my mind
 CoAP over AX.25.

The thinking is this
 use UI frames to encapsulate CoAP messages in the same manner as UDP and use a URI scheme like coap+ax25://DEST[,DIGI1[,DIGI2
]]/[path]

If DEST has the C/H bit clear, DEST is a "multicast" group, otherwise it's a specific amateur station.

File transfer just uses RFC-7959 [block-wise transfer] (with possibly a small extension inspired by RFC-2090 [TFTP Multicast] to allow Block1 transmissions to a multicast group).

That would allow file transfer and messaging between stations using existing AX.25 packet radio hardware.

- datatracker.ietf.org/doc/html/ - CoAP RFC
- datatracker.ietf.org/doc/html/ - Blockwise transfers over CoAP
- datatracker.ietf.org/doc/html/ - TFTP Multicast
- ax25.net/ - AX.25 protocol specs and docs

#AmateurRadio #PacketRadio #AX25 #CoAP

2025-05-12

Are there any ham radio packet BBS systems that I can connect to via the Internet? Ideally East Coast US.

I don't have the ability to connect to packet nodes local to me. My ham shack is down pending remodeling. I'd still like to poke around from a Linux box over SSH or Telnet if I can just to see what it's like.

#packetradio #bbs #hamradio #amateurradio

For all you #PacketRadio folks, checking to see that my whitepages entry is working.

can someone send me a packet message to:

KB8QPT

Thanks!

2025-05-04

It looks like APRS has competition in the form of the CATS protocol. cats.radio/

Is there a node map, equivalent to aprs.fi for this protocol?

#hamradio #aprs #packetradio

I am mulling over creating a website and a #GeminiCapsule for those interested in getting started in #PacketRadio . I was thinking that it might be cool to be able to post a listing to the #PacketBBS and allow users to request info via packet, but proxy through #Gemini

This should be possible, as my node can play #Zork

Andreas DC6AP (JO43)andreas@mastodon.aventer.biz
2025-05-01

with the latest changes, 7Plus works very well with my flexpacket #packetradio terminal. đŸ„ł

#hamradio #amateurradio #ax25

N-gated Hacker Newsngate
2025-04-15

🚀 Oh joy, another "lightweight" protocol to complicate your life with packet radios! Because what we really needed was yet another GitHub project with a name only a tech hipster would love—MeshCore. đŸ€Šâ€â™‚ïž But hey, at least you get to "automate any workflow" while drowning in .
github.com/ripplebiz/MeshCore

Andreas DC6AP (JO43)andreas@mastodon.aventer.biz
2025-04-12

I've add a new feature in Flexpacket. Flexpacket will store chosen mails automatically therefore we can read them later offline. Thats a helpfull feature for very long mails. :-) I've tested it with OpenBCM. If it's not working with your home PBBS, please open an issue and add the whole Mail (include header data). 😀 #hamradio #packetradio #ax25

github.com/andreaspeters/flexp

2025-04-05

In other news, a copy of Jan Axelson’s “USB Complete” 5th edition arrived today. Hoping it can help me make sense of USB Audio 2, so I can make progress on my #RaspberryPiPico project! #PacketRadio #Embedded #HamRadio

@kf7ccc

I just set up a node too, after 35 years away from #PacketRadio

if you want to try and send a message,my address is:

KB8QPT@KD8FTR.#NEOH.OH.USA.NOAM

thanks!

I think i have a working #HomeBBS on VHF #PacketRadio.

If someone wants to send me a bbs message, that would be awesome. My address is:

KB8QPT@KD8FTR.#NEOH.OH.USA.NOAM

if you post your address, I'll try sending you a message.

thanks!

So, I am finally updating my #GeminiCapsule #Gemlog .

This time, it's about getting my #PacketRadio station put back up for the first time since like 1992. it works!

But this posting makes me wonder about the present state of the #Gemini protocol. More later.

gemini://gemini.sergio101.com/

2025-03-26

It's back to the future for packet radio. I just reflashed my Kantronics KAM-XL (vintage 2005 or so) with new firmware.

After a few mistakes - Kantronics wasn't expecting a .hex file with Unix line terminators, and there were an awkward few minutes when it would say "upload now" then "upload failed" right after - my TNC now boots up with a version from August 2024.

Who knew they were still doing development?

#hamRadio #packet #tnc #kantronics #packetRadio #AmateurRadio

2025-03-25

In 2021, the german #DARC received 179,690€ from the #ARDC to correct and update the #Linux #AX25 #packetradio #kernel stack.

ardc.net/apply/grants/2021-gra

Since that day, NOTHING is available anywhere. The dedicated web site (linux-ax25.org) is non-existant and all about this project (and the money) vanished.

mailman.ardc.net/mailman3/hype

Has anyone any information about the status of this project? Where is the code? Where the money went?

#amateurradio #hamradio

So, I've been learning #GraphDatabases with #Neo4j this week. I think it would be SUPER fun to recursivlely do an mheard on all the #PacketRadio nodes, to help establish paths around the country.

2025-03-15

Just casually playing with old #ham #msdos #packetradio software #GraphicPacket, my favorite in the 90's, in a #DosBoxX window.

I'm thrown 30 years back and thrilled to have managed to make it work with a #KISS modem and #TFKISS resident driver (a NordLink TNC2 "TheFirmware" emulator for MSDOS).

Btw, I am preaparing some real hardware (Pentium 233) to make that work on, with a legendary 1200 bauds packet-radio #BayCom modem...

#amateurradio #hamradio #radioamateur

A screen capture of the "Graphic Packet" MS-DOS software for packet radio by Ulf Saran in DosBox-X window.
In the monitor window we can see a "test" UI frame from F1SLS (me) and an APRS telemetry frame from F1ZSG, the local APRS repeater.

Client Info

Server: https://mastodon.social
Version: 2025.04
Repository: https://github.com/cyevgeniy/lmst