In amongst my FoxTelem coding responsibilities I have been working on a new Ground Station for FalconSat-3. Initially decoding the packets was straight forward. For those who are interested, I'll explain how it works in this post.
The KISS frames are easily spotted because the 0xC0 (FEND) markers do not appear in the data. So every time we see the FEND byte a frame is starting or ending. There is a little bit of work because the FEND has been escaped in the data, and we have to undo that. Otherwise it is straight forward. I wrote a simple add() method in a KissFrame class that returns true once a frame is complete and produces a clean array of data. This class also has a constructor to make Kiss Frames, but that is needed to transmit data and not to receive.
Each Kiss Frame can wrap any data we want, but from the spacecraft it is wrapping an AX25 frame. We can look at the rather long AX25 Specification to understand the formats. We can ignore the start and end Flags and the FCS check bytes. These have been handled by the TNC. Our data, once the KISS wrapping is removed, starts with The addresses and the control bytes.
Inspection of the received bytes in a hex editor immediately shows us the data from the spacecraft:
One kiss frame is highlighted. We can see in the ASCII translation to the right that this frame says "PB: Empty" and is a message from the spacecraft saying that there are no callsigns in the broadcast queue waiting for data. This is an invitation to transmit a request!
There are more bytes here than just the String "PB: Empty". So let's decode the others, which is how we start to decode all of the frames. We ignore the C0 and 00 at the start. That is the KISS FEND marker for the start of the frame and the KISS command byte. We then have 14 bytes that encode the From and To callsigns:
A0 84 98 92 A6 A8 00 A0 8C A6 66 40 40 17
Each callsign is 7 bytes. The algorithm is well documented in the AX25 specification. It is just ASCII characters shifted one bit to make room for an "end of callsign list" bit. It also includes the SSID which allows the same callsign to have more than one destination on a single AX25 frequency. It's a bit like a computer port. I have implemented the callsign decoding in an AX25 Frame class. When we run it, we see that the two callsigns are:
From: PFS3-11
To: PBLIST
PFS3-11 is the Broadcast Callsign of the spacecraft. PBLIST is a destination that it uses for Status updates.
There are only two more bytes before we hit the ASCII data and they are: 03 F0. If we look in the AX25 specification then the byte straight after the callsign list is the control byte which indicates what type of AX25 frame this is. 03 is a UI frame. The next byte then tells us what protocol is used for the data, called the PID, and F0 means there is no protocol. So we just take the rest of the data as an information message.
Data is broadcast from the satellite with several different formats, all under the banner of the Pacsat protocol. After status messages like the one above, the next type I decoded are broadcast messages. These have the PID set to BB for file broadcasts and BD for directory broadcasts. This is all explained in the Broadcast Specification, though you have to make sure you also read the updates: Broadcast Spec Update 1, Broadcast Spec Update 2, Broadcast Spec Update 3
The broadcast frames were relatively easy to decode because they are easy to spot and they just contain a chunk of data. The File Broadcast frames contain a file id and an offset. I wrote them to a Random Access file with the given offset and it creates the file on disk. If I received all of the frames then I had the complete file. With very little coding. However there is significant meta data at the start of the file, which is explained in the Pacsat File Header Specification. That needs to be parsed if we want to make sense of the files. We also need keep track of the missing data, or holes, in the files so we can request the parts of the files that we missed. I'll discuss the PacSat File Headers and holes in another post, because they turned out to be tricky.
The uplink uses AX25 in connected mode, which means that all of the AX25 frame types need to be understood and decoded. I have written the code to decode the frames but I have not yet started on the uplink.
73
Chris
Enter Comments Here:
On: 08/03/18 15:15 Aitor EB2AT said: |
Yesterday I tried TS-790 and a TNC-2 but it seems to me that PSGS does not put the TNC in KISS mode. I did not receive anything until I put it in KISS with WISP and then I was able to receive with PSGS. I'm not sure, I have to try this again. In the next pass I got to download the directory and select messages to download and download them. It seems you're on the right way, congratulations, |
On: 08/03/18 15:15 Aitor EB2AT said: |
Today I tried to receive with an SDR dongle. The path is USB_DONGLE_RTL -> HDSDR -> VB Audio Cable -> UZ7HO softmodem -> HW Virtual serial port -> PSGS. It works well. Maybe you could configure the data flow to TNC by COM port as now and add TCP-IP connection for softmodem like AGW-UZ7HO kind. |
On: 08/03/18 17:17 Chris G0KLA said: |
Aitor, There is definitely some tricks needed to get some TNCs into KISS mode. Do you have a genuine TNC-2 or a TNC-2 clone? It might go into KISS but FULL DUPLEX may not be on. I have had that issue with another TNC. Glad to hear that the SDR works. I will definitely provide support for decode from a TCP-IP port for SoundModem or others. I need to check how it works, but it should be easy. |
On: 08/05/18 4:04 Aitor EB2AT said: |
Hi Chris, I have tested with a TNC TAPR and it works fine. This TNC is identified as "Tucson Amateur Packet Radio TNC-2 AX.25 Level 2 Version 2.0 + BLP Host Mode 1.0 Release 1.1.9 12/26/94 - 32K RAM " The other one does not work if I did not previously configure it in KISS mode. This TNC is identified as "TheFirmware Version 2.7 DAMA / SMACK / XHOST (2553 Bytes * 10 Channel) Copyright by NORD> <LINK, 21-Sep-94 " So I think that WISP sends something like this to initialize it ESC @ K Switch to KISS-mode. ESC @D [0 | 1] Disable / enable full duplex mode. as described in https://ralfzimmermann.de/tf26_2.html#Description%20of%20Commands> I will try a COM port sniffer to see the initialization commands. But it is not a priority issue. |
On: 08/05/18 8:08 Chris G0KLA said: |
Aitor, let me know the sequence. I will have to add the ability to send special bytes to put some TNCs into KISS mode. And thanks for pointing out the bug with < and >. I have fixed that. |
On: 08/15/18 4:04 EA8CXN said: |
Hello, I'm trying it into a linux raspberry with a TNC... By the moment the software power up but there is no way to change the path of the TNC, I will continue investigating! Best Regards and very good job! |
On: 08/15/18 4:04 EA8CXN said: |
Finally I found how to fix it. In the /home the software made a file .conf, I edit it and problem solved! Now I'm waiting to the next pass to test it. |
On: 08/15/18 9:09 Chris G0KLA said: |
Great to hear that it runs on the Raspberry Pi. I don't know how COM ports are selected on Linux. Which file did you need to edit and what did you put in it? Let me know if it works. |
On: 08/23/18 8:08EA8CXN said: |
On the raspberry pi the COM ports depend of the ussed model. I have the Raspberry Pi 3B with a TNC-PI 9k6. My COM port address is /dev/serial0. By the moment I run your software with sudo command, to allow access to the TNC with: sudo java -jar PacSat.... The file is automatically created on the software's folders.The exact name is PacSatGround.properties My set up is the following: #PacSat Ground Station Properties #Sun Aug 19 00:03:40 UTC 2018 spacecraft_window_width=600 settings_window_width=1282 logfile_dir= TNC_DATA_BITS=8 home_dir= TNC_TX_DELAY=130 mainwindow_y=29 mainwindow_x=120 logging=true settings_window_y=34 settings_window_x=-2 callsign=EA8CXN mainwindow_height=641 TNC_STOP_BITS=1 spacecraft_window_height=400 spacecraft_window_y=100 TNC_PARITY=0 spacecraft_window_x=100 mainwindow_current_dir=/home/pi/Desktop/PacSatGround_v0.06 settings_window_height=686 TNC_BAUD_RATE=9600 mainwindow_width=776 use_native_file_chooser=false COM_PORT=/dev/serial0 By the moment I can not test it due to my job! Best Regards |
Copyright 2001-2021 Chris Thompson
Send me an email