Decoding ERMINAZ

ERMINAZ-1U and ERMINAZ-1V are upcoming 1P PocketQubes by AMSAT-DL that will be launched in Rocket Factory Augsburg first flight from SaxaVord (Shetland, UK) later this year, together with other PocketQubes from AMSAT-EA and Libre Space Foundation. The ERMINAZ-1 satellites are based on the Libre Space QUBIK design and use the same communications system. Recently I have added a decoder for the ERMINAZ-1 satellites to gr-satellites and tested it using some pre-flight recordings that the team has shared with me.

The QUBIK communications stack uses something know as OSDLP (Open Space Data Link Protocol), which was developed by Libre Space based on CCSDS. Unfortunately, there is not much documentation about OSDLP. The best I’ve found are these slides, which only speak about the Data Link and higher layers. A look at the QUBIK transceiver GNU Radio flowgraph that AMSAT-DL is using with these satellites, together with some gr-satnogs blocks used in the flowgraph has been quite useful to figure out how the Synchronization and Coding layer of QUBIK works. In the rest of this post I will document my findings.

As usual with small satellites, the transmitter uses packets rather than a continuous signal. The modulation is simple enough: 9600 baud GFSK with a deviation of 3000 Hz.

To decode the Synchronization and Coding layer, the AMSAT-DL flowgraph uses a gr-satnogs block called IEEE 802.15.4 Decoder Definition. In the flowgraph there is also a provision for a Viterbi Decoder that runs before the IEEE 802.15.4 decoder, but in the recordings I’ve seen this is not used. Saying that something uses IEEE 802.15.4 without specifying more details is not very helpful, because the 802.15.4 standard is quite large and includes several fundamentally different PHYs, that use modulations as varied as O-QPSK, BPSK, Chirp Spread Spectrum, FSK, and OFDM (chapters 12 through 31 of the 2020 version of the standard are each dedicated to a different PHY).

Moreover, it appears that calling this IEEE 802.15.4 is a red herring, at least in the way that it is used QUBIK. The gr-satnogs ieee802_15_4_variant_decoder is a rather generic and flexible block that depending on its configuration, has nothing to do with IEEE 802.15.4. In the case of QUBIK, I didn’t recognize any of the settings as something actually taken from one of the 802.15.4 PHYs.

At the beginning of the packet there is a preamble formed by a repeating sequence of 0011 bits. This is a somewhat intriguing choice given that the sequence 01 is much more common. The sequence 0011 appears to have half the baudrate and probably is not a great sequence to train a symbol clock recovery loop, although it has plenty of bit transitions. After the preamble, there is the syncword 0x3C674952, transmitted MSB-first. I don’t know where this choice of syncword has come from.

Following the syncword there is a fixed-length payload of 164 bytes (1312 bits). I will explain the order of operations on the payload from the perspective of the decoder, since it is unusual. First, a (164, 132) Reed-Solomon code is decoded. This Reed-Solomon code is the one in the CCSDS TM Synchronization and Channel Coding Blue Book, but using the conventional basis instead of the dual basis. After Reed-Solomon decoding, the payload is descrambled using the CCSDS synchronous scrambler (also from the TM Synchronization and Channel Coding Blue Book). This is not CCSDS compliant, because CCSDS specifies that descrambling is done before Reed-Solomon decoding (i.e., the scrambler is applied to the whole Reed-Solomon codeword including the parity check bytes, not just to the systematic part of the codeword).

The 132 byte information word is formed by a 128 byte payload followed by a CRC-32C calculated over all the payload. The 128 byte payload is a TM Transfer Frame as specified in the CCSDS TM Space Data Link Protocol Blue Book. The Transfer Frame includes the Frame Error Control Field (CRC-16-CCITT-FALSE). Having two consecutive CRCs in the frame is awkward and not too useful.

The spacecraft ID in the recording that I’ve seen is 0x16, which is indeed assigned to ERMINAZ-1U in the SANA registry (and ERMINAZ-1V has 0x25 assigned).

One of the things that the ERMINAZ-1 satellites will transmit is SSDV images. Below are the first two TM Transfer Frames of an SSDV transmission, as parsed by gr-satellites. It seems that virtual channel ID 4 is used for SSDV. The data field of the Transfer Frame is not fully compliant with CCSDS. It does not contain CCSDS Space Packets or any other form of CCSDS Packets. Instead, the first two bytes of the data field (0x0076 in these two packets) indicate the length of the SDU in the data field (akin to the Space Packet packet length field, but saving 4 additional bytes of Space Packet Primary Header). I think this length field is generated by this piece of code. That code makes it seem like only one SDU can be carried in each TM Transfer Frame (unlike CCSDS Space Packets, which support aggregating multiple Packets in a single Transfer Frame). Although the code also refers to a CLCW which is actually not present.

The TM Space Data Link Protocol allows sending data which is not formatted as CCSDS Packets. This is known as the Virtual Channel Access service, but it requires the synchronization flag in the TM Primary Header to be set to 1, while it is 0 in this case (which is used to indicate that the payload consists of CCSDS Packets, as defined by the Virtual Channel Packet service).

