sjlongland / aioax25

Asynchronous AX.25 library using asyncio
GNU General Public License v2.0
21 stars 8 forks source link

seeing problems decoding aprs packets from direwolf #11

Open hemna opened 2 years ago

hemna commented 2 years ago

I have aprsd using tcpkiss socket to direwolf. Each packet that is seen by aioax25 results in this.

Screen Shot 2022-02-12 at 9 32 13 AM
hemna commented 2 years ago
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECV RAW 'c00082a082a87062e2969c68988a866e966886a24040e8ae92888a6240e0ae92888a64406503f021333732322e3 kiss.py:211
                                                     2304e2f30373930302e363657263030302f3030302f413d3030303638354d6f62696c65c0'
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECV FRAME start at 0                                                                                 kiss.py:249
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECV FRAME end at 1                                                                                   kiss.py:263
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECEIVED FRAME , REMAINING c00082a082a87062e2969c68988a866e966886a24040e8ae92888a6240e0ae92888a644065 kiss.py:270
                                                     03f021333732322e32304e2f30373930302e363657263030302f3030302f413d3030303638354d6f62696c65c0
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECV FRAME start at 0                                                                                 kiss.py:249
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECV FRAME end at 81                                                                                  kiss.py:263
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECEIVED FRAME 0082a082a87062e2969c68988a866e966886a24040e8ae92888a6240e0ae92888a64406503f02133373232 kiss.py:270
                                                     2e32304e2f30373930302e363657263030302f3030302f413d3030303638354d6f62696c65, REMAINING c0
02/12/2022 09:38:29 AM RX_MSG               DEBUG    RECV FRAME dispatch KISSCmdData{Port 0, Cmd 0x00, Payload 82a082a87062e2969c68988a866e966886a24040e8a kiss.py:302
                                                     e92888a6240e0ae92888a64406503f021333732322e32304e2f30373930302e363657263030302f3030302f413d3030303638
                                                     354d6f62696c65}
02/12/2022 09:38:29 AM RX_MSG               DEBUG    Received frame KISSCmdData{Port 0, Cmd 0x00, Payload 82a082a87062e2969c68988a866e966886a24040e8ae9288 kiss.py:503
                                                     8a6240e0ae92888a64406503f021333732322e32304e2f30373930302e363657263030302f3030302f413d3030303638354d6
                                                     f62696c65}
02/12/2022 09:38:29 AM RX_MSG               DEBUG    Failed to decode as APRS                                                                              frame.py:46
                                                     ╭──────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
                                                     │                                                                                                   │
                                                     │ /Users/i530566/devel/mine/hamradio/aprsd/.aprsd-venv/lib/python3.8/site-packages/aioax25/aprs/fra │
                                                     │ me.py:38 in decode                                                                                │
                                                     │                                                                                                   │
                                                     │   35 │   │   try:                                                                                 │
                                                     │   36 │   │   │   # Inspect the first byte.                                                        │
                                                     │   37 │   │   │   type_code = APRSDataType(uiframe.payload[0])                                     │
                                                     │ ❱ 38 │   │   │   handler_class = cls.DATA_TYPE_HANDLERS[type_code]                                │
                                                     │   39 │   │   │                                                                                    │
                                                     │   40 │   │   │   # Decode the payload as text                                                     │
                                                     │   41 │   │   │   payload = uiframe.payload.decode('US-ASCII')                                     │
                                                     ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
                                                     KeyError: <APRSDataType.POSITION: 33>
02/12/2022 09:38:29 AM RX_MSG               DEBUG    Processing incoming message KN4LEC-7>APAT81-1*,K4CQ-4*,WIDE1*,WIDE2-2: PID=0xf0                       aprs.py:246
                                                     Payload=b'!3722.20N/07900.66W&000/000/A=000685Mobile' (type AX25UnnumberedInformationFrame)
02/12/2022 09:38:29 AM RX_MSG               DEBUG    Handling incoming frame KN4LEC-7>APAT81-1*,K4CQ-4*,WIDE1*,WIDE2-2: PID=0xf0                          router.py:98
                                                     Payload=b'!3722.20N/07900.66W&000/000/A=000685Mobile'
02/12/2022 09:38:29 AM RX_MSG               DEBUG    Dispatching frame to 0 receivers
sjlongland commented 2 years ago

Okay, seems those APRS message types aren't implemented, shouldn't be a difficult problem to solve.

