The modulation that the FUNcube satellites use is DBPSK at 1200baud. The coding is based on a CCSDS concatenated code with a convolutional code and Reed-Solomon, but it makes extensive use of interleaving to combat the fading caused by the spin of the spacecraft. This system was originally designed by Phil Karn KA9Q for AO-40. Phil has a description of the AO-40 FEC system in his web and there is another nice description by James Miller G3RUH.
I took a glance at this documents and noted that it would be a nice and easy exercise to implement a decoder in GNU Radio, as I have most of the building blocks that are needed already working as part of gr-satellites. Today, I have implemented an out-of-tree module with a decoder for the AO-40 FEC in gr-ao40. There is another gr-ao40 project out there, but it seems incomplete. For instance, it doesn't have any code to search for the syncword. I have also added decoders for AO-73 and UKube-1 to gr-satellites.
The signal processing in gr-ao40 is as described in the following diagram taken from G3RUH's paper.
First, the distributed syncword is searched using a C++ custom block. It is possible to set a threshold in this block to account for several bit errors in the syncword. De-interleaving is done using another C++ custom block. For Viterbi decoding, I have used the "FEC Async Decoder" block from GNU Radio, since I like to use stock blocks when possible. Then, CCSDS descrambling is done with a hierarchical block from gr-satellites. Finally, the interleaved Reed-Solomon decoders are implemented in a C++ custom blocks that uses Phil Karn's libfec.
The complete FEC decoder is implemented as a hierarchical block as show in the figure below.
I've been looking at an erasure code by Luigi Rizzo which is based on Vandermonde matrices, since this code is used in Outernet. In fact, it is the code implemented by the zfec library. Luigi Rizzo describes his code in a paper from 1997, but the paper can be very confusing and misleading because it describes the mathematics in very little detail. I needed to go to the source code to understand how it works. Actually, the idea behind this code is very simple. Here I do a mathematical description of the code and show that it is the same as a Reed-Solomon code. This is rather weird, because Luigi Rizzo makes no mention of Reed-Solomon codes, which were first described in 1960.
In my previous post I talked about some small updates made by George Hopkins to my free-outernet project. In fact, George has been reverse engineering the ondd binary quite in depth and he has been able to reverse engineer the LDPC code which is used for file FEC. This solves a long-standing issue of free-outernet. Formerly, LDPC decoding was not implemented, so to recover a file successfully all the file blocks had to be received correctly. Now, with LDPC decoding the file can be recovered even if some of the file blocks are lost. Thus, the performance of free-outernet in this aspect should now be the same as the performance of the closed source ondd binary included in the official Outernet receiver. Many thanks to George, as this is a substantial improvement of free-outernet. Here I describe the latest changes made by George in free-outernet.
Thus, the last field of the LDP header as described in my previous post, which was formerly known as "B field", gets now included in the payload of the package. The former "A field" is now the only field that identifies the port or service, and therefore it is now known as "type". For file and FEC blocks, this change is small, because the former "B field" was always 0, so it gets incorporated into the "file id" field of the payload, which is now 24 bits long instead of 16 bits. For time packets it provides a nice way to interpret the packet as a variable record field structure. This interpretation now explains all the contents of the time packet.
After reviewing and merging George's changes and while I still have these details fresh in my mind, I have updated the slides I used in my 33C3 talk to reflect these changes. These are the updated slides.
Recently, Wei BG2BHC has published instructions for the use of BY70-1's camera by Amateurs. Essentially, there are three commands that can be used: 0x00 to take a picture and send it, 0x55 to take a picture and store it in memory, and 0xaa to send the picture stored in memory. He also gives the modulation and coding details for the commands. They use AX.25 with 1000baud FM-AFSK with tones at 1000Hz and 1833.33Hz. The AX.25 frames are UI frames containing a single byte with the command (0x00, 0x55 or 0xaa as described above). For ease of use, he also gives WAV recordings of the three commands, so they can be played back easily into an FM transmitter by any Amateur. Here I look at the contents of these WAV files and how to process and create this kind of packets.
Recently, I have been working on decoding KS-1Q and I've seen that it uses the same CCSDS coding as the HIT satellites. This has made me realise that most of this CCSDS coding can be processed using stock GNU Radio blocks, without the need for custom blocks. The only exception is Reed-Solomon decoding. This can be done easily with gr-libfec, which provides an easy interface from GNU Radio to Phil Karn's libfec. Here I look at the details of the CCSDS coding and how to process it with GNU Radio. I've updated the decoders in gr-satellites to use this kind of processing. I'll also talk about the small advantages of doing it in this way versus using the custom implementation in gr-lilacsat.
In a previous post, I talked about my attempts to decode KS-1Q. Lately, WarMonkey, who is part of the satellite team, has been giving me some extra information and finally I have been able to decode the packets from the satellite. The decoder is in gr-ks1q, together with a sample recording contributed by Scott K4KDR. I've also added support for KS-1Q in gr-satellites. Here I look at the coding of the packets in more detail.
The Amateur satellite BY70-1 launched yesterday at around 3:00UTC. The launch was a partial failure, as all the satellites from this launch have been put in a 520x220km orbit. The perigee is too low to support a long duration orbit, and the satellites will decay in a couple months. BY70-1 has a 9k6 BPSK telemetry downlink on 70cm. This downlink is also used to download JPEG images from the onboard camera. I've talked about this in a previous post.
Since I'm at 33C3, I haven't been able to receive this satellite with my own equipment yet. However, Tetsu JA0CAW already has posted some IQ recordings. Here I look at recording1 and recording2.
My first impression is that the packets are not very strong. I don't know if this is something about JA0CAW's station or that the downlink of BY70-1 is not very strong. I've only managed to decode the strongest packets in the recording. In comparison, LilacSat-2 has a very strong downlink and I can decode correctly almost from horizon to horizon with a handheld 7 element yagi.
Perhaps it's possible to do some optimization of the decoder parameters such as filter width or loop bandwidths, but so far I haven't experimented much. I just wanted to write a quick post to publish all the information I've managed to decode. I'm using the decoder from gr-satellites. The decoder log from recording1 is in this gist. From recording2 I could only decode a couple of JPEG packets and no telemetry packets.
There are three distinct types of telemetry packets. It seems that BY70-1 transmits all the three types in a single burst. Another curiosity: the message in one of the telemetry packets uses the callsign ON02CN, which is the Belgian callsign that LilacSat-1 will use. Since LilacSat-1 is part of the QB50 project, it makes sense that it uses a Belgian callsign. However, it seems that it's some sort of software configuration error that BY70-1 is also using this callsign.
Update on 30/12/2016: I have found that there was a problem with the Costas loop bandwidth in the GNU Radio receiver on gr-satellites. Its value was too large. I have copied the value from the example demodulator on gr-lilacsat and now the decoder works much better. I have even been able to decode the following image from recording2.
The result looks pretty bad, but the keen eye will notice that in fact there are few packets lost in this JPEG image. Compare with the image posted by BG2BHC, which has no errors and is presumably the same image.
If you've being following me on Twitter lately, you should already know that I've being giving a talk this morning at 33C3 about my work reverse engineering Outernet. In cased you missed the talk, the recording and the slides are already up. Many thanks for the organization for their wonderful recordings and streamings of the talks and for keeping everything running smoothly.
BY70-1 is a Chinese Amateur satellite that will launch on Monday 26 December. It has a V/U FM repeater, a camera and a 9k6 BPSK downlink on 70cm that transmits telemetry and the JPEG images taken by the camera. The BPSK downlink uses the same modulation and coding as LilacSat-2, of which I have spoken several times. Recently, Wei MingChuan BG2BHC has added support for the image downlink of BY70-1 to gr-lilacsat and a bit stream recording to test the image receiver.
Unfortunately, the image decoder is closed-source, as it contains some certification methods used to avoid fake packets over the internet. However, Wei gave me a brief description of how the image downlink protocol works. After seeing the closed-source decoder running, I had enough to figure out how the protocol works. I have implemented an open-source image decoder as a python GNU Radio block. It is in my gr-lilacsat fork, and it will soon be included in the upstream gr-lilacsat repository. Here I look at the protocol used for the image downlink.