-> Packet from 9k6 FSK downlink
Container:
primary_header = Container:
transfer_frame_version_number = 0
spacecraft_id = 22
virtual_channel_id = 4
ocf_flag = False
master_channel_frame_count = 6
virtual_channel_frame_count = 1
secondary_header_flag = False
synch_flag = False
packet_order_flag = False
segment_length_id = 3
first_header_pointer = 0
data_field = hexundump("""
0000 00 76 55 67 CB AC AA D9 03 00 00 1E 13 00 00 00 .vUg............
0010 00 E4 4D 34 D4 8A AA DC 16 DA 7B 13 D2 95 E0 75 ..M4......{....u
0020 ED 91 EA 39 15 4D A1 D9 90 D1 41 18 A2 81 09 48 ...9.M....A....H
0030 69 4D 25 00 14 0A 29 29 80 A4 D3 4D 29 A0 9A 06 iM%...))...M)...
0040 26 68 24 62 93 39 A2 80 02 69 29 69 28 00 A2 8A &h$b.9...i)i(...
0050 4A 00 5C D1 9A 28 A0 02 81 45 14 00 66 8C D1 40 J.\..(...E..f..@
0060 19 A0 02 94 64 D2 85 A7 85 A2 E0 20 5A B3 69 67 ....d...... Z.ig
0070 71 7B 30 86 6F 43 36 61 q{0.oC6a
""")

-> Packet from 9k6 FSK downlink
Container:
primary_header = Container:
transfer_frame_version_number = 0
spacecraft_id = 22
virtual_channel_id = 4
ocf_flag = False
master_channel_frame_count = 7
virtual_channel_frame_count = 2
secondary_header_flag = False
synch_flag = False
packet_order_flag = False
segment_length_id = 3
first_header_pointer = 0
data_field = hexundump("""
0000 00 76 55 67 CB AC AA D9 03 00 01 1E 13 00 32 00 .vUg..........2.
0010 0D DE 26 91 CF 60 3A 7D 7D 2A FE 91 E1 FB CD 5A ..&..`:}}*.....Z
0020 41 E5 A1 48 73 CC AC 38 C7 B7 AD 7A 3E 91 A1 DA A..Hs..8...z>...
0030 E8 F6 FB 21 52 CE D8 2E ED D5 8D 66 E5 7D 22 55 ...!R......f.}"U
0040 AD AB 3F 4D 2F C0 B7 12 4C 1E FE 45 8E 11 83 B6 ..?M/...L..E....
0050 33 96 6F 6F 6A EE 6D 2C AD EC 2D D6 0B 68 96 28 3.ooj.m,..-..h.(
0060 D7 B2 8E BE E7 D6 A7 24 28 24 90 00 EA 4D 62 DF .......$($...Mb.
0070 EB AB 19 31 64 8C 25 99 ...1d.%.
""")

The SDU is a 118 byte SSDV packet. The header of this SSDV packet follows the standard format defined by SSDV, although the packet length is not standard (standard SSDV packets are 256 bytes long). Apparently now the SSDV software has an option to specify a packet size manually, so this can be readily handled.

I have modified a Python script that I wrote for JY1SAT to extract the SSDV images from a KISS file containing TM Transfer Frames from ERMINAZ-1 (such as the output files produced by gr-satellites). This works with the upstream SSDV decoder from Philip Heron, rather than my fork that supports the non-standard modes used by DSLWP and JY1SAT. When this script is run with the KISS file obtained from one of the test recordings, it outputs the following images.

Calling SSDV decoder for image 0x3
Callsign: DP0SAT
Image ID: 03
Resolution: 480x304
MCU blocks: 570
Sampling factor: 2x2
Quality level: 4
Read 201 packets

Calling SSDV decoder for image 0xff
Callsign: DP0SAT
Image ID: FF
Resolution: 144x144
MCU blocks: 324
Sampling factor: 1x1
Quality level: 4
Read 50 packets
Image 0x03
Image 0xFF

4 comments

  1. Thank so much for introducing us to these new satellites! Looking forward to seeing them in orbit.

    Couple of questions, please:

    #1, I don’t see your usual link to a .GRC file as an example of how to decode these downlinks… do we just use the generic ‘satellite_decoder’ flowgraph with the new ERMINAZ-1U.yml file?

    #2, would it be possible to share a link to the sample input file(s) so that we have a source to test with?

    Thanks as always!

    1. Hi Scott,

      #1. Yes. The Satellite Decoder block and the gr_satellites command line tool can be used with the ERMINAZ-1U.yml. As for most satellites in gr-satellites, there is no specific flowgraph. There will also be an ERMINAZ-1V.yml file, but at the moment the satellites don’t even have a temporary NORAD ID from SatNOGS.

      #2. I assume that at some point AMSAT-DL will publish some sample recordings.

  2. I was able to locate a sample file on PEOSAT’s site (https://www.pe0sat.vgnet.nl/download/ERMINAZ/) and it does produce a large number of decoded frames. (unknown if SSDV)

    Regarding:
    ———————————
    I have modified a Python script that I wrote for JY1SAT to extract the SSDV images from a KISS file containing TM Transfer Frames from ERMINAZ-1
    ———————————
    … would it be possible for you to share that script? Or, if another method is preferable, please provide some more detail on how to go from the decoded packets in GNU Radio to an SSDV image?

    Thanks!

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.