B2b signal of Chinese positioning satellite BeiDou Part 2

category: gnss


BeiDou, a China’s positioning satellite system, has all orbit constellations of: medium-altitude orbit (MEO), geostationary orbit (GEO), and inclined geosynchronous orbit (IGSO). I am particularly focused on PPP-B2b broadcast by BeiDou 3rd generation (BDS-3) series GEO satellites. This is an informational message delivered on B2b signals that increases positioning accuracy.

Based on the published PPP-B2b specification BDS-SIS-ICD-PPP-B2b-1.0, I wrote a code (bdsb2read.py) to read the PPP-B2b message contents. Let us observe the actual PPP-B2b message content with this.

B2b signal receiver

In order to observe BeiDou’s precise point positioning (PPP) message, PPP-B2b, the radiowaves of the B2b signal are received, demodulated, error corrected, and decoded according to the procedures in the specifications.

As far as I know, the receiver that can receive B2b signals, perform error correction, and output the raw data is an open-source software defined radio Pocket SDR receiver and Septentrio’s mosaic-go X5 receiver. I own both of these receivers.

In particular, Pocket SDR achieves 64-ary LDPC error correction in a concise form, which is one of the difficulties in outputting raw data. It’s awesome. I have also tried this LDPC decryption, but I have not been able to do it until now. I personally enjoy using the Pocket SDR receiver every day, including receiving signals other than B2b signals.

On the other hand, the mosaic-go X5 receiver also implements 64-ary LDPC error correction. On page 276 of Reference Guide.pdf included in Septentrio mosaic-X5 Firmware v.4.14.4, we can found a description:

The receiver attempts to correct bit errors using the LDPC parity bits, but unrecoverable errors are still possible at low C/N0. It is therefore always needed to check the CRC status before using the navigation bits.

I am making the output of the mosaic-go X5 receiver, which I use for regular observation, available to the public. The live stream, which can be accessed via the Internet, contains the B2b raw data observed with my mosaic-go X5 receiver and its archive is also included. This public data is available to anyone free of charge without prior notice.

Observing B2b signals

str2str included in RTKLIB ver.2.4.3 b34 and QZS L6 Tool to observe the B2b signal live stream information.

This live stream is output in the raw data format of the Septentrio receiver. Here we use QZS L6 Tool’s Septentrio receiver decoder septread.py along with str2str.

$ str2str -in ntrip://ntrip.phys.info.hiroshima-cu.ac.jp:80/B2B 2> /dev/null | septread.py

2024-04-08 00:15:26 BDSRawB2b C35 eb908d078554847730480cdafebfec2e800f1e3fc3d4969affc103828001ffd20010518877203dc080001fdc360c945aa202a57fff08747bfdc122d8e06c94d497c0e39bea2feae75f9264acb6ad443b660b26edd283939c686def490e73bcf1d50d9b0e41f0e12ca0bebace651b4343f8a587a37154021aa906df00e7
2024-04-08 00:15:26 BDSRawB2b C26 eb9069078554847730483704d71ff430800ef23fc3d4969affc103828001ffd20010518877203dc080001fdc360c945aa202a57fff08747bfdc122d8e03ce0760e3196795eb1e4bcca31ac826274f033268ee0fd28d4dc3558525025c68e476d1691c1b4dc4f48994059548f16bbe9816aeccbb34b2216f80cac411c88
2024-04-08 00:15:26 BDSRawB2b C44 eb90b1078554847730480e527d60190c000f2f3fc3d4969affc103828001ffd20010518877203dc080001fdc360c945aa202a57fff08747bfdc122dfe03aaa42cc17bfbb390e645933645023c1cbc4deefe02b10b9b3acc79068b8a9d26bfe59fb3021512fcf415bc53aefe01b369cc31329365713d4d1e042b875095b
2024-04-08 00:15:26 BDSRawB2b C45 eb90b52285548609060037e780136f0a665ffc1d97e17602c007186c40c02d95a04f5329b89af87c05dab004468013003700403400205780f1000345209ec3bde00df0e2469cf8bdf50dd14d1a488dd5295673fbd5a8e9c26e98809e258fe2ad72b4d6d71dd8bea1c1e44148fd820b5f839cc081e023360c148fdfa5e7
2024-04-08 00:15:26 BDSRawB2b C39 eb909c078554847730483fbe097fffb1000f283fc3d4969affc103828001ffd20010518877203dc080001fdc360c945aa202a57fff08747bfdc122dfe032646fbe9b41f2734e36d8da429acfcfae7b06a34cdbeed11d8d6dc3dc6c2b20bd620078decaaf984396bf1f95d776f8df1da3da714960b9e871ceec012fbd7c
2024-04-08 00:15:26 BDSRawB2b C40 eb90a0078554847730483de38e5ffc08800f1b3fc3d4969affc103828001ffd20010518877203dc080001fdc360c945aa202a57fff08747bfdc122dfe015d8096da97986ca877d9e7d70c3920fa7b09d3ebc0ef346a5546b8cd1be15888790ffd2d37e0f34a8d4fb65177630d2db3188e3d2a93e18ecb5c59769d0bdb8
2024-04-08 00:15:26 BDSRawB2b C59 eb90ec01007344908400110004400110004400110004826ba000040011000440019fefc40010000000000000000000000000000000000000000000000002f8b5f9926de359888ef5aceedd27e5bba028504f6e099ce6e11c8ca102d639724cd9c7639231195ba460d87d7fcc3f606c2ae03c054556435277e9cbf57d3f
2024-04-08 00:15:26 BDSRawB2b C62 eb90fbf1007345188400110004400110004400110004827cbfb2840011000440019fe2c400100000000000000000000000000000000000000000000000006f4a22f0ffe7ced4b870f4e033822573fb43faf005c8fe6297dcb90ba955d37fc56de39aa5113cb6d76c8935ce964ba26ec40b6f035dd37b50ee2a86f6a294

