Created
November 9, 2017 18:11
-
-
Save mumrah/8fe7597edde50855211e27192cce9f88 to your computer and use it in GitHub Desktop.
Python script to decode AX.25 from KISS frames over a serial TNC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hexdump | |
import kiss | |
import struct | |
def decode_addr(data, cursor): | |
(a1, a2, a3, a4, a5, a6, a7) = struct.unpack("<BBBBBBB", data[cursor:cursor+7]) | |
hrr = a7 >> 5 | |
ssid = (a7 >> 1) & 0xf | |
ext = a7 & 0x1 | |
addr = struct.pack("<BBBBBB", a1 >> 1, a2 >> 1, a3 >> 1, a4 >> 1, a5 >> 1, a6 >> 1) | |
if ssid != 0: | |
call = "{}-{}".format(addr.strip(), ssid) | |
else: | |
call = addr | |
return (call, hrr, ext) | |
def decode_uframe(ctrl, data, pos): | |
print "U Frame" | |
if ctrl == 0x3: | |
# UI frame | |
(pid,) = struct.unpack("<B", data[pos]) | |
pos += 1 | |
rem = len(data[pos:-2]) | |
info = struct.unpack("<" + "B"*rem, data[pos:-2]) | |
pos += rem | |
fcs = struct.unpack("<BB", data[pos:]) | |
print "INFO: " + struct.pack("<" + "B"*len(info), *info) | |
def decode_sframe(ctrl, data, pos): | |
print "S Frame" | |
def decode_iframe(ctrl, data, pos): | |
print "I Frame" | |
def p(frame): | |
pos = 0 | |
what_is_this = struct.unpack("<B", frame[pos]) | |
pos += 1 | |
# DST | |
(dest_addr, dest_hrr, dest_ext) = decode_addr(frame, pos) | |
pos += 7 | |
print "DST: " + dest_addr | |
# SRC | |
(src_addr, src_hrr, src_ext) = decode_addr(frame, pos) | |
pos += 7 | |
print "SRC: " + src_addr | |
# REPEATERS | |
ext = src_ext | |
while ext == 0: | |
rpt_addr, rpt_hrr, ext = decode_addr(frame, pos) | |
print "RPT: " + rpt_addr | |
pos += 7 | |
# CTRL | |
(ctrl,) = struct.unpack("<B", frame[pos]) | |
pos += 1 | |
print ctrl | |
if (ctrl & 0x3) == 0x3: | |
decode_uframe(ctrl, frame, pos) | |
elif (ctrl & 0x3) == 0x1: | |
decode_sframe(ctrl, frame, pos) | |
elif (ctrl & 0x1) == 0x0: | |
decode_iframe(ctrl, frame, pos) | |
print(hexdump.hexdump(frame)) | |
if __name__ == "__main__": | |
k = kiss.SerialKISS('/dev/cu.wchusbserial401220', 9600) | |
k.start() # inits the TNC, optionally passes KISS config flags. | |
k.read(callback=p) # reads frames and passes them to `p`. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment