get raw packet data from KISS socket and start decoding

This commit is contained in:
Jakob Ketterl 2019-08-11 16:37:30 +02:00
parent f53b51a208
commit 2053e5f521
4 changed files with 107 additions and 0 deletions

View File

@ -25,6 +25,8 @@ import os
import signal import signal
import threading import threading
from functools import partial from functools import partial
from owrx.kiss import KissClient
from owrx.wsjt import Ft8Chopper, WsprChopper, Jt9Chopper, Jt65Chopper, Ft4Chopper from owrx.wsjt import Ft8Chopper, WsprChopper, Jt9Chopper, Jt65Chopper, Ft4Chopper
import logging import logging
@ -334,6 +336,10 @@ class dsp(object):
else: else:
self.output.send_output("secondary_demod", partial(self.secondary_process_demod.stdout.read, 1)) self.output.send_output("secondary_demod", partial(self.secondary_process_demod.stdout.read, 1))
if self.isPacket():
kiss = KissClient(8001)
self.output.send_output("packet_demod", kiss.read)
# open control pipes for csdr and send initialization data # open control pipes for csdr and send initialization data
if self.secondary_shift_pipe != None: # TODO digimodes if self.secondary_shift_pipe != None: # TODO digimodes
self.secondary_shift_pipe_file = open(self.secondary_shift_pipe, "w") # TODO digimodes self.secondary_shift_pipe_file = open(self.secondary_shift_pipe, "w") # TODO digimodes

View File

@ -205,6 +205,9 @@ class OpenWebRxReceiverClient(Client):
def write_dial_frequendies(self, frequencies): def write_dial_frequendies(self, frequencies):
self.protected_send({"type": "dial_frequencies", "value": frequencies}) self.protected_send({"type": "dial_frequencies", "value": frequencies})
def write_packet_data(self, data):
self.protected_send({"type": "packet_data", "value": data})
class MapConnection(Client): class MapConnection(Client):
def __init__(self, conn): def __init__(self, conn):

97
owrx/kiss.py Normal file
View File

@ -0,0 +1,97 @@
import socket
import time
import logging
logger = logging.getLogger(__name__)
FEND = 0xC0
FESC = 0xDB
TFEND = 0xDC
TFESC = 0XDD
def group(a, *ns):
for n in ns:
a = [a[i:i+n] for i in range(0, len(a), n)]
return a
def join(a, *cs):
return [cs[0].join(join(t, *cs[1:])) for t in a] if cs else a
def hexdump(data):
toHex = lambda c: '{:02X}'.format(c)
toChr = lambda c: chr(c) if 32 <= c < 127 else '.'
make = lambda f, *cs: join(group(list(map(f, data)), 8, 2), *cs)
hs = make(toHex, ' ', ' ')
cs = make(toChr, ' ', '')
for i, (h, c) in enumerate(zip(hs, cs)):
print ('{:010X}: {:48} {:16}'.format(i * 16, h, c))
class KissClient(object):
def __init__(self, port):
time.sleep(1)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect(("localhost", port))
def read(self):
buf = bytes()
escaped = False
while True:
input = self.socket.recv(1)
# EOF
if len(input) == 0:
return bytes()
if input[0] == FESC:
escaped = True
elif escaped:
if input[0] == TFEND:
buf += [FEND]
elif input[0] == TFESC:
buf += [FESC]
else:
logger.warning("invalid escape char: %s", str(input[0]))
escaped = False
elif input[0] == FEND:
logger.debug("decoded frame: " + str(buf))
if len(buf) > 0:
return self.parseFrame(buf)
else:
buf += input
def parseFrame(self, frame):
# data frames start with 0x00
if frame[0] != 0x00:
return {}
ax25frame = frame[1:]
control_pid = ax25frame.find(bytes([0x03, 0xf0]))
if control_pid % 7 > 0:
logger.warning("aprs packet framing error: control/pid position not aligned with 7-octet callsign data")
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
information = ax25frame[control_pid+2:]
self.parseAprsData(information)
data = {
"destination": self.extractCallsign(ax25frame[0:7]),
"source": self.extractCallsign(ax25frame[7:14]),
"path": [self.extractCallsign(c) for c in chunks(ax25frame[14:control_pid], 7)]
}
logger.debug(data)
return data
def parseAprsData(self, data):
hexdump(data)
return {}
def extractCallsign(self, input):
cs = bytes([b >> 1 for b in input[0:6]]).decode().strip()
ssid = (input[6] & 0b00011110) >> 1
if ssid > 0:
return "{callsign}-{ssid}".format(callsign=cs, ssid=ssid)
else:
return cs

View File

@ -502,6 +502,7 @@ class DspManager(csdr.output):
"secondary_demod": self.handler.write_secondary_demod, "secondary_demod": self.handler.write_secondary_demod,
"meta": self.metaParser.parse, "meta": self.metaParser.parse,
"wsjt_demod": self.wsjtParser.parse, "wsjt_demod": self.wsjtParser.parse,
"packet_demod": self.handler.write_packet_data,
} }
write = writers[t] write = writers[t]