This output consists of the date and time (UTC), the mosaic-X5 receiver’s raw data message name BDSRawB2b, the satellite name (such as C35), and the raw data in hexadecimal notation.

PPP-B2b messages are broadcast from the BDS-3 GEO satellite. The candidate satellites are C59, C60, C61, and C62, but the latter two are in testing status. A new navigation message B-CNAV3 will be broadcast from the BDS-3 MEO satellite. PPP-B2b and B-CNAV3 use the same format.

First, we observe all B2b signal messages without specifying any satellites. We get the raw data with str2str, extract the B2b message with the -b option of septread.py of QZS L6 Tool, and extract the message with bdsb2read.py.

$ str2str -in ntrip://ntrip.phys.info.hiroshima-cu.ac.jp:80/B2B 2> /dev/null | septread.py -b | bdsb2read.py
C39 MT5  URA   03:03:41 IODSSR=1 IODP=5 IODSSR mismatch
C40 MT5  URA   03:03:41 IODSSR=3 IODP=9 IODSSR mismatch
C59 MT4  CLOCK 00:29:28 IODSSR=1 IODP=2 IODSSR mismatch
C62 MT4  CLOCK 00:29:28 IODSSR=2 IODP=3 IODSSR mismatch
C60 MT4  CLOCK 00:29:28 IODSSR=1 IODP=2 IODSSR mismatch
C35 MT10 EPH  00:29:35+1 TOE=288 sattype=3
C26 MT10 EPH  00:29:35+1 TOE=288 sattype=3
C44 MT10 EPH  00:29:35+1 TOE=288 sattype=3
C24 MT10 EPH  00:29:35+1 TOE=288 sattype=3
C45 MT30 CLK  2024-04-08 00:29:31
C39 MT30 CLK  2024-04-08 00:29:31
C40 MT10 EPH  00:29:35+1 TOE=288 sattype=2
C59 MT4  CLOCK 00:29:28 IODSSR=1 IODP=2 IODSSR mismatch
C62 MT4  CLOCK 00:29:28 IODSSR=2 IODP=3 IODSSR mismatch
C60 MT4  CLOCK 00:29:28 IODSSR=1 IODP=2 IODSSR mismatch
C35 MT30 CLK  2024-04-08 00:29:32
C26 MT5  URA   03:03:42 IODSSR=1 IODP=14 IODSSR mismatch
C44 MT30 CLK  2024-04-08 00:29:32
C24 MT30 CLK  2024-04-08 00:29:32
C45 MT10 EPH  00:29:36+1 TOE=288 sattype=3
C39 MT10 EPH  00:29:36+1 TOE=288 sattype=2
C40 MT30 CLK  2024-04-08 00:29:32
C35 MT10 EPH  00:29:37+1 TOE=288 sattype=3
C26 MT10 EPH  00:29:37+1 TOE=288 sattype=3
C44 MT10 EPH  00:29:37+1 TOE=288 sattype=3
C24 MT10 EPH  00:29:37+1 TOE=288 sattype=3
C45 MT30 CLK  2024-04-08 00:29:33
C39 MT30 CLK  2024-04-08 00:29:33
C40 MT10 EPH  00:29:37+1 TOE=288 sattype=2

