changeset 53:c39111c37631

gnss-galileo: move I/NAV parsing into a dedicated file Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 16 Jan 2020 18:00:44 -0500
parents 2554cd13eddd
children c8c848632471
files CMakeLists.txt gnss-galileo-parse-inav.c gnss-galileo.c
diffstat 3 files changed, 264 insertions(+), 264 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Thu Jan 16 17:56:46 2020 -0500
+++ b/CMakeLists.txt	Thu Jan 16 18:00:44 2020 -0500
@@ -55,8 +55,8 @@
 )
 
 add_library(gnss
-	gnss-galileo.c
 	gnss-galileo-eph.c
+	gnss-galileo-parse-inav.c
 )
 
 target_link_libraries(gnss
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnss-galileo-parse-inav.c	Thu Jan 16 18:00:44 2020 -0500
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "gnss-galileo.h"
+
+#include <jeffpc/types.h>
+#include <jeffpc/error.h>
+
+static inline uint32_t rawval(const uint32_t *words, int raw_msb_bit, int size)
+{
+	const int msb_bit = raw_msb_bit + ((raw_msb_bit >= 120) ? 8 : 0);
+	const int lsb_bit = msb_bit + size - 1;
+	uint32_t val = words[msb_bit / 32];
+
+	if ((msb_bit / 32) != (lsb_bit / 32)) {
+		int hsize = 32 - (msb_bit % 32);
+		int lsize = size - hsize;
+
+		return (rawval(words, raw_msb_bit, hsize) << lsize) |
+			rawval(words, raw_msb_bit + hsize, lsize);
+	}
+
+	ASSERT3U(msb_bit / 32, ==, lsb_bit / 32);
+
+	val >>= 31 - (lsb_bit % 32);
+	val &= (1u << size) - 1;
+
+	return val;
+}
+
+static inline bool rawbit(const uint32_t *words, int bit)
+{
+	return rawval(words, bit, 1) != 0;
+}
+
+static inline uint32_t uval(const uint32_t *nom, int msb_bit, int size)
+{
+	const int lsb_bit = msb_bit + size - 1;
+	uint32_t val = nom[msb_bit / 32];
+
+	if ((msb_bit / 32) != (lsb_bit / 32)) {
+		int hsize = 32 - (msb_bit % 32);
+		int lsize = size - hsize;
+
+		return (uval(nom, msb_bit, hsize) << lsize) |
+			uval(nom, msb_bit + hsize, lsize);
+	}
+
+	ASSERT3U(msb_bit / 32, ==, lsb_bit / 32);
+
+	val >>= 31 - (lsb_bit % 32);
+	val &= (1u << size) - 1;
+
+	return val;
+}
+
+static inline int32_t ival(const uint32_t *nom, int msb_bit, int size)
+{
+	const uint32_t sign_mask = (1u << (size - 1));
+	uint32_t val;
+
+	ASSERT3S(size, >=, 2);
+	ASSERT3S(size, <=, 32);
+
+	val = uval(nom, msb_bit, size);
+
+	if (val & sign_mask) {
+		/* negative */
+
+		val |= ~0 ^ (sign_mask - 1);
+	}
+
+	return val;
+}
+
+static inline bool bit(const uint32_t *nom, int bit)
+{
+	return uval(nom, bit, 1) != 0;
+}
+
+/*
+ * Parse a raw I/NAV message.  Note, this only splits out the various
+ * fields, it does *not* do any scaling.
+ */
+bool galileo_parse_inav_page(struct galileo_inav_page *pg,
+			     const uint32_t *words, size_t nwords)
+{
+	ASSERT3U(nwords, ==, 9); /* ublox docs say 8 */
+
+	ASSERT(!rawbit(words, 0)); /* even */
+	ASSERT(rawbit(words, 120)); /* odd */
+
+	pg->page_nominal = !rawbit(words, 1);
+
+	if (pg->page_nominal) {
+		uint32_t nom[4];
+
+		pg->nominal.sar = rawval(words, 58, 22);
+
+		nom[0] = rawval(words, 2, 32);
+		nom[1] = rawval(words, 34, 32);
+		nom[2] = rawval(words, 66, 32);
+		nom[3] = (rawval(words, 98, 16) << 16) | rawval(words, 122, 16);
+
+		pg->nominal.type = uval(nom, 0, 6);
+
+		switch (pg->nominal.type) {
+			case 1:
+				pg->nominal.w1.iod = uval(nom, 6, 10);
+				pg->nominal.w1.t0e = uval(nom, 16, 14);
+				pg->nominal.w1.m0 = ival(nom, 30, 32);
+				pg->nominal.w1.e = uval(nom, 62, 32);
+				pg->nominal.w1.sqrt_a = uval(nom, 94, 32);
+				return true;
+			case 2:
+				pg->nominal.w2.iod = uval(nom, 6, 10);
+				pg->nominal.w2.omega0 = ival(nom, 16, 32);
+				pg->nominal.w2.i0 = ival(nom, 48, 32);
+				pg->nominal.w2.omega = ival(nom, 80, 32);
+				pg->nominal.w2.idot = ival(nom, 112, 14);
+				return true;
+			case 3:
+				pg->nominal.w3.iod = uval(nom, 6, 10);
+				pg->nominal.w3.omegadot = ival(nom, 16, 24);
+				pg->nominal.w3.delta_n = ival(nom, 40, 16);
+				pg->nominal.w3.cuc = ival(nom, 56, 16);
+				pg->nominal.w3.cus = ival(nom, 72, 16);
+				pg->nominal.w3.crc = ival(nom, 88, 16);
+				pg->nominal.w3.crs = ival(nom, 104, 16);
+				pg->nominal.w3.sisa = uval(nom, 120, 8);
+				return true;
+			case 4:
+				pg->nominal.w4.iod = uval(nom, 6, 10);
+				pg->nominal.w4.svid = uval(nom, 16, 6);
+				pg->nominal.w4.cic = ival(nom, 22, 16);
+				pg->nominal.w4.cis = ival(nom, 38, 16);
+				pg->nominal.w4.t0c = uval(nom, 54, 14);
+				pg->nominal.w4.af0 = uval(nom, 68, 31);
+				pg->nominal.w4.af1 = uval(nom, 99, 21);
+				pg->nominal.w4.af2 = uval(nom, 120, 6);
+				return true;
+			case 5:
+				pg->nominal.w5.ai0 = uval(nom, 6, 11);
+				pg->nominal.w5.ai1 = uval(nom, 17, 11);
+				pg->nominal.w5.ai2 = uval(nom, 28, 14);
+				pg->nominal.w5.reg1 = bit(nom, 42);
+				pg->nominal.w5.reg2 = bit(nom, 43);
+				pg->nominal.w5.reg3 = bit(nom, 44);
+				pg->nominal.w5.reg4 = bit(nom, 45);
+				pg->nominal.w5.reg5 = bit(nom, 46);
+				pg->nominal.w5.bgda = uval(nom, 47, 10);
+				pg->nominal.w5.bgdb = uval(nom, 57, 10);
+				pg->nominal.w5.e5bhs = uval(nom, 67, 2);
+				pg->nominal.w5.e1bhs = uval(nom, 69, 2);
+				pg->nominal.w5.e5bdvs = bit(nom, 71);
+				pg->nominal.w5.e1bdvs = bit(nom, 72);
+				pg->nominal.w5.wn = uval(nom, 73, 12);
+				pg->nominal.w5.tow = uval(nom, 85, 20);
+				return true;
+			case 6:
+				pg->nominal.w6.a0 = uval(nom, 6, 32);
+				pg->nominal.w6.a1 = uval(nom, 38, 24);
+				pg->nominal.w6.delta_tls = uval(nom, 62, 8);
+				pg->nominal.w6.tot = uval(nom, 70, 8);
+				pg->nominal.w6.wn0t = uval(nom, 78, 8);
+				pg->nominal.w6.wnlsf = uval(nom, 86, 8);
+				pg->nominal.w6.dn = uval(nom, 94, 3);
+				pg->nominal.w6.delta_tlsf = uval(nom, 97, 8);
+				pg->nominal.w6.tow = uval(nom, 105, 20);
+				return true;
+			case 7:
+				pg->nominal.w7.iod = uval(nom, 6, 4);
+				pg->nominal.w7.wn = uval(nom, 10, 2);
+				pg->nominal.w7.t0a = uval(nom, 12, 10);
+				pg->nominal.w7.svid1 = uval(nom, 22, 6);
+				pg->nominal.w7.sv1_delta_sqrt_a = ival(nom, 28, 13);
+				pg->nominal.w7.sv1_e = uval(nom, 41, 11);
+				pg->nominal.w7.sv1_omega = ival(nom, 52, 16);
+				pg->nominal.w7.sv1_delta = ival(nom, 68, 11);
+				pg->nominal.w7.sv1_omega0 = ival(nom, 79, 16);
+				pg->nominal.w7.sv1_omegadot = ival(nom, 95, 11);
+				pg->nominal.w7.sv1_m0 = ival(nom, 106, 16);
+				return true;
+			case 8:
+				pg->nominal.w8.iod = uval(nom, 6, 4);
+				pg->nominal.w8.sv1_af0 = ival(nom, 10, 16);
+				pg->nominal.w8.sv1_af1 = ival(nom, 26, 13);
+				pg->nominal.w8.sv1_e5bhs = uval(nom, 39, 2);
+				pg->nominal.w8.sv1_e1bhs = uval(nom, 41, 2);
+				pg->nominal.w8.svid2 = uval(nom, 43, 6);
+				pg->nominal.w8.sv2_delta_sqrt_a = ival(nom, 49, 13);
+				pg->nominal.w8.sv2_e = uval(nom, 62, 11);
+				pg->nominal.w8.sv2_omega = ival(nom, 73, 16);
+				pg->nominal.w8.sv2_delta = ival(nom, 89, 11);
+				pg->nominal.w8.sv2_omega0 = ival(nom, 100, 16);
+				pg->nominal.w8.sv2_omegadot = ival(nom, 116, 11);
+				return true;
+			case 9:
+				pg->nominal.w9.iod = uval(nom, 6, 4);
+				pg->nominal.w9.wn = uval(nom, 10, 2);
+				pg->nominal.w9.t0a = uval(nom, 12, 10);
+				pg->nominal.w9.sv2_m0 = ival(nom, 22, 16);
+				pg->nominal.w9.sv2_af0 = ival(nom, 38, 16);
+				pg->nominal.w9.sv2_af1 = ival(nom, 54, 13);
+				pg->nominal.w9.sv2_e5bhs = uval(nom, 67, 2);
+				pg->nominal.w9.sv2_e1bhs = uval(nom, 69, 2);
+				pg->nominal.w9.svid3 = uval(nom, 71, 6);
+				pg->nominal.w9.sv3_delta_sqrt_a = ival(nom, 77, 13);
+				pg->nominal.w9.sv3_e = uval(nom, 90, 11);
+				pg->nominal.w9.sv3_omega = ival(nom, 101, 16);
+				pg->nominal.w9.sv3_delta = ival(nom, 117, 11);
+				return true;
+			case 10:
+				pg->nominal.w10.iod = uval(nom, 6, 4);
+				pg->nominal.w10.sv3_omega0 = ival(nom, 10, 16);
+				pg->nominal.w10.sv3_omegadot = ival(nom, 26, 11);
+				pg->nominal.w10.sv3_m0 = ival(nom, 37, 16);
+				pg->nominal.w10.sv3_af0 = ival(nom, 53, 16);
+				pg->nominal.w10.sv3_af1 = ival(nom, 69, 13);
+				pg->nominal.w10.sv3_e5bhs = uval(nom, 82, 2);
+				pg->nominal.w10.sv3_e1bhs = uval(nom, 84, 2);
+				pg->nominal.w10.a0g = uval(nom, 86, 16);
+				pg->nominal.w10.a1g = uval(nom, 102, 12);
+				pg->nominal.w10.t0g = uval(nom, 114, 8);
+				pg->nominal.w10.wn = uval(nom, 122, 6);
+				return true;
+			case 0:
+				pg->nominal.w0.wn = uval(nom, 96, 12);
+				pg->nominal.w0.tow = uval(nom, 108, 20);
+				return true;
+			case 63:
+				/* dummy page */
+				return true;
+		}
+
+		fprintf(stderr, "Unknown Galileo word type %u\n",
+			pg->nominal.type);
+
+		return false;
+	} else {
+		/* nothing to do */
+		return true;
+	}
+}
--- a/gnss-galileo.c	Thu Jan 16 17:56:46 2020 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "gnss-galileo.h"
-
-#include <jeffpc/types.h>
-#include <jeffpc/error.h>
-
-static inline uint32_t rawval(const uint32_t *words, int raw_msb_bit, int size)
-{
-	const int msb_bit = raw_msb_bit + ((raw_msb_bit >= 120) ? 8 : 0);
-	const int lsb_bit = msb_bit + size - 1;
-	uint32_t val = words[msb_bit / 32];
-
-	if ((msb_bit / 32) != (lsb_bit / 32)) {
-		int hsize = 32 - (msb_bit % 32);
-		int lsize = size - hsize;
-
-		return (rawval(words, raw_msb_bit, hsize) << lsize) |
-			rawval(words, raw_msb_bit + hsize, lsize);
-	}
-
-	ASSERT3U(msb_bit / 32, ==, lsb_bit / 32);
-
-	val >>= 31 - (lsb_bit % 32);
-	val &= (1u << size) - 1;
-
-	return val;
-}
-
-static inline bool rawbit(const uint32_t *words, int bit)
-{
-	return rawval(words, bit, 1) != 0;
-}
-
-static inline uint32_t uval(const uint32_t *nom, int msb_bit, int size)
-{
-	const int lsb_bit = msb_bit + size - 1;
-	uint32_t val = nom[msb_bit / 32];
-
-	if ((msb_bit / 32) != (lsb_bit / 32)) {
-		int hsize = 32 - (msb_bit % 32);
-		int lsize = size - hsize;
-
-		return (uval(nom, msb_bit, hsize) << lsize) |
-			uval(nom, msb_bit + hsize, lsize);
-	}
-
-	ASSERT3U(msb_bit / 32, ==, lsb_bit / 32);
-
-	val >>= 31 - (lsb_bit % 32);
-	val &= (1u << size) - 1;
-
-	return val;
-}
-
-static inline int32_t ival(const uint32_t *nom, int msb_bit, int size)
-{
-	const uint32_t sign_mask = (1u << (size - 1));
-	uint32_t val;
-
-	ASSERT3S(size, >=, 2);
-	ASSERT3S(size, <=, 32);
-
-	val = uval(nom, msb_bit, size);
-
-	if (val & sign_mask) {
-		/* negative */
-
-		val |= ~0 ^ (sign_mask - 1);
-	}
-
-	return val;
-}
-
-static inline bool bit(const uint32_t *nom, int bit)
-{
-	return uval(nom, bit, 1) != 0;
-}
-
-/*
- * Parse a raw I/NAV message.  Note, this only splits out the various
- * fields, it does *not* do any scaling.
- */
-bool galileo_parse_inav_page(struct galileo_inav_page *pg,
-			     const uint32_t *words, size_t nwords)
-{
-	ASSERT3U(nwords, ==, 9); /* ublox docs say 8 */
-
-	ASSERT(!rawbit(words, 0)); /* even */
-	ASSERT(rawbit(words, 120)); /* odd */
-
-	pg->page_nominal = !rawbit(words, 1);
-
-	if (pg->page_nominal) {
-		uint32_t nom[4];
-
-		pg->nominal.sar = rawval(words, 58, 22);
-
-		nom[0] = rawval(words, 2, 32);
-		nom[1] = rawval(words, 34, 32);
-		nom[2] = rawval(words, 66, 32);
-		nom[3] = (rawval(words, 98, 16) << 16) | rawval(words, 122, 16);
-
-		pg->nominal.type = uval(nom, 0, 6);
-
-		switch (pg->nominal.type) {
-			case 1:
-				pg->nominal.w1.iod = uval(nom, 6, 10);
-				pg->nominal.w1.t0e = uval(nom, 16, 14);
-				pg->nominal.w1.m0 = ival(nom, 30, 32);
-				pg->nominal.w1.e = uval(nom, 62, 32);
-				pg->nominal.w1.sqrt_a = uval(nom, 94, 32);
-				return true;
-			case 2:
-				pg->nominal.w2.iod = uval(nom, 6, 10);
-				pg->nominal.w2.omega0 = ival(nom, 16, 32);
-				pg->nominal.w2.i0 = ival(nom, 48, 32);
-				pg->nominal.w2.omega = ival(nom, 80, 32);
-				pg->nominal.w2.idot = ival(nom, 112, 14);
-				return true;
-			case 3:
-				pg->nominal.w3.iod = uval(nom, 6, 10);
-				pg->nominal.w3.omegadot = ival(nom, 16, 24);
-				pg->nominal.w3.delta_n = ival(nom, 40, 16);
-				pg->nominal.w3.cuc = ival(nom, 56, 16);
-				pg->nominal.w3.cus = ival(nom, 72, 16);
-				pg->nominal.w3.crc = ival(nom, 88, 16);
-				pg->nominal.w3.crs = ival(nom, 104, 16);
-				pg->nominal.w3.sisa = uval(nom, 120, 8);
-				return true;
-			case 4:
-				pg->nominal.w4.iod = uval(nom, 6, 10);
-				pg->nominal.w4.svid = uval(nom, 16, 6);
-				pg->nominal.w4.cic = ival(nom, 22, 16);
-				pg->nominal.w4.cis = ival(nom, 38, 16);
-				pg->nominal.w4.t0c = uval(nom, 54, 14);
-				pg->nominal.w4.af0 = uval(nom, 68, 31);
-				pg->nominal.w4.af1 = uval(nom, 99, 21);
-				pg->nominal.w4.af2 = uval(nom, 120, 6);
-				return true;
-			case 5:
-				pg->nominal.w5.ai0 = uval(nom, 6, 11);
-				pg->nominal.w5.ai1 = uval(nom, 17, 11);
-				pg->nominal.w5.ai2 = uval(nom, 28, 14);
-				pg->nominal.w5.reg1 = bit(nom, 42);
-				pg->nominal.w5.reg2 = bit(nom, 43);
-				pg->nominal.w5.reg3 = bit(nom, 44);
-				pg->nominal.w5.reg4 = bit(nom, 45);
-				pg->nominal.w5.reg5 = bit(nom, 46);
-				pg->nominal.w5.bgda = uval(nom, 47, 10);
-				pg->nominal.w5.bgdb = uval(nom, 57, 10);
-				pg->nominal.w5.e5bhs = uval(nom, 67, 2);
-				pg->nominal.w5.e1bhs = uval(nom, 69, 2);
-				pg->nominal.w5.e5bdvs = bit(nom, 71);
-				pg->nominal.w5.e1bdvs = bit(nom, 72);
-				pg->nominal.w5.wn = uval(nom, 73, 12);
-				pg->nominal.w5.tow = uval(nom, 85, 20);
-				return true;
-			case 6:
-				pg->nominal.w6.a0 = uval(nom, 6, 32);
-				pg->nominal.w6.a1 = uval(nom, 38, 24);
-				pg->nominal.w6.delta_tls = uval(nom, 62, 8);
-				pg->nominal.w6.tot = uval(nom, 70, 8);
-				pg->nominal.w6.wn0t = uval(nom, 78, 8);
-				pg->nominal.w6.wnlsf = uval(nom, 86, 8);
-				pg->nominal.w6.dn = uval(nom, 94, 3);
-				pg->nominal.w6.delta_tlsf = uval(nom, 97, 8);
-				pg->nominal.w6.tow = uval(nom, 105, 20);
-				return true;
-			case 7:
-				pg->nominal.w7.iod = uval(nom, 6, 4);
-				pg->nominal.w7.wn = uval(nom, 10, 2);
-				pg->nominal.w7.t0a = uval(nom, 12, 10);
-				pg->nominal.w7.svid1 = uval(nom, 22, 6);
-				pg->nominal.w7.sv1_delta_sqrt_a = ival(nom, 28, 13);
-				pg->nominal.w7.sv1_e = uval(nom, 41, 11);
-				pg->nominal.w7.sv1_omega = ival(nom, 52, 16);
-				pg->nominal.w7.sv1_delta = ival(nom, 68, 11);
-				pg->nominal.w7.sv1_omega0 = ival(nom, 79, 16);
-				pg->nominal.w7.sv1_omegadot = ival(nom, 95, 11);
-				pg->nominal.w7.sv1_m0 = ival(nom, 106, 16);
-				return true;
-			case 8:
-				pg->nominal.w8.iod = uval(nom, 6, 4);
-				pg->nominal.w8.sv1_af0 = ival(nom, 10, 16);
-				pg->nominal.w8.sv1_af1 = ival(nom, 26, 13);
-				pg->nominal.w8.sv1_e5bhs = uval(nom, 39, 2);
-				pg->nominal.w8.sv1_e1bhs = uval(nom, 41, 2);
-				pg->nominal.w8.svid2 = uval(nom, 43, 6);
-				pg->nominal.w8.sv2_delta_sqrt_a = ival(nom, 49, 13);
-				pg->nominal.w8.sv2_e = uval(nom, 62, 11);
-				pg->nominal.w8.sv2_omega = ival(nom, 73, 16);
-				pg->nominal.w8.sv2_delta = ival(nom, 89, 11);
-				pg->nominal.w8.sv2_omega0 = ival(nom, 100, 16);
-				pg->nominal.w8.sv2_omegadot = ival(nom, 116, 11);
-				return true;
-			case 9:
-				pg->nominal.w9.iod = uval(nom, 6, 4);
-				pg->nominal.w9.wn = uval(nom, 10, 2);
-				pg->nominal.w9.t0a = uval(nom, 12, 10);
-				pg->nominal.w9.sv2_m0 = ival(nom, 22, 16);
-				pg->nominal.w9.sv2_af0 = ival(nom, 38, 16);
-				pg->nominal.w9.sv2_af1 = ival(nom, 54, 13);
-				pg->nominal.w9.sv2_e5bhs = uval(nom, 67, 2);
-				pg->nominal.w9.sv2_e1bhs = uval(nom, 69, 2);
-				pg->nominal.w9.svid3 = uval(nom, 71, 6);
-				pg->nominal.w9.sv3_delta_sqrt_a = ival(nom, 77, 13);
-				pg->nominal.w9.sv3_e = uval(nom, 90, 11);
-				pg->nominal.w9.sv3_omega = ival(nom, 101, 16);
-				pg->nominal.w9.sv3_delta = ival(nom, 117, 11);
-				return true;
-			case 10:
-				pg->nominal.w10.iod = uval(nom, 6, 4);
-				pg->nominal.w10.sv3_omega0 = ival(nom, 10, 16);
-				pg->nominal.w10.sv3_omegadot = ival(nom, 26, 11);
-				pg->nominal.w10.sv3_m0 = ival(nom, 37, 16);
-				pg->nominal.w10.sv3_af0 = ival(nom, 53, 16);
-				pg->nominal.w10.sv3_af1 = ival(nom, 69, 13);
-				pg->nominal.w10.sv3_e5bhs = uval(nom, 82, 2);
-				pg->nominal.w10.sv3_e1bhs = uval(nom, 84, 2);
-				pg->nominal.w10.a0g = uval(nom, 86, 16);
-				pg->nominal.w10.a1g = uval(nom, 102, 12);
-				pg->nominal.w10.t0g = uval(nom, 114, 8);
-				pg->nominal.w10.wn = uval(nom, 122, 6);
-				return true;
-			case 0:
-				pg->nominal.w0.wn = uval(nom, 96, 12);
-				pg->nominal.w0.tow = uval(nom, 108, 20);
-				return true;
-			case 63:
-				/* dummy page */
-				return true;
-		}
-
-		fprintf(stderr, "Unknown Galileo word type %u\n",
-			pg->nominal.type);
-
-		return false;
-	} else {
-		/* nothing to do */
-		return true;
-	}
-}