gnss-js 1.20.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sbf.d.cts CHANGED
@@ -209,6 +209,178 @@ interface SbfGloNavResult {
209
209
  */
210
210
  declare function parseSbfGloNav(data: Uint8Array): SbfGloNavResult;
211
211
 
212
+ /** Constellations HAS corrects: GPS (GNSS ID 0), Galileo (GNSS ID 2). */
213
+ type HasSystem = 'G' | 'E';
214
+ /** One system's satellite/signal mask (ICD §6.4.3). */
215
+ interface HasSystemMask {
216
+ /** GNSS ID as broadcast: 0 GPS, 2 Galileo. */
217
+ gnssId: number;
218
+ system: HasSystem;
219
+ /** Masked satellites in mask order, e.g. ["E03", "E05", ...]. */
220
+ prns: string[];
221
+ /** Set bits of the 16-bit signal mask, ascending. */
222
+ signalIndices: number[];
223
+ /** ICD names for `signalIndices`. */
224
+ signals: string[];
225
+ /**
226
+ * Cell mask, [satellite][signal] in mask order — true when the
227
+ * sat×signal combination carries biases. Null when the cell-mask
228
+ * availability flag is 0 (all combinations available).
229
+ */
230
+ cellMask: boolean[][] | null;
231
+ /** Nav-message index the corrections refer to (0 = LNAV / I/NAV). */
232
+ navMessage: number;
233
+ }
234
+ /** The satellite/signal mask block of one mask ID. */
235
+ interface HasMasks {
236
+ maskId: number;
237
+ systems: HasSystemMask[];
238
+ }
239
+ /** Orbit correction for one satellite (ICD §6.5). */
240
+ interface HasOrbitCorrection {
241
+ system: HasSystem;
242
+ prn: string;
243
+ /** Broadcast issue of data the deltas refer to (IODE / IODNav). */
244
+ gnssIod: number;
245
+ /** Delta radial in m (LSB 0.0025), null = data not available. */
246
+ deltaRadial: number | null;
247
+ /** Delta in-track in m (LSB 0.008), null = data not available. */
248
+ deltaInTrack: number | null;
249
+ /** Delta cross-track in m (LSB 0.008), null = data not available. */
250
+ deltaCrossTrack: number | null;
251
+ }
252
+ interface HasOrbitBlock {
253
+ validityIndex: number;
254
+ /** Validity interval in s (null = reserved index 15). */
255
+ validitySeconds: number | null;
256
+ corrections: HasOrbitCorrection[];
257
+ }
258
+ /** Clock correction for one satellite (ICD §6.6-6.7). */
259
+ interface HasClockCorrection {
260
+ system: HasSystem;
261
+ prn: string;
262
+ /**
263
+ * Delta clock C0 in m, multiplier folded in; positive means the
264
+ * satellite clock offset grows (add Δclock/c to the broadcast
265
+ * clock). Null when data not available or the satellite is flagged
266
+ * "shall not be used" (see `notUsable`).
267
+ */
268
+ deltaClock: number | null;
269
+ /** True for the reserved "insufficient accuracy, do not use" value. */
270
+ notUsable: boolean;
271
+ }
272
+ interface HasClockBlock {
273
+ validityIndex: number;
274
+ validitySeconds: number | null;
275
+ /** Delta-clock C0 multiplier per system (1-4), in mask order. */
276
+ multipliers: {
277
+ system: HasSystem;
278
+ multiplier: number;
279
+ }[];
280
+ corrections: HasClockCorrection[];
281
+ }
282
+ /** Code or phase bias of one satellite × signal cell (ICD §6.8-6.9). */
283
+ interface HasSignalBias {
284
+ system: HasSystem;
285
+ prn: string;
286
+ signalIndex: number;
287
+ signal: string;
288
+ /** Bias in m (code, LSB 0.02) or cycles (phase, LSB 0.01); null = N/A. */
289
+ bias: number | null;
290
+ /** Phase-discontinuity indicator (phase biases only). */
291
+ discontinuity?: number;
292
+ }
293
+ interface HasBiasBlock {
294
+ validityIndex: number;
295
+ validitySeconds: number | null;
296
+ biases: HasSignalBias[];
297
+ }
298
+ /** Which sub-blocks the MT1 header flags as present (ICD §6.2). */
299
+ interface HasContentFlags {
300
+ mask: boolean;
301
+ orbit: boolean;
302
+ clockFullSet: boolean;
303
+ clockSubset: boolean;
304
+ codeBias: boolean;
305
+ phaseBias: boolean;
306
+ }
307
+ /** One decoded HAS MT1 message. */
308
+ interface HasMessage {
309
+ /** Receiver time of week (s) of the page completing the message. */
310
+ tow?: number;
311
+ /** HAS status of the carrying pages (0 test, 1 operational). */
312
+ status: number;
313
+ messageId: number;
314
+ /** Message size in pages (= pages used for the RS decode). */
315
+ messageSize: number;
316
+ /** Time of hour of the corrections, s (0-3599, ICD §6.2). */
317
+ toh: number;
318
+ maskId: number;
319
+ iodSetId: number;
320
+ flags: HasContentFlags;
321
+ /** The mask block in force (own or cached, see `maskFromCache`). */
322
+ masks?: HasMasks;
323
+ /** True when `masks` came from an earlier message with this mask ID. */
324
+ maskFromCache: boolean;
325
+ orbit?: HasOrbitBlock;
326
+ clockFullSet?: HasClockBlock;
327
+ clockSubset?: HasClockBlock;
328
+ codeBias?: HasBiasBlock;
329
+ phaseBias?: HasBiasBlock;
330
+ /** Null when fully parsed, else why the sub-blocks are missing. */
331
+ parseError: string | null;
332
+ }
333
+
334
+ /**
335
+ * Septentrio SBF GALRawCNAV (4024) blocks: one 492-bit Galileo E6-B
336
+ * C/NAV page per block (after deinterleaving and Viterbi decoding),
337
+ * feeding the receiver-independent HAS decoder in ../navbits/has.
338
+ *
339
+ * Block layout (mosaic-X5 reference guide §4.2): after the 8-byte SBF
340
+ * header, TOW u4 (ms) + WNc u2, SVID u1, CRCPassed u1, ViterbiCnt u1,
341
+ * Source u1, FreqNr u1, RxChannel u1, then NAVBits as u4[16] — the
342
+ * first received bit is the MSB of NAVBits[0] (each u4 little-endian
343
+ * in the stream, page bits MSB-first within the word), the unused 20
344
+ * bits of NAVBits[15] to be ignored.
345
+ *
346
+ * RTKLIB demo5 (rtklibexplorer) has no C/NAV decoder — GALRawCNAV is
347
+ * not handled by src/rcv/septentrio.c at all — so the block layout
348
+ * comes from the reference guide directly, and the page handling was
349
+ * cross-checked against FGI's HASlib reference decoder
350
+ * (github.com/nlsfi/HASlib, EUPL-1.2, galileo_has_decoder/sbf_reading.py).
351
+ *
352
+ * The receiver's own CRCPassed flag is ignored in favor of re-running
353
+ * CRC-24Q on the transported page, so `pagesBadCrc` counts exactly the
354
+ * pages this library rejected.
355
+ */
356
+
357
+ /** A HAS message tagged with the SBF time stamp that completed it. */
358
+ interface SbfHasMessage extends HasMessage {
359
+ /** Receiver time of week (s) of the completing GALRawCNAV block. */
360
+ tow: number;
361
+ /** Receiver week number (GPS weeks, no rollover) of that block. */
362
+ wnc: number;
363
+ }
364
+ interface SbfHasResult {
365
+ /** Completed HAS messages in stream order. */
366
+ messages: SbfHasMessage[];
367
+ /** GALRawCNAV blocks seen (with valid SBF framing and length). */
368
+ pagesSeen: number;
369
+ /** Pages dropped for a failed CRC-24Q re-check. */
370
+ pagesBadCrc: number;
371
+ /** Dummy pages (idle filler, no HAS content). */
372
+ pagesDummy: number;
373
+ /** Non-dummy HAS pages fed to the assembler. */
374
+ pagesHas: number;
375
+ }
376
+ /**
377
+ * Decode every GALRawCNAV block in an SBF byte stream and assemble the
378
+ * carried HAS pages — network-wide, across all satellites — into HAS
379
+ * messages. Pages must be fed as captured (chronological order) for
380
+ * the message-generation bookkeeping to work.
381
+ */
382
+ declare function parseSbfHas(data: Uint8Array): SbfHasResult;
383
+
212
384
  /**
213
385
  * Septentrio SBF raw-measurement decoding (MeasEpoch + Meas3) — the
214
386
  * path from a receiver log to RINEX-grade observables.
@@ -272,4 +444,4 @@ interface SbfParseResult {
272
444
  */
273
445
  declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
274
446
 
275
- export { CnavEphemeris, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
447
+ export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
package/dist/sbf.d.ts CHANGED
@@ -209,6 +209,178 @@ interface SbfGloNavResult {
209
209
  */
210
210
  declare function parseSbfGloNav(data: Uint8Array): SbfGloNavResult;
211
211
 
212
+ /** Constellations HAS corrects: GPS (GNSS ID 0), Galileo (GNSS ID 2). */
213
+ type HasSystem = 'G' | 'E';
214
+ /** One system's satellite/signal mask (ICD §6.4.3). */
215
+ interface HasSystemMask {
216
+ /** GNSS ID as broadcast: 0 GPS, 2 Galileo. */
217
+ gnssId: number;
218
+ system: HasSystem;
219
+ /** Masked satellites in mask order, e.g. ["E03", "E05", ...]. */
220
+ prns: string[];
221
+ /** Set bits of the 16-bit signal mask, ascending. */
222
+ signalIndices: number[];
223
+ /** ICD names for `signalIndices`. */
224
+ signals: string[];
225
+ /**
226
+ * Cell mask, [satellite][signal] in mask order — true when the
227
+ * sat×signal combination carries biases. Null when the cell-mask
228
+ * availability flag is 0 (all combinations available).
229
+ */
230
+ cellMask: boolean[][] | null;
231
+ /** Nav-message index the corrections refer to (0 = LNAV / I/NAV). */
232
+ navMessage: number;
233
+ }
234
+ /** The satellite/signal mask block of one mask ID. */
235
+ interface HasMasks {
236
+ maskId: number;
237
+ systems: HasSystemMask[];
238
+ }
239
+ /** Orbit correction for one satellite (ICD §6.5). */
240
+ interface HasOrbitCorrection {
241
+ system: HasSystem;
242
+ prn: string;
243
+ /** Broadcast issue of data the deltas refer to (IODE / IODNav). */
244
+ gnssIod: number;
245
+ /** Delta radial in m (LSB 0.0025), null = data not available. */
246
+ deltaRadial: number | null;
247
+ /** Delta in-track in m (LSB 0.008), null = data not available. */
248
+ deltaInTrack: number | null;
249
+ /** Delta cross-track in m (LSB 0.008), null = data not available. */
250
+ deltaCrossTrack: number | null;
251
+ }
252
+ interface HasOrbitBlock {
253
+ validityIndex: number;
254
+ /** Validity interval in s (null = reserved index 15). */
255
+ validitySeconds: number | null;
256
+ corrections: HasOrbitCorrection[];
257
+ }
258
+ /** Clock correction for one satellite (ICD §6.6-6.7). */
259
+ interface HasClockCorrection {
260
+ system: HasSystem;
261
+ prn: string;
262
+ /**
263
+ * Delta clock C0 in m, multiplier folded in; positive means the
264
+ * satellite clock offset grows (add Δclock/c to the broadcast
265
+ * clock). Null when data not available or the satellite is flagged
266
+ * "shall not be used" (see `notUsable`).
267
+ */
268
+ deltaClock: number | null;
269
+ /** True for the reserved "insufficient accuracy, do not use" value. */
270
+ notUsable: boolean;
271
+ }
272
+ interface HasClockBlock {
273
+ validityIndex: number;
274
+ validitySeconds: number | null;
275
+ /** Delta-clock C0 multiplier per system (1-4), in mask order. */
276
+ multipliers: {
277
+ system: HasSystem;
278
+ multiplier: number;
279
+ }[];
280
+ corrections: HasClockCorrection[];
281
+ }
282
+ /** Code or phase bias of one satellite × signal cell (ICD §6.8-6.9). */
283
+ interface HasSignalBias {
284
+ system: HasSystem;
285
+ prn: string;
286
+ signalIndex: number;
287
+ signal: string;
288
+ /** Bias in m (code, LSB 0.02) or cycles (phase, LSB 0.01); null = N/A. */
289
+ bias: number | null;
290
+ /** Phase-discontinuity indicator (phase biases only). */
291
+ discontinuity?: number;
292
+ }
293
+ interface HasBiasBlock {
294
+ validityIndex: number;
295
+ validitySeconds: number | null;
296
+ biases: HasSignalBias[];
297
+ }
298
+ /** Which sub-blocks the MT1 header flags as present (ICD §6.2). */
299
+ interface HasContentFlags {
300
+ mask: boolean;
301
+ orbit: boolean;
302
+ clockFullSet: boolean;
303
+ clockSubset: boolean;
304
+ codeBias: boolean;
305
+ phaseBias: boolean;
306
+ }
307
+ /** One decoded HAS MT1 message. */
308
+ interface HasMessage {
309
+ /** Receiver time of week (s) of the page completing the message. */
310
+ tow?: number;
311
+ /** HAS status of the carrying pages (0 test, 1 operational). */
312
+ status: number;
313
+ messageId: number;
314
+ /** Message size in pages (= pages used for the RS decode). */
315
+ messageSize: number;
316
+ /** Time of hour of the corrections, s (0-3599, ICD §6.2). */
317
+ toh: number;
318
+ maskId: number;
319
+ iodSetId: number;
320
+ flags: HasContentFlags;
321
+ /** The mask block in force (own or cached, see `maskFromCache`). */
322
+ masks?: HasMasks;
323
+ /** True when `masks` came from an earlier message with this mask ID. */
324
+ maskFromCache: boolean;
325
+ orbit?: HasOrbitBlock;
326
+ clockFullSet?: HasClockBlock;
327
+ clockSubset?: HasClockBlock;
328
+ codeBias?: HasBiasBlock;
329
+ phaseBias?: HasBiasBlock;
330
+ /** Null when fully parsed, else why the sub-blocks are missing. */
331
+ parseError: string | null;
332
+ }
333
+
334
+ /**
335
+ * Septentrio SBF GALRawCNAV (4024) blocks: one 492-bit Galileo E6-B
336
+ * C/NAV page per block (after deinterleaving and Viterbi decoding),
337
+ * feeding the receiver-independent HAS decoder in ../navbits/has.
338
+ *
339
+ * Block layout (mosaic-X5 reference guide §4.2): after the 8-byte SBF
340
+ * header, TOW u4 (ms) + WNc u2, SVID u1, CRCPassed u1, ViterbiCnt u1,
341
+ * Source u1, FreqNr u1, RxChannel u1, then NAVBits as u4[16] — the
342
+ * first received bit is the MSB of NAVBits[0] (each u4 little-endian
343
+ * in the stream, page bits MSB-first within the word), the unused 20
344
+ * bits of NAVBits[15] to be ignored.
345
+ *
346
+ * RTKLIB demo5 (rtklibexplorer) has no C/NAV decoder — GALRawCNAV is
347
+ * not handled by src/rcv/septentrio.c at all — so the block layout
348
+ * comes from the reference guide directly, and the page handling was
349
+ * cross-checked against FGI's HASlib reference decoder
350
+ * (github.com/nlsfi/HASlib, EUPL-1.2, galileo_has_decoder/sbf_reading.py).
351
+ *
352
+ * The receiver's own CRCPassed flag is ignored in favor of re-running
353
+ * CRC-24Q on the transported page, so `pagesBadCrc` counts exactly the
354
+ * pages this library rejected.
355
+ */
356
+
357
+ /** A HAS message tagged with the SBF time stamp that completed it. */
358
+ interface SbfHasMessage extends HasMessage {
359
+ /** Receiver time of week (s) of the completing GALRawCNAV block. */
360
+ tow: number;
361
+ /** Receiver week number (GPS weeks, no rollover) of that block. */
362
+ wnc: number;
363
+ }
364
+ interface SbfHasResult {
365
+ /** Completed HAS messages in stream order. */
366
+ messages: SbfHasMessage[];
367
+ /** GALRawCNAV blocks seen (with valid SBF framing and length). */
368
+ pagesSeen: number;
369
+ /** Pages dropped for a failed CRC-24Q re-check. */
370
+ pagesBadCrc: number;
371
+ /** Dummy pages (idle filler, no HAS content). */
372
+ pagesDummy: number;
373
+ /** Non-dummy HAS pages fed to the assembler. */
374
+ pagesHas: number;
375
+ }
376
+ /**
377
+ * Decode every GALRawCNAV block in an SBF byte stream and assemble the
378
+ * carried HAS pages — network-wide, across all satellites — into HAS
379
+ * messages. Pages must be fed as captured (chronological order) for
380
+ * the message-generation bookkeeping to work.
381
+ */
382
+ declare function parseSbfHas(data: Uint8Array): SbfHasResult;
383
+
212
384
  /**
213
385
  * Septentrio SBF raw-measurement decoding (MeasEpoch + Meas3) — the
214
386
  * path from a receiver log to RINEX-grade observables.
@@ -272,4 +444,4 @@ interface SbfParseResult {
272
444
  */
273
445
  declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
274
446
 
275
- export { CnavEphemeris, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
447
+ export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
package/dist/sbf.js CHANGED
@@ -5,11 +5,12 @@ import {
5
5
  parseSbfCnav,
6
6
  parseSbfGalNav,
7
7
  parseSbfGloNav,
8
+ parseSbfHas,
8
9
  parseSbfIonoUtc,
9
10
  parseSbfMeas,
10
11
  parseSbfNav,
11
12
  scanSbfFrames
12
- } from "./chunk-VJEPOC76.js";
13
+ } from "./chunk-K3V3NHWL.js";
13
14
  import "./chunk-WZDFZ76K.js";
14
15
  import "./chunk-HVXYFUCB.js";
15
16
  import "./chunk-LEEU5OIO.js";
@@ -19,6 +20,7 @@ export {
19
20
  parseSbfCnav,
20
21
  parseSbfGalNav,
21
22
  parseSbfGloNav,
23
+ parseSbfHas,
22
24
  parseSbfIonoUtc,
23
25
  parseSbfMeas,
24
26
  parseSbfNav,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gnss-js",
3
- "version": "1.20.0",
3
+ "version": "1.21.0",
4
4
  "description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
5
5
  "type": "module",
6
6
  "sideEffects": false,