This output consists of satellite name, message type (MT), MT message name, and content summary.

The content summary indicates that the PPP-B2b message cannot be decoded due to an inconsistency in the IODSSR (issue of data - state space representation). In this code, when PPP-B2b discovers the mask message MASK that should be received first, it retains the IODSSR. This code, then, checks consistency of IODSSR in the following messages of the clock correction CLOCK and the orbit correctionORBIT.

In the example above, the IODSSR of satellite C62 was different from the IODSSR of C59 and C60. Also, in this example, the IODP (issue of data - PRN) that manages satellite number (PRN: pseudo random noise) mask changes is different between C59 and C60.

PPP-B2b message observation with augmented broadcasting satellite specified

For example, we specify the satellite transmitting PPP-B2b messages of C59. We provide the -p 59 option to bdsb2read.py to specify the satellites, and also add the -t 1 option to it to display detailed information.

By specifying a satellite that broadcast the augmentation message, we were able to decode the message! Since decoding of augmentation information starts after receiving the mask message, it takes some time to start decoding. This type of time lag occurs similarly with other high-precision positioning methods such as Michibiki’s CLAS, MADOCA-PPP, and Galileo’s HAS.

$ str2str -in ntrip://ntrip.phys.info.hiroshima-cu.ac.jp:80/B2B 2> /dev/null | septread.py -b | bdsb2read.py -p 59 -t 1
C59 MT4  CLOCK 00:51:28 IODSSR=1 IODP=2 IODSSR mismatch
C59 MT4  CLOCK 00:51:34 IODSSR=1 IODP=2 IODSSR mismatch
C59 MT4  CLOCK 00:51:34 IODSSR=1 IODP=2 IODSSR mismatch
C59 MT4  CLOCK 00:51:34 IODSSR=1 IODP=2 IODSSR mismatch
C59 MT1  MASK  00:51:58 IODSSR=1 IODP=2 (updated)
 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 G01 G02 G03 G04 G05 G06 G07 G08 G09 G10 G11 G12 G13 G14 G15 G16 G17 G18 G19 G20 G21 G22 G23 G24 G25 G26 G27 G28 G29 G30 G31 G32
C59 MT4  CLOCK 00:51:58 IODSSR=1 IODP=2
SAT IODCorr clock[m]
C20       5   -0.634
C21       3    0.310
C23       3   -0.114
C59 MT4  CLOCK 00:51:58 IODSSR=1 IODP=2
SAT IODCorr clock[m]
C25       3    0.197
C26       7    0.208
C34       3    0.555
C35       4    0.589
C36       4   -0.544
C43       7    1.058
C45       3    0.000
C59 MT4  CLOCK 00:51:58 IODSSR=1 IODP=2
SAT IODCorr clock[m]
G01       0    0.000
G02       0    0.000
G03       0    0.000
G04       0    0.000
G05       0    0.000
G06       0    0.000
C59 MT3  CODE  00:51:12 IODSSR=1 numsat=3
SAT Signal Code   Code Bias[m]
C24 B1I                  1.122
C24 B1C(D)               2.465
C24 B1C(P)               2.482
C24 B2a(D)              -6.341
C24 B2a(P)              -5.559
C24 B2b-I               -5.389
C24 B2b-Q               -4.879
C24 B3 I                 0.000
C26 B1I                 -1.564
C26 B1C(D)              -0.136
C26 B1C(P)              -0.034
C26 B2a(D)              -5.848
C26 B2a(P)              -5.066
C26 B2b-I               -4.709
C26 B2b-Q               -4.148
C26 B3 I                 0.000
C29 B1I                  0.000
C29 B1C(D)               1.088
C29 B1C(P)               1.207
C29 B2a(D)              -5.882
C29 B2a(P)              -5.049
C29 B2b-I               -5.304
C29 B2b-Q               -4.777
C29 B3 I                 0.000

This result shows that, for example, for the ``C20’’ satellite, correction of the pseudo distance between the satellite and the receiver by -0.634 meters reduces positioning errors caused by the satellite clock error.

In this PPP-B2b message, the satellite clock correction for all GPS satellites seems to always be zero. The amount of orbit correction for GPS satellites showed different values for each satellite.

Currently, BeiDou and GPS seem to be the only satellites targeted for augmentation of PPP-B2b. In addition to BeiDou and GPS, the specifications specify augmentation for Galileo and GLONASS. Unfortunately, the Quasi-Zenith Satellite System, Michibiki, is not subject to augmentation in the specifications.