sjlongland commented 2 years ago
Received frame KISSCmdData{Port 0, Cmd 0x00, Payload 82a082a87062e2969c68988a866e966886a24040e8ae92888a6240e0ae92888a64406503f021333732322e32304e2f30373930302e363657263030302f3030302f413d3030303638354d6f62696c65}
RC=0 stuartl@rikishi ~/projects/wicen/rfid/aioax25 $ ipython3
Python 3.9.9 (main, Jan 23 2022, 10:56:58) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.30.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from aioax25 import frame

In [2]: from binascii import a2b_hex

In [3]: f = frame.AX25Frame.decode(a2b_hex('82a082a87062e2969c68988a866e966886a24040e8ae92888a6240e0ae92888a64406503f021333732322e3
   ...: 2304e2f30373930302e363657263030302f3030302f413d3030303638354d6f62696c65'))

In [4]: f
Out[4]: <aioax25.frame.AX25UnnumberedInformationFrame at 0x7f138e2510a0>

In [5]: f.payload
Out[5]: b'!3722.20N/07900.66W&000/000/A=000685Mobile'

In [6]: str(f)
Out[6]: "KN4LEC-7>APAT81-1*,K4CQ-4*,WIDE1*,WIDE2-2: PID=0xf0 Payload=b'!3722.20N/07900.66W&000/000/A=000685Mobile'"
In [7]: from aioax25.aprs import frame as aprsframe

In [8]: import logging

In [9]: logging.basicConfig(level=logging.DEBUG)

In [10]: af=aprsframe.APRSFrame.decode(f, logging.root)
DEBUG:root:Failed to decode as APRS
Traceback (most recent call last):
  File "/home/stuartl/projects/wicen/rfid/aioax25/aioax25/aprs/frame.py", line 38, in decode
    handler_class = cls.DATA_TYPE_HANDLERS[type_code]
KeyError: <APRSDataType.POSITION: 33>

How about I make a test-case out of this then see if we can fix the problem.

hemna commented 2 years ago

ok that sounds good

sjlongland commented 2 years ago

Okay, so I dug into the APRS specs on position reporting… and man, what a can of worms… I think I've got something that should recognise and hopefully not mangle position reports.

It's worth noting that, the code as it stands now should pass through unrecognised frames as generic AX.25 UI frames, so other code should be able to pick them up and parse them as needed, but handling of position frames certainly fits within the purview of this library, so it should handle it.

On the to-do list:

sjlongland commented 2 years ago

So… had a chance to look at this today.

Unit conversion is supported… basically natively it still uses imperial units, but there's alternate versions that use pint's Quantity class. That will let you convert to any unit it supports. Prefer your altitudes in meters, or your speeds in angstroms/week, knock yourself out. :-)

Uncompressed and compressed position report formats are supported. Of course timestamps are basically using a dedicated class rather than the standard datetime classes, since the APRS standard timestamps often omit things like year/month, and some timestamps are localtime vs UTC. It was a big can of worms I decided wasn't worth trying to unpick at this time.

NOT supported at this time, but maybe I'll get a chance to add that in later, is MicE support. Those packets use a slightly different format, I'll have to research how that all works.

I'll have to see if I can gather more frame types to test the decoder and encoder out, but things are looking pretty good so far.

sjlongland commented 2 years ago
stuartl@vk4msl-ws:~/projects/wicen/aioax25$ cat test.py 
from aioax25 import frame
from binascii import a2b_hex

f = frame.AX25Frame.decode(a2b_hex('82a082a87062e2969c68988a866e966886a24040e8ae92888a6240e0ae92888a64406503f021333732322e32304e2f30373930302e363657263030302f3030302f413d3030303638354d6f62696c65'))

from aioax25.aprs import frame as aprsframe
from aioax25.aprs import position
import logging

logging.basicConfig(level=logging.DEBUG)

af=aprsframe.APRSFrame.decode(f, logging.root)
stuartl@vk4msl-ws:~/projects/wicen/aioax25$ python3.10 test.py 
DEBUG:root:Received a APRSDataType.POSITION frame
DEBUG:root:Type: APRSDataType.POSITION; timestamp: None; payload: '3722.20N/07900.66W&000/000/A=000685Mobile'
DEBUG:root:Position: APRSUncompressedCoordinates(lat=APRSLatitude(degrees=37, minutes=22, seconds=11.999999999999957, ambiguity=<APRSPositionAmbiguity.NONE: 0>), lng=APRSLongitude(degrees=-79, minutes=0, seconds=39.6, ambiguity=<APRSPositionAmbiguity.NONE: 0>), symbol=APRSSymbol(table=<APRSSymbolTable.PRIMARY: '/'>, symbol='&', overlay=None)), Message: '000/000/A=000685Mobile'
sjlongland commented 1 year ago

I've merged the position reporting stuff for now… but I'll leave this open as there's MIC-e stuff to be added.