In my last post about gr-satellites 3, I announced that gr-satellites would start to support all the AX.25 satellites transmitting in Amateur bands. Historically, gr-satellites didn’t support packet radio (AFSK and FSK AX.25) satellites since there were too many of them and there were already other good decoders such as Direwolf. At one point Rocco Valenzano W2RTV convinced me to add “generic” packet radio decoders to gr-satellites and since then these have been seeing quite some use.
In gr-satellites 3 it is very easy to add new satellites, since this is done with a SatYAML file, which is a brief YAML file describing basic information about the satellite and its transmitters. Therefore, I decided to make a script to get this data from SatNOGS DB and write the SatYAMLs automatically for all the AFSK and FSK AX.25 satellites.
In principle, this should be an easy task. The following information is needed for the SatYAML file:
- The satellite name
- The satellite NORAD ID
- An optional list of alternative names for the satellite
- The downlink frequency of each transmitter
- Whether each transmitter uses AX.25
- Whether FSK or AFSK is used in each transmitter
- The baudrate of each transmitter
- Whether G3RUH scrambling is used in each transmitter
It is straightforward to get 1 through 4 from SatNOGS DB. However we reach a difficulty when trying to get 5. In SatNOGS DB, the only data about which kind of protocols a transmitter uses is the “mode”. The list of possible modes can be seen here. These are things like AFSK1k2 and FSK9k6, which are insufficient to identify which kind of decoder should be used for each satellite.
For a concrete example about this problem, compare the SatNOGS DB entries for Challenger and TY-2. Both are listed as FSK9k6, but they use really different protocols. Challenger uses a conventional packet radio mode with AX.25 and G3RUH encoding. It can be decoded with any packet radio modem supporting 9k6. On the contrary, TY-2 uses an AX100 transceiver in the ASM+Golay mode. It can only be decoded with gr-satellites and one of the UZ7HO’s soundmodems, as far as I know (as well as with the GOMspace groundstation GS100 hardware or with another AX100 transceiver).
Nevertheless, SatNOGS DB makes a distinction between FSK, GFSK, MSK and GMSK. This doesn’t make much sense in my opinion because the deviation or filtering used by an FSK satellite is often not documented publicly and it is not easy to measure it accurately over the air (and no one really cares to do so, honestly). Because of this, and as the difference between these four modes doesn’t usually help you to choose an appropriate decoder, many people (including myself ) will often not make a distinction and call everything FSK. Thus, I bet that a lot of this information in SatNOGS DB is wrong (most satellites listed as FSK will use some form of Gaussian filtering, for example).
Therefore, unfortunately it is not easy to determine if a satellite transmits AX.25 by using the information from SatNOGS DB. Most of the satellites using AFSK1k2 will transmit AX.25 with no scrambler and most of the satellites using FSK9k6 will transmit AX.25 with a G3RUH scrambler, but there are many exceptions (and it has been the gr-satellites main goal to support all these exceptions).
Since the list of satellites using AFSK or FSK is relatively large and the modes used by each satellite are not very well documented if one tries to search in Google, it is very time consuming to try to filter this list by hand to check which satellites use AX.25. Therefore, I decided to try to use the telemetry stored in SatNOGS DB to infer which of the satellites use AX.25.
This idea is based on the fact that the AX.25 protocol uses a header with some particular properties. The AX.25 header is present at the beginning of each packet and it has at least 16 bytes. The first 14 bytes essentially contain the AX.25 addresses, which are encoded in a certain way (as ASCII characters using the 7 most significant bits of each byte). Therefore, we can fetch a few telemetry frames for each satellite from SatNOGS DB and try to check if the beginning of each frame is formatted as an AX.25 header.
There is the problem that the teams of many AX.25 satellites have gotten some aspects of the AX.25 standard wrong and the headers transmitted by their satellite are malformed. Therefore we need to use some heuristics to allow for this. The algorithm I have come up with goes as follows. For each satellite we do:
- Take the first 16 bytes of each frame and group them counting repetitions. The idea is that almost all AX.25 satellites will always transmit the same first 16 bytes in each frame, so there might be a few erroneous frames in the database, but most of them should have the same first 16 bytes. In contrast, most non-AX.25 satellites already have some data in the first 16 bytes which varies between different frames. A satellite passes this test if the most popular 16 byte sequence occurs more than 4 times than each of the other sequences.
- If the satellite has passed 1, try to decode the two AX.25 addresses according to the standard. If the decoded addresses are only composed of printable characters, then the satellite passes the test.
- There are several satellites with malformed AX.25 headers that fail 2. If a satellite didn’t pass 2, we examine its addresses manually to see if they look reasonable. If they do, we add the satellite to the “good list” manually. If they don’t, a quick search in Google can reveal that the satellite uses AX.25, and so it is added to the “good list” also. If the Google search doesn’t give a clear indication, then it is considered that the satellite doesn’t use AX.25.
This kind of algorithm determines quite well if a satellite uses AX.25 or not. Only a few of them need to be examined manually in 3.
Getting the baudrate and whether the satellite uses AFSK or FSK is trivial. However, checking if a satellite uses G3RUH or not is again difficult, since there is no information about this in the SatNOGS DB or in the telemetry frames.
The heuristic I have used here is the de-facto standard for packet radio. At 1k2, AFSK with no scrambling is used. At 9k6, FSK with G3RUH scrambling is used. Regarding Amateur satellites, those using 4k8 or 19k2 FSK generally do so as a variation of the 9k6 mode, so G3RUH scrambling is also used for these modes. However, there is no common practice about what to do for 1k2 FSK or for 2k4 FSK, and these modes are rarely used.
Thus, I have decided to classify 1k2 AFSK as non-scrambled and 4k8, 9k6 and 19k2 as G3RUH as scrambled. For everything else, an error is flagged. It turns out that we only get errors for INS-1C, NIUSAT and AAUSAT-II, all of which use 1k2 FSK. INS-1C indeed transmitted 1k2 FSK unscrambled AX.25. I have no information about NIUSAT, and I have been unable to confirm whether AAUSAT-II uses AX.25 or not (the later cubesats from Aalborg University don’t). Thus, I have made a SatYAML file for INS-1C manually and ignored the other two.
I have implemented a script in this Jupyter notebook to run the heuristics described above and write the SatYAML files. With the help of this script, files for 68 satellites have been written automatically and added to the gr-satellites next branch. This raises the number of satellites supported by gr-satellites to 133, so I don’t think it is any longer fair to judge gr-satellites by the number of satellites it supports, since many of them use the same decoder. I think it is more fair to count the number of different deframers, and currently there are 24.
I am tempted to do the same kind of thing for BPSK AX.25 satellites. These are far fewer than the AFSK/FSK AX.25 satellites and I have taken the care to keep adding support for them in gr-satellites (even in v1), but some may have slipped. However, here the heuristic for guessing if scrambling is used doesn’t work well. For 1k2 BPSK there are satellites using scrambled AX.25 and satellites using unscrambled AX.25.