It is also possible to process the data in the archives mentioned above using commands such as cURL, which are included in many Linux distributions. For example, to display PPP-B2b messages 1 hour from 2024-04-05 00:00:00 UTC, do the following:

$ curl https://phys.info.hiroshima-cu.ac.jp/gnss/b2b/202404/20240405a.sept | septread.py -b | bdsb2read.py -p 60 -t 1 -c | lv

Here, lv is used as the pager. I specified the -c option to bsdb2read.py to get color output.

Of course, it is also possible to save the archive data in a file and display the file contents. Here, we are storing the archive data in the file b2b.sept.

$ curl https://phys.info.hiroshima-cu.ac.jp/gnss/b2b/202404/20240405a.sept > b2b.sept
$ septread.py -b < b2b.sept | bdsb2read.py -p 60 -t 1 -c | lv

B2b message decoding error

Errors may remain even after 64-value LDPC error correction of B2b signals. To detect such errors, a 24-bit CRC (cyclic redundancy check) code is added to the PPP-B2b message. When processing the above 1-hour observation data against C60, errors were sometimes detected by CRC.

CRC error on B2b message decode

Let’s count the number of errors in the observation data for this one hour.

$ septread.py -b < b2b.sept | bdsb2read.py -p 60 | wc -l
$ septread.py -b < b2b.sept | bdsb2read.py -p 60 | grep CRC | wc -l

Errors were detected in 142 messages (4.4%) out of a total of 3214 messages. I thought that the error correction of the mosaic-go X5 receiver might be incomplete.

Therefore, we utilize Pocket SDR’s 64-ary LDPC error correction code. Colocate the Pocket SDR’s Python source code with the QZS L6 Tool’s Python source code, and modify the QZS L6 Tool’s bdsb2read.py to further perform 64-ary LDPC error correction on this raw data.

# change this to 1 if you use 64-ary LDPC function of Pocket SDR (ref.[3])


        import sdr_ldpc
        import numpy as np
except ModuleNotFoundError:


        if POCKET_SDR_LDPC:  # if Pocket SDR (ref.[3]) LDPC python module is available
            syms = np.fromstring((b2b_data + b2b_parity).bin, 'u1') - ord('0')
            bits, _ = sdr_ldpc.decode_LDPC_BCNV3(syms)
            b2b_data = bitstring.Bits(bits)[:486]

As before, calculate the number of CRC error detections.

$ septread.py -b < b2b.sept | bdsb2read.py -p 60 | grep CRC | wc -l

The number of errors remained 142 and did not change with additional LDPC error correction. The mosaic-go X5 receiver was fully error correcting. mosaic-go X5 receiver, sorry for doubting you.

PPP-B2b message broadcast timing

For this 1-hour observation data b2b.sept, we will compare the messages from the C59 and C60 satellites, aligning the decoding start times. The left screenshot is for C59 result with septread.py -b < b2b.sept | bdsb2read.py -p 59 -c | lv, and the right screenshot is for C60 result with septread.py -b < b2b.sept | bdsb2read.py -p 60 -c | lv.

comparison between C59 and C60 PPP-B2b messages

Here IODSSR and IODP are matched between them. The content of both messages seems to be the same. However, the message broadcast timing differs between the two, and the time offset also varies.

BeiDou has multiple BDS-3 series GEO satellites. Simultaneous reception and process of B2b signals enable the receivers to obtain mask messages more quickly and achieve high-precision positioning in a shorter time. In that case, an algorithm is required to manage the IODP mismatch due to the possibility of broadcast timing differences.


I showed a decode example of BeiDou’s PPP-B2b message. The open source software radio Pocket SDR’s 64-value LDPC error correction code helps me improved understanding of PPP-B2b messages.

Currently, PPP-B2b messages broadcast from the C59 and C60 satellites are available. According to the specifications, PPP-B2b can provide high-precision positioning augmentation information for BeiDou, GPS, Galileo, and GLONASS. However, in my observation range, the targets were for BeiDou and GPS. Also, it seems that the clock correction for GPS satellites is always zero. Receiving B2b signals from multiple BDS-3 GEO satellites may shorten the time to start decoding augmentation messages.

Living in Japan, we can use all of the high-precision augmentation information of:

  • Galileo’s HAS,
  • BeiDou’s PPP-B2b, and
  • SBAS.

Additionally, we can obtain QZSS’s disaster information transmission, signal authentication messages, and Galileo’s new navigation messages. I am in a very privileged environment and I am enjoying it.

Related article(s):