gnss-js 1.56.0 → 1.57.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/{chunk-ZPNMIUNZ.js → chunk-UHLUAU6H.js} +131 -9
- package/dist/index.cjs +139 -9
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -1
- package/dist/sbf.cjs +139 -9
- package/dist/sbf.d.cts +112 -28
- package/dist/sbf.d.ts +112 -28
- package/dist/sbf.js +17 -1
- package/package.json +1 -1
|
@@ -756,13 +756,42 @@ function parseSbfGloNav(data) {
|
|
|
756
756
|
return { ephemerides, badCrc, messages };
|
|
757
757
|
}
|
|
758
758
|
|
|
759
|
+
// src/navbits/sbas-l5.ts
|
|
760
|
+
var SBAS_L5_PREAMBLE_UW = 6056250;
|
|
761
|
+
function isSbasL1Preamble(msg) {
|
|
762
|
+
return msg[0] === 83 || msg[0] === 154 || msg[0] === 198;
|
|
763
|
+
}
|
|
764
|
+
function sbasL5MessageType(msg) {
|
|
765
|
+
return getBitU(msg, 4, 6);
|
|
766
|
+
}
|
|
767
|
+
var SBAS_L5_MT_NAMES = {
|
|
768
|
+
0: "Do Not Use (test)",
|
|
769
|
+
31: "SBAS satellite mask",
|
|
770
|
+
32: "Satellite clock-ephemeris corrections + covariance",
|
|
771
|
+
34: "Integrity (DFREI/DFRECI)",
|
|
772
|
+
35: "Integrity (DFREI/DFRECI)",
|
|
773
|
+
36: "Integrity (DFREI/DFRECI)",
|
|
774
|
+
37: "Degradation parameters + DFREI scale table",
|
|
775
|
+
39: "SBAS satellite clock/ephemeris/covariance-1",
|
|
776
|
+
40: "SBAS satellite clock/ephemeris/covariance-2",
|
|
777
|
+
42: "SNT-to-UTC offset",
|
|
778
|
+
47: "SBAS satellite almanacs",
|
|
779
|
+
62: "Reserved",
|
|
780
|
+
63: "Null message"
|
|
781
|
+
};
|
|
782
|
+
function sbasL5MessageName(type) {
|
|
783
|
+
return SBAS_L5_MT_NAMES[type] ?? (type >= 1 && type <= 61 ? "Spare" : `Type ${type}`);
|
|
784
|
+
}
|
|
785
|
+
function isSbasL5Correction(type) {
|
|
786
|
+
return type === 31 || type === 32 || type >= 34 && type <= 37 || type === 39 || type === 40 || type === 42 || type === 47;
|
|
787
|
+
}
|
|
788
|
+
|
|
759
789
|
// src/sbf/rawnav-sbas.ts
|
|
760
|
-
function
|
|
790
|
+
function readGeoMessage(view, b) {
|
|
761
791
|
const tow = view.getUint32(b + 8, true);
|
|
762
792
|
const wnc = view.getUint16(b + 12, true);
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
-
if (!prnStr || prnStr[0] !== "S") return {};
|
|
793
|
+
const prnStr = svidToPrn(view.getUint8(b + 14));
|
|
794
|
+
if (!prnStr || prnStr[0] !== "S") return null;
|
|
766
795
|
const msg = new Uint8Array(32);
|
|
767
796
|
for (let k = 0; k < 8; k++) {
|
|
768
797
|
const w = view.getUint32(b + 20 + 4 * k, true);
|
|
@@ -771,12 +800,29 @@ function feedGeoBlock(view, b, onSbasMessage) {
|
|
|
771
800
|
msg[4 * k + 2] = w >>> 8 & 255;
|
|
772
801
|
msg[4 * k + 3] = w & 255;
|
|
773
802
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
const
|
|
803
|
+
return { msg, prn: Number(prnStr.slice(1)) + 100, wnc, towSec: tow / 1e3 };
|
|
804
|
+
}
|
|
805
|
+
function feedGeoBlock(view, b, onSbasMessage) {
|
|
806
|
+
const g = readGeoMessage(view, b);
|
|
807
|
+
if (!g) return {};
|
|
808
|
+
if (!sbasCrcOk(g.msg)) return { badCrc: true };
|
|
809
|
+
onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
|
|
810
|
+
const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
|
|
778
811
|
return eph ? { eph } : {};
|
|
779
812
|
}
|
|
813
|
+
function feedGeoL5Block(view, b, onSbasMessage, onDfmcMessage) {
|
|
814
|
+
const g = readGeoMessage(view, b);
|
|
815
|
+
if (!g) return {};
|
|
816
|
+
if (!sbasCrcOk(g.msg)) return { badCrc: true };
|
|
817
|
+
if (isSbasL1Preamble(g.msg)) {
|
|
818
|
+
onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
|
|
819
|
+
const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
|
|
820
|
+
return eph ? { kind: "l1", eph } : { kind: "l1" };
|
|
821
|
+
}
|
|
822
|
+
const dfmcType = sbasL5MessageType(g.msg);
|
|
823
|
+
onDfmcMessage?.(g.msg, g.prn, g.wnc, g.towSec, dfmcType);
|
|
824
|
+
return { kind: "l5", dfmcType };
|
|
825
|
+
}
|
|
780
826
|
function parseSbfGeoNav(data, opts = {}) {
|
|
781
827
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
782
828
|
const ephemerides = [];
|
|
@@ -799,6 +845,47 @@ function parseSbfGeoNav(data, opts = {}) {
|
|
|
799
845
|
});
|
|
800
846
|
return { ephemerides, badCrc, messages };
|
|
801
847
|
}
|
|
848
|
+
function parseSbfGeoL5(data, opts = {}) {
|
|
849
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
850
|
+
const ephemerides = [];
|
|
851
|
+
const seen = /* @__PURE__ */ new Set();
|
|
852
|
+
const byType = {};
|
|
853
|
+
const dfmcPrns = /* @__PURE__ */ new Set();
|
|
854
|
+
let legacyMessages = 0;
|
|
855
|
+
let dfmcMessages = 0;
|
|
856
|
+
let badCrc = 0;
|
|
857
|
+
let messages = 0;
|
|
858
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
859
|
+
if (id !== 4021 || len < 52) return;
|
|
860
|
+
messages++;
|
|
861
|
+
const r = feedGeoL5Block(view, b, opts.onSbasMessage, opts.onDfmcMessage);
|
|
862
|
+
if (r.badCrc) {
|
|
863
|
+
badCrc++;
|
|
864
|
+
} else if (r.kind === "l1") {
|
|
865
|
+
legacyMessages++;
|
|
866
|
+
if (r.eph) {
|
|
867
|
+
const key = `${r.eph.prn}|${r.eph.tocDate.getTime()}`;
|
|
868
|
+
if (!seen.has(key)) {
|
|
869
|
+
seen.add(key);
|
|
870
|
+
ephemerides.push(r.eph);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
} else if (r.kind === "l5" && r.dfmcType !== void 0) {
|
|
874
|
+
dfmcMessages++;
|
|
875
|
+
byType[r.dfmcType] = (byType[r.dfmcType] ?? 0) + 1;
|
|
876
|
+
const prn = view.getUint8(b + 14);
|
|
877
|
+
const s = svidToPrn(prn);
|
|
878
|
+
if (s) dfmcPrns.add(s);
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
return {
|
|
882
|
+
ephemerides,
|
|
883
|
+
legacyMessages,
|
|
884
|
+
dfmc: { byType, prns: [...dfmcPrns].sort(), messages: dfmcMessages },
|
|
885
|
+
badCrc,
|
|
886
|
+
messages
|
|
887
|
+
};
|
|
888
|
+
}
|
|
802
889
|
|
|
803
890
|
// src/sbf/navigation.ts
|
|
804
891
|
var F4_DNU4 = -2e10;
|
|
@@ -821,8 +908,11 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
821
908
|
gloRaw: 0,
|
|
822
909
|
bdsRaw: 0,
|
|
823
910
|
sbasRaw: 0,
|
|
911
|
+
sbasL5Raw: 0,
|
|
824
912
|
badFrames: 0
|
|
825
913
|
};
|
|
914
|
+
const dfmcByType = {};
|
|
915
|
+
const dfmcPrns = /* @__PURE__ */ new Set();
|
|
826
916
|
const cnavAsm = newCnavAssemblers();
|
|
827
917
|
const galAsm = newGalAssemblers();
|
|
828
918
|
const gloAsm = new GloStringAssembler();
|
|
@@ -932,6 +1022,25 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
932
1022
|
else if (r.badCrc) counts.badFrames++;
|
|
933
1023
|
return;
|
|
934
1024
|
}
|
|
1025
|
+
case 4021: {
|
|
1026
|
+
if (len < 52) return;
|
|
1027
|
+
counts.sbasL5Raw++;
|
|
1028
|
+
const r = feedGeoL5Block(
|
|
1029
|
+
view,
|
|
1030
|
+
b,
|
|
1031
|
+
opts.onSbasMessage,
|
|
1032
|
+
opts.onDfmcMessage
|
|
1033
|
+
);
|
|
1034
|
+
if (r.badCrc) counts.badFrames++;
|
|
1035
|
+
else if (r.kind === "l1") {
|
|
1036
|
+
if (r.eph) addEph(r.eph);
|
|
1037
|
+
} else if (r.kind === "l5" && r.dfmcType !== void 0) {
|
|
1038
|
+
dfmcByType[r.dfmcType] = (dfmcByType[r.dfmcType] ?? 0) + 1;
|
|
1039
|
+
const s = svidToPrn(view.getUint8(b + 14));
|
|
1040
|
+
if (s) dfmcPrns.add(s);
|
|
1041
|
+
}
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
935
1044
|
/* ---- iono / UTC ---- */
|
|
936
1045
|
case 5893:
|
|
937
1046
|
// GPSIon
|
|
@@ -956,7 +1065,12 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
956
1065
|
return;
|
|
957
1066
|
}
|
|
958
1067
|
});
|
|
959
|
-
|
|
1068
|
+
const dfmc = {
|
|
1069
|
+
byType: dfmcByType,
|
|
1070
|
+
prns: [...dfmcPrns].sort(),
|
|
1071
|
+
messages: Object.values(dfmcByType).reduce((a, v) => a + v, 0)
|
|
1072
|
+
};
|
|
1073
|
+
return { ephemerides, cnav, ionoCorrections, leapSeconds, dfmc, counts };
|
|
960
1074
|
}
|
|
961
1075
|
|
|
962
1076
|
// src/navbits/rs255.ts
|
|
@@ -2163,8 +2277,16 @@ export {
|
|
|
2163
2277
|
parseSbfGalNav,
|
|
2164
2278
|
parseSbfBdsNav,
|
|
2165
2279
|
parseSbfGloNav,
|
|
2280
|
+
SBAS_L5_PREAMBLE_UW,
|
|
2281
|
+
isSbasL1Preamble,
|
|
2282
|
+
sbasL5MessageType,
|
|
2283
|
+
SBAS_L5_MT_NAMES,
|
|
2284
|
+
sbasL5MessageName,
|
|
2285
|
+
isSbasL5Correction,
|
|
2166
2286
|
feedGeoBlock,
|
|
2287
|
+
feedGeoL5Block,
|
|
2167
2288
|
parseSbfGeoNav,
|
|
2289
|
+
parseSbfGeoL5,
|
|
2168
2290
|
decodeSbfNavigation,
|
|
2169
2291
|
parseSbfHas,
|
|
2170
2292
|
parseSbfMeas
|
package/dist/index.cjs
CHANGED
|
@@ -84,6 +84,8 @@ __export(src_exports, {
|
|
|
84
84
|
RTCM3_MESSAGE_NAMES: () => RTCM3_MESSAGE_NAMES,
|
|
85
85
|
Rtcm3Decoder: () => Rtcm3Decoder,
|
|
86
86
|
RtkFloatEngine: () => RtkFloatEngine,
|
|
87
|
+
SBAS_L5_MT_NAMES: () => SBAS_L5_MT_NAMES,
|
|
88
|
+
SBAS_L5_PREAMBLE_UW: () => SBAS_L5_PREAMBLE_UW,
|
|
87
89
|
SECONDS_IN_DAY: () => SECONDS_IN_DAY,
|
|
88
90
|
SECONDS_IN_HOUR: () => SECONDS_IN_HOUR,
|
|
89
91
|
SECONDS_IN_MINUTE: () => SECONDS_IN_MINUTE,
|
|
@@ -157,6 +159,7 @@ __export(src_exports, {
|
|
|
157
159
|
euclidean3D: () => euclidean3D,
|
|
158
160
|
extractWidelaneArcs: () => extractWidelaneArcs,
|
|
159
161
|
feedGeoBlock: () => feedGeoBlock,
|
|
162
|
+
feedGeoL5Block: () => feedGeoL5Block,
|
|
160
163
|
fetchSourcetable: () => fetchSourcetable,
|
|
161
164
|
findSatBias: () => findSatBias,
|
|
162
165
|
fixPppPosition: () => fixPppPosition,
|
|
@@ -233,6 +236,8 @@ __export(src_exports, {
|
|
|
233
236
|
hdrLine: () => hdrLine,
|
|
234
237
|
horizonDistance: () => horizonDistance,
|
|
235
238
|
ionoFree: () => ionoFree,
|
|
239
|
+
isSbasL1Preamble: () => isSbasL1Preamble,
|
|
240
|
+
isSbasL5Correction: () => isSbasL5Correction,
|
|
236
241
|
keplerPosition: () => keplerPosition,
|
|
237
242
|
klobucharDelay: () => klobucharDelay,
|
|
238
243
|
lambdaReduction: () => lambdaReduction,
|
|
@@ -263,6 +268,7 @@ __export(src_exports, {
|
|
|
263
268
|
parseSbfBdsNav: () => parseSbfBdsNav,
|
|
264
269
|
parseSbfCnav: () => parseSbfCnav,
|
|
265
270
|
parseSbfGalNav: () => parseSbfGalNav,
|
|
271
|
+
parseSbfGeoL5: () => parseSbfGeoL5,
|
|
266
272
|
parseSbfGeoNav: () => parseSbfGeoNav,
|
|
267
273
|
parseSbfGloNav: () => parseSbfGloNav,
|
|
268
274
|
parseSbfGpsNav: () => parseSbfGpsNav,
|
|
@@ -297,6 +303,8 @@ __export(src_exports, {
|
|
|
297
303
|
rhumbLine: () => rhumbLine,
|
|
298
304
|
rtcm3Constellation: () => rtcm3Constellation,
|
|
299
305
|
satClockCorrection: () => satClockCorrection,
|
|
306
|
+
sbasL5MessageName: () => sbasL5MessageName,
|
|
307
|
+
sbasL5MessageType: () => sbasL5MessageType,
|
|
300
308
|
sbasProtectionLevels: () => sbasProtectionLevels,
|
|
301
309
|
sbfCrc16: () => crc16,
|
|
302
310
|
scanSbfFrames: () => scanSbfFrames,
|
|
@@ -7833,13 +7841,42 @@ function parseSbfGloNav(data) {
|
|
|
7833
7841
|
return { ephemerides, badCrc, messages };
|
|
7834
7842
|
}
|
|
7835
7843
|
|
|
7844
|
+
// src/navbits/sbas-l5.ts
|
|
7845
|
+
var SBAS_L5_PREAMBLE_UW = 6056250;
|
|
7846
|
+
function isSbasL1Preamble(msg) {
|
|
7847
|
+
return msg[0] === 83 || msg[0] === 154 || msg[0] === 198;
|
|
7848
|
+
}
|
|
7849
|
+
function sbasL5MessageType(msg) {
|
|
7850
|
+
return getBitU(msg, 4, 6);
|
|
7851
|
+
}
|
|
7852
|
+
var SBAS_L5_MT_NAMES = {
|
|
7853
|
+
0: "Do Not Use (test)",
|
|
7854
|
+
31: "SBAS satellite mask",
|
|
7855
|
+
32: "Satellite clock-ephemeris corrections + covariance",
|
|
7856
|
+
34: "Integrity (DFREI/DFRECI)",
|
|
7857
|
+
35: "Integrity (DFREI/DFRECI)",
|
|
7858
|
+
36: "Integrity (DFREI/DFRECI)",
|
|
7859
|
+
37: "Degradation parameters + DFREI scale table",
|
|
7860
|
+
39: "SBAS satellite clock/ephemeris/covariance-1",
|
|
7861
|
+
40: "SBAS satellite clock/ephemeris/covariance-2",
|
|
7862
|
+
42: "SNT-to-UTC offset",
|
|
7863
|
+
47: "SBAS satellite almanacs",
|
|
7864
|
+
62: "Reserved",
|
|
7865
|
+
63: "Null message"
|
|
7866
|
+
};
|
|
7867
|
+
function sbasL5MessageName(type) {
|
|
7868
|
+
return SBAS_L5_MT_NAMES[type] ?? (type >= 1 && type <= 61 ? "Spare" : `Type ${type}`);
|
|
7869
|
+
}
|
|
7870
|
+
function isSbasL5Correction(type) {
|
|
7871
|
+
return type === 31 || type === 32 || type >= 34 && type <= 37 || type === 39 || type === 40 || type === 42 || type === 47;
|
|
7872
|
+
}
|
|
7873
|
+
|
|
7836
7874
|
// src/sbf/rawnav-sbas.ts
|
|
7837
|
-
function
|
|
7875
|
+
function readGeoMessage(view, b) {
|
|
7838
7876
|
const tow = view.getUint32(b + 8, true);
|
|
7839
7877
|
const wnc = view.getUint16(b + 12, true);
|
|
7840
|
-
const
|
|
7841
|
-
|
|
7842
|
-
if (!prnStr || prnStr[0] !== "S") return {};
|
|
7878
|
+
const prnStr = svidToPrn(view.getUint8(b + 14));
|
|
7879
|
+
if (!prnStr || prnStr[0] !== "S") return null;
|
|
7843
7880
|
const msg = new Uint8Array(32);
|
|
7844
7881
|
for (let k = 0; k < 8; k++) {
|
|
7845
7882
|
const w = view.getUint32(b + 20 + 4 * k, true);
|
|
@@ -7848,12 +7885,29 @@ function feedGeoBlock(view, b, onSbasMessage) {
|
|
|
7848
7885
|
msg[4 * k + 2] = w >>> 8 & 255;
|
|
7849
7886
|
msg[4 * k + 3] = w & 255;
|
|
7850
7887
|
}
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
const
|
|
7888
|
+
return { msg, prn: Number(prnStr.slice(1)) + 100, wnc, towSec: tow / 1e3 };
|
|
7889
|
+
}
|
|
7890
|
+
function feedGeoBlock(view, b, onSbasMessage) {
|
|
7891
|
+
const g = readGeoMessage(view, b);
|
|
7892
|
+
if (!g) return {};
|
|
7893
|
+
if (!sbasCrcOk(g.msg)) return { badCrc: true };
|
|
7894
|
+
onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
|
|
7895
|
+
const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
|
|
7855
7896
|
return eph ? { eph } : {};
|
|
7856
7897
|
}
|
|
7898
|
+
function feedGeoL5Block(view, b, onSbasMessage, onDfmcMessage) {
|
|
7899
|
+
const g = readGeoMessage(view, b);
|
|
7900
|
+
if (!g) return {};
|
|
7901
|
+
if (!sbasCrcOk(g.msg)) return { badCrc: true };
|
|
7902
|
+
if (isSbasL1Preamble(g.msg)) {
|
|
7903
|
+
onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
|
|
7904
|
+
const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
|
|
7905
|
+
return eph ? { kind: "l1", eph } : { kind: "l1" };
|
|
7906
|
+
}
|
|
7907
|
+
const dfmcType = sbasL5MessageType(g.msg);
|
|
7908
|
+
onDfmcMessage?.(g.msg, g.prn, g.wnc, g.towSec, dfmcType);
|
|
7909
|
+
return { kind: "l5", dfmcType };
|
|
7910
|
+
}
|
|
7857
7911
|
function parseSbfGeoNav(data, opts = {}) {
|
|
7858
7912
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
7859
7913
|
const ephemerides = [];
|
|
@@ -7876,6 +7930,47 @@ function parseSbfGeoNav(data, opts = {}) {
|
|
|
7876
7930
|
});
|
|
7877
7931
|
return { ephemerides, badCrc, messages };
|
|
7878
7932
|
}
|
|
7933
|
+
function parseSbfGeoL5(data, opts = {}) {
|
|
7934
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
7935
|
+
const ephemerides = [];
|
|
7936
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7937
|
+
const byType = {};
|
|
7938
|
+
const dfmcPrns = /* @__PURE__ */ new Set();
|
|
7939
|
+
let legacyMessages = 0;
|
|
7940
|
+
let dfmcMessages = 0;
|
|
7941
|
+
let badCrc = 0;
|
|
7942
|
+
let messages = 0;
|
|
7943
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
7944
|
+
if (id !== 4021 || len < 52) return;
|
|
7945
|
+
messages++;
|
|
7946
|
+
const r = feedGeoL5Block(view, b, opts.onSbasMessage, opts.onDfmcMessage);
|
|
7947
|
+
if (r.badCrc) {
|
|
7948
|
+
badCrc++;
|
|
7949
|
+
} else if (r.kind === "l1") {
|
|
7950
|
+
legacyMessages++;
|
|
7951
|
+
if (r.eph) {
|
|
7952
|
+
const key = `${r.eph.prn}|${r.eph.tocDate.getTime()}`;
|
|
7953
|
+
if (!seen.has(key)) {
|
|
7954
|
+
seen.add(key);
|
|
7955
|
+
ephemerides.push(r.eph);
|
|
7956
|
+
}
|
|
7957
|
+
}
|
|
7958
|
+
} else if (r.kind === "l5" && r.dfmcType !== void 0) {
|
|
7959
|
+
dfmcMessages++;
|
|
7960
|
+
byType[r.dfmcType] = (byType[r.dfmcType] ?? 0) + 1;
|
|
7961
|
+
const prn = view.getUint8(b + 14);
|
|
7962
|
+
const s = svidToPrn(prn);
|
|
7963
|
+
if (s) dfmcPrns.add(s);
|
|
7964
|
+
}
|
|
7965
|
+
});
|
|
7966
|
+
return {
|
|
7967
|
+
ephemerides,
|
|
7968
|
+
legacyMessages,
|
|
7969
|
+
dfmc: { byType, prns: [...dfmcPrns].sort(), messages: dfmcMessages },
|
|
7970
|
+
badCrc,
|
|
7971
|
+
messages
|
|
7972
|
+
};
|
|
7973
|
+
}
|
|
7879
7974
|
|
|
7880
7975
|
// src/sbf/navigation.ts
|
|
7881
7976
|
var F4_DNU4 = -2e10;
|
|
@@ -7898,8 +7993,11 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
7898
7993
|
gloRaw: 0,
|
|
7899
7994
|
bdsRaw: 0,
|
|
7900
7995
|
sbasRaw: 0,
|
|
7996
|
+
sbasL5Raw: 0,
|
|
7901
7997
|
badFrames: 0
|
|
7902
7998
|
};
|
|
7999
|
+
const dfmcByType = {};
|
|
8000
|
+
const dfmcPrns = /* @__PURE__ */ new Set();
|
|
7903
8001
|
const cnavAsm = newCnavAssemblers();
|
|
7904
8002
|
const galAsm = newGalAssemblers();
|
|
7905
8003
|
const gloAsm = new GloStringAssembler();
|
|
@@ -8009,6 +8107,25 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
8009
8107
|
else if (r.badCrc) counts.badFrames++;
|
|
8010
8108
|
return;
|
|
8011
8109
|
}
|
|
8110
|
+
case 4021: {
|
|
8111
|
+
if (len < 52) return;
|
|
8112
|
+
counts.sbasL5Raw++;
|
|
8113
|
+
const r = feedGeoL5Block(
|
|
8114
|
+
view,
|
|
8115
|
+
b,
|
|
8116
|
+
opts.onSbasMessage,
|
|
8117
|
+
opts.onDfmcMessage
|
|
8118
|
+
);
|
|
8119
|
+
if (r.badCrc) counts.badFrames++;
|
|
8120
|
+
else if (r.kind === "l1") {
|
|
8121
|
+
if (r.eph) addEph(r.eph);
|
|
8122
|
+
} else if (r.kind === "l5" && r.dfmcType !== void 0) {
|
|
8123
|
+
dfmcByType[r.dfmcType] = (dfmcByType[r.dfmcType] ?? 0) + 1;
|
|
8124
|
+
const s = svidToPrn(view.getUint8(b + 14));
|
|
8125
|
+
if (s) dfmcPrns.add(s);
|
|
8126
|
+
}
|
|
8127
|
+
return;
|
|
8128
|
+
}
|
|
8012
8129
|
/* ---- iono / UTC ---- */
|
|
8013
8130
|
case 5893:
|
|
8014
8131
|
// GPSIon
|
|
@@ -8033,7 +8150,12 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
8033
8150
|
return;
|
|
8034
8151
|
}
|
|
8035
8152
|
});
|
|
8036
|
-
|
|
8153
|
+
const dfmc = {
|
|
8154
|
+
byType: dfmcByType,
|
|
8155
|
+
prns: [...dfmcPrns].sort(),
|
|
8156
|
+
messages: Object.values(dfmcByType).reduce((a, v) => a + v, 0)
|
|
8157
|
+
};
|
|
8158
|
+
return { ephemerides, cnav, ionoCorrections, leapSeconds, dfmc, counts };
|
|
8037
8159
|
}
|
|
8038
8160
|
|
|
8039
8161
|
// src/navbits/rs255.ts
|
|
@@ -17781,6 +17903,8 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
17781
17903
|
RTCM3_MESSAGE_NAMES,
|
|
17782
17904
|
Rtcm3Decoder,
|
|
17783
17905
|
RtkFloatEngine,
|
|
17906
|
+
SBAS_L5_MT_NAMES,
|
|
17907
|
+
SBAS_L5_PREAMBLE_UW,
|
|
17784
17908
|
SECONDS_IN_DAY,
|
|
17785
17909
|
SECONDS_IN_HOUR,
|
|
17786
17910
|
SECONDS_IN_MINUTE,
|
|
@@ -17854,6 +17978,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
17854
17978
|
euclidean3D,
|
|
17855
17979
|
extractWidelaneArcs,
|
|
17856
17980
|
feedGeoBlock,
|
|
17981
|
+
feedGeoL5Block,
|
|
17857
17982
|
fetchSourcetable,
|
|
17858
17983
|
findSatBias,
|
|
17859
17984
|
fixPppPosition,
|
|
@@ -17930,6 +18055,8 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
17930
18055
|
hdrLine,
|
|
17931
18056
|
horizonDistance,
|
|
17932
18057
|
ionoFree,
|
|
18058
|
+
isSbasL1Preamble,
|
|
18059
|
+
isSbasL5Correction,
|
|
17933
18060
|
keplerPosition,
|
|
17934
18061
|
klobucharDelay,
|
|
17935
18062
|
lambdaReduction,
|
|
@@ -17960,6 +18087,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
17960
18087
|
parseSbfBdsNav,
|
|
17961
18088
|
parseSbfCnav,
|
|
17962
18089
|
parseSbfGalNav,
|
|
18090
|
+
parseSbfGeoL5,
|
|
17963
18091
|
parseSbfGeoNav,
|
|
17964
18092
|
parseSbfGloNav,
|
|
17965
18093
|
parseSbfGpsNav,
|
|
@@ -17994,6 +18122,8 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
17994
18122
|
rhumbLine,
|
|
17995
18123
|
rtcm3Constellation,
|
|
17996
18124
|
satClockCorrection,
|
|
18125
|
+
sbasL5MessageName,
|
|
18126
|
+
sbasL5MessageType,
|
|
17997
18127
|
sbasProtectionLevels,
|
|
17998
18128
|
sbfCrc16,
|
|
17999
18129
|
scanSbfFrames,
|
package/dist/index.d.cts
CHANGED
|
@@ -12,7 +12,7 @@ export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBia
|
|
|
12
12
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
|
|
13
13
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
|
|
14
14
|
export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxPvtResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxPvt, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.cjs';
|
|
15
|
-
export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfPvt, SbfPvtResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.cjs';
|
|
15
|
+
export { DfmcCensus, DfmcMessageCb, GeoL5Result, HasMessage, SBAS_L5_MT_NAMES, SBAS_L5_PREAMBLE_UW, SbasMessageCb, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoL5Result, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfPvt, SbfPvtResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, feedGeoL5Block, isSbasL1Preamble, isSbasL5Correction, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoL5, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbasL5MessageName, sbasL5MessageType, sbfCrc16, scanSbfFrames } from './sbf.cjs';
|
|
16
16
|
export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, NovatelPvtResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelPvt, parseNovatelRange } from './novatel.cjs';
|
|
17
17
|
export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.cjs';
|
|
18
18
|
export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBia
|
|
|
12
12
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
|
|
13
13
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.js';
|
|
14
14
|
export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxPvtResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxPvt, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.js';
|
|
15
|
-
export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfPvt, SbfPvtResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.js';
|
|
15
|
+
export { DfmcCensus, DfmcMessageCb, GeoL5Result, HasMessage, SBAS_L5_MT_NAMES, SBAS_L5_PREAMBLE_UW, SbasMessageCb, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoL5Result, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfPvt, SbfPvtResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, feedGeoL5Block, isSbasL1Preamble, isSbasL5Correction, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoL5, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbasL5MessageName, sbasL5MessageType, sbfCrc16, scanSbfFrames } from './sbf.js';
|
|
16
16
|
export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, NovatelPvtResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelPvt, parseNovatelRange } from './novatel.js';
|
|
17
17
|
export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.js';
|
|
18
18
|
export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.js';
|
package/dist/index.js
CHANGED
|
@@ -53,13 +53,19 @@ import {
|
|
|
53
53
|
ubxFrames
|
|
54
54
|
} from "./chunk-MRC6LIPM.js";
|
|
55
55
|
import {
|
|
56
|
+
SBAS_L5_MT_NAMES,
|
|
57
|
+
SBAS_L5_PREAMBLE_UW,
|
|
56
58
|
crc16,
|
|
57
59
|
decodeSbfNavigation,
|
|
58
60
|
feedGeoBlock,
|
|
61
|
+
feedGeoL5Block,
|
|
62
|
+
isSbasL1Preamble,
|
|
63
|
+
isSbasL5Correction,
|
|
59
64
|
parseSbfAlmanac,
|
|
60
65
|
parseSbfBdsNav,
|
|
61
66
|
parseSbfCnav,
|
|
62
67
|
parseSbfGalNav,
|
|
68
|
+
parseSbfGeoL5,
|
|
63
69
|
parseSbfGeoNav,
|
|
64
70
|
parseSbfGloNav,
|
|
65
71
|
parseSbfGpsNav,
|
|
@@ -69,8 +75,10 @@ import {
|
|
|
69
75
|
parseSbfNav,
|
|
70
76
|
parseSbfPvt,
|
|
71
77
|
parseSbfReceiverSetup,
|
|
78
|
+
sbasL5MessageName,
|
|
79
|
+
sbasL5MessageType,
|
|
72
80
|
scanSbfFrames
|
|
73
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-UHLUAU6H.js";
|
|
74
82
|
import "./chunk-FA2UTLEQ.js";
|
|
75
83
|
import {
|
|
76
84
|
OEM4_HLEN,
|
|
@@ -424,6 +432,8 @@ export {
|
|
|
424
432
|
RTCM3_MESSAGE_NAMES,
|
|
425
433
|
Rtcm3Decoder,
|
|
426
434
|
RtkFloatEngine,
|
|
435
|
+
SBAS_L5_MT_NAMES,
|
|
436
|
+
SBAS_L5_PREAMBLE_UW,
|
|
427
437
|
SECONDS_IN_DAY,
|
|
428
438
|
SECONDS_IN_HOUR,
|
|
429
439
|
SECONDS_IN_MINUTE,
|
|
@@ -497,6 +507,7 @@ export {
|
|
|
497
507
|
euclidean3D,
|
|
498
508
|
extractWidelaneArcs,
|
|
499
509
|
feedGeoBlock,
|
|
510
|
+
feedGeoL5Block,
|
|
500
511
|
fetchSourcetable,
|
|
501
512
|
findSatBias,
|
|
502
513
|
fixPppPosition,
|
|
@@ -573,6 +584,8 @@ export {
|
|
|
573
584
|
hdrLine,
|
|
574
585
|
horizonDistance,
|
|
575
586
|
ionoFree,
|
|
587
|
+
isSbasL1Preamble,
|
|
588
|
+
isSbasL5Correction,
|
|
576
589
|
keplerPosition,
|
|
577
590
|
klobucharDelay,
|
|
578
591
|
lambdaReduction,
|
|
@@ -603,6 +616,7 @@ export {
|
|
|
603
616
|
parseSbfBdsNav,
|
|
604
617
|
parseSbfCnav,
|
|
605
618
|
parseSbfGalNav,
|
|
619
|
+
parseSbfGeoL5,
|
|
606
620
|
parseSbfGeoNav,
|
|
607
621
|
parseSbfGloNav,
|
|
608
622
|
parseSbfGpsNav,
|
|
@@ -637,6 +651,8 @@ export {
|
|
|
637
651
|
rhumbLine,
|
|
638
652
|
rtcm3Constellation,
|
|
639
653
|
satClockCorrection,
|
|
654
|
+
sbasL5MessageName,
|
|
655
|
+
sbasL5MessageType,
|
|
640
656
|
sbasProtectionLevels,
|
|
641
657
|
crc16 as sbfCrc16,
|
|
642
658
|
scanSbfFrames,
|
package/dist/sbf.cjs
CHANGED
|
@@ -20,12 +20,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/sbf/index.ts
|
|
21
21
|
var sbf_exports = {};
|
|
22
22
|
__export(sbf_exports, {
|
|
23
|
+
SBAS_L5_MT_NAMES: () => SBAS_L5_MT_NAMES,
|
|
24
|
+
SBAS_L5_PREAMBLE_UW: () => SBAS_L5_PREAMBLE_UW,
|
|
23
25
|
decodeSbfNavigation: () => decodeSbfNavigation,
|
|
24
26
|
feedGeoBlock: () => feedGeoBlock,
|
|
27
|
+
feedGeoL5Block: () => feedGeoL5Block,
|
|
28
|
+
isSbasL1Preamble: () => isSbasL1Preamble,
|
|
29
|
+
isSbasL5Correction: () => isSbasL5Correction,
|
|
25
30
|
parseSbfAlmanac: () => parseSbfAlmanac,
|
|
26
31
|
parseSbfBdsNav: () => parseSbfBdsNav,
|
|
27
32
|
parseSbfCnav: () => parseSbfCnav,
|
|
28
33
|
parseSbfGalNav: () => parseSbfGalNav,
|
|
34
|
+
parseSbfGeoL5: () => parseSbfGeoL5,
|
|
29
35
|
parseSbfGeoNav: () => parseSbfGeoNav,
|
|
30
36
|
parseSbfGloNav: () => parseSbfGloNav,
|
|
31
37
|
parseSbfGpsNav: () => parseSbfGpsNav,
|
|
@@ -35,6 +41,8 @@ __export(sbf_exports, {
|
|
|
35
41
|
parseSbfNav: () => parseSbfNav,
|
|
36
42
|
parseSbfPvt: () => parseSbfPvt,
|
|
37
43
|
parseSbfReceiverSetup: () => parseSbfReceiverSetup,
|
|
44
|
+
sbasL5MessageName: () => sbasL5MessageName,
|
|
45
|
+
sbasL5MessageType: () => sbasL5MessageType,
|
|
38
46
|
sbfCrc16: () => crc16,
|
|
39
47
|
scanSbfFrames: () => scanSbfFrames
|
|
40
48
|
});
|
|
@@ -2033,13 +2041,42 @@ function decodeSbasGeoNav(msg, prn, week, tow) {
|
|
|
2033
2041
|
};
|
|
2034
2042
|
}
|
|
2035
2043
|
|
|
2044
|
+
// src/navbits/sbas-l5.ts
|
|
2045
|
+
var SBAS_L5_PREAMBLE_UW = 6056250;
|
|
2046
|
+
function isSbasL1Preamble(msg) {
|
|
2047
|
+
return msg[0] === 83 || msg[0] === 154 || msg[0] === 198;
|
|
2048
|
+
}
|
|
2049
|
+
function sbasL5MessageType(msg) {
|
|
2050
|
+
return getBitU(msg, 4, 6);
|
|
2051
|
+
}
|
|
2052
|
+
var SBAS_L5_MT_NAMES = {
|
|
2053
|
+
0: "Do Not Use (test)",
|
|
2054
|
+
31: "SBAS satellite mask",
|
|
2055
|
+
32: "Satellite clock-ephemeris corrections + covariance",
|
|
2056
|
+
34: "Integrity (DFREI/DFRECI)",
|
|
2057
|
+
35: "Integrity (DFREI/DFRECI)",
|
|
2058
|
+
36: "Integrity (DFREI/DFRECI)",
|
|
2059
|
+
37: "Degradation parameters + DFREI scale table",
|
|
2060
|
+
39: "SBAS satellite clock/ephemeris/covariance-1",
|
|
2061
|
+
40: "SBAS satellite clock/ephemeris/covariance-2",
|
|
2062
|
+
42: "SNT-to-UTC offset",
|
|
2063
|
+
47: "SBAS satellite almanacs",
|
|
2064
|
+
62: "Reserved",
|
|
2065
|
+
63: "Null message"
|
|
2066
|
+
};
|
|
2067
|
+
function sbasL5MessageName(type) {
|
|
2068
|
+
return SBAS_L5_MT_NAMES[type] ?? (type >= 1 && type <= 61 ? "Spare" : `Type ${type}`);
|
|
2069
|
+
}
|
|
2070
|
+
function isSbasL5Correction(type) {
|
|
2071
|
+
return type === 31 || type === 32 || type >= 34 && type <= 37 || type === 39 || type === 40 || type === 42 || type === 47;
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2036
2074
|
// src/sbf/rawnav-sbas.ts
|
|
2037
|
-
function
|
|
2075
|
+
function readGeoMessage(view, b) {
|
|
2038
2076
|
const tow = view.getUint32(b + 8, true);
|
|
2039
2077
|
const wnc = view.getUint16(b + 12, true);
|
|
2040
|
-
const
|
|
2041
|
-
|
|
2042
|
-
if (!prnStr || prnStr[0] !== "S") return {};
|
|
2078
|
+
const prnStr = svidToPrn(view.getUint8(b + 14));
|
|
2079
|
+
if (!prnStr || prnStr[0] !== "S") return null;
|
|
2043
2080
|
const msg = new Uint8Array(32);
|
|
2044
2081
|
for (let k = 0; k < 8; k++) {
|
|
2045
2082
|
const w = view.getUint32(b + 20 + 4 * k, true);
|
|
@@ -2048,12 +2085,29 @@ function feedGeoBlock(view, b, onSbasMessage) {
|
|
|
2048
2085
|
msg[4 * k + 2] = w >>> 8 & 255;
|
|
2049
2086
|
msg[4 * k + 3] = w & 255;
|
|
2050
2087
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
const
|
|
2088
|
+
return { msg, prn: Number(prnStr.slice(1)) + 100, wnc, towSec: tow / 1e3 };
|
|
2089
|
+
}
|
|
2090
|
+
function feedGeoBlock(view, b, onSbasMessage) {
|
|
2091
|
+
const g = readGeoMessage(view, b);
|
|
2092
|
+
if (!g) return {};
|
|
2093
|
+
if (!sbasCrcOk(g.msg)) return { badCrc: true };
|
|
2094
|
+
onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
|
|
2095
|
+
const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
|
|
2055
2096
|
return eph ? { eph } : {};
|
|
2056
2097
|
}
|
|
2098
|
+
function feedGeoL5Block(view, b, onSbasMessage, onDfmcMessage) {
|
|
2099
|
+
const g = readGeoMessage(view, b);
|
|
2100
|
+
if (!g) return {};
|
|
2101
|
+
if (!sbasCrcOk(g.msg)) return { badCrc: true };
|
|
2102
|
+
if (isSbasL1Preamble(g.msg)) {
|
|
2103
|
+
onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
|
|
2104
|
+
const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
|
|
2105
|
+
return eph ? { kind: "l1", eph } : { kind: "l1" };
|
|
2106
|
+
}
|
|
2107
|
+
const dfmcType = sbasL5MessageType(g.msg);
|
|
2108
|
+
onDfmcMessage?.(g.msg, g.prn, g.wnc, g.towSec, dfmcType);
|
|
2109
|
+
return { kind: "l5", dfmcType };
|
|
2110
|
+
}
|
|
2057
2111
|
function parseSbfGeoNav(data, opts = {}) {
|
|
2058
2112
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
2059
2113
|
const ephemerides = [];
|
|
@@ -2076,6 +2130,47 @@ function parseSbfGeoNav(data, opts = {}) {
|
|
|
2076
2130
|
});
|
|
2077
2131
|
return { ephemerides, badCrc, messages };
|
|
2078
2132
|
}
|
|
2133
|
+
function parseSbfGeoL5(data, opts = {}) {
|
|
2134
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
2135
|
+
const ephemerides = [];
|
|
2136
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2137
|
+
const byType = {};
|
|
2138
|
+
const dfmcPrns = /* @__PURE__ */ new Set();
|
|
2139
|
+
let legacyMessages = 0;
|
|
2140
|
+
let dfmcMessages = 0;
|
|
2141
|
+
let badCrc = 0;
|
|
2142
|
+
let messages = 0;
|
|
2143
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
2144
|
+
if (id !== 4021 || len < 52) return;
|
|
2145
|
+
messages++;
|
|
2146
|
+
const r = feedGeoL5Block(view, b, opts.onSbasMessage, opts.onDfmcMessage);
|
|
2147
|
+
if (r.badCrc) {
|
|
2148
|
+
badCrc++;
|
|
2149
|
+
} else if (r.kind === "l1") {
|
|
2150
|
+
legacyMessages++;
|
|
2151
|
+
if (r.eph) {
|
|
2152
|
+
const key = `${r.eph.prn}|${r.eph.tocDate.getTime()}`;
|
|
2153
|
+
if (!seen.has(key)) {
|
|
2154
|
+
seen.add(key);
|
|
2155
|
+
ephemerides.push(r.eph);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
} else if (r.kind === "l5" && r.dfmcType !== void 0) {
|
|
2159
|
+
dfmcMessages++;
|
|
2160
|
+
byType[r.dfmcType] = (byType[r.dfmcType] ?? 0) + 1;
|
|
2161
|
+
const prn = view.getUint8(b + 14);
|
|
2162
|
+
const s = svidToPrn(prn);
|
|
2163
|
+
if (s) dfmcPrns.add(s);
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
return {
|
|
2167
|
+
ephemerides,
|
|
2168
|
+
legacyMessages,
|
|
2169
|
+
dfmc: { byType, prns: [...dfmcPrns].sort(), messages: dfmcMessages },
|
|
2170
|
+
badCrc,
|
|
2171
|
+
messages
|
|
2172
|
+
};
|
|
2173
|
+
}
|
|
2079
2174
|
|
|
2080
2175
|
// src/sbf/navigation.ts
|
|
2081
2176
|
var F4_DNU4 = -2e10;
|
|
@@ -2098,8 +2193,11 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2098
2193
|
gloRaw: 0,
|
|
2099
2194
|
bdsRaw: 0,
|
|
2100
2195
|
sbasRaw: 0,
|
|
2196
|
+
sbasL5Raw: 0,
|
|
2101
2197
|
badFrames: 0
|
|
2102
2198
|
};
|
|
2199
|
+
const dfmcByType = {};
|
|
2200
|
+
const dfmcPrns = /* @__PURE__ */ new Set();
|
|
2103
2201
|
const cnavAsm = newCnavAssemblers();
|
|
2104
2202
|
const galAsm = newGalAssemblers();
|
|
2105
2203
|
const gloAsm = new GloStringAssembler();
|
|
@@ -2209,6 +2307,25 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2209
2307
|
else if (r.badCrc) counts.badFrames++;
|
|
2210
2308
|
return;
|
|
2211
2309
|
}
|
|
2310
|
+
case 4021: {
|
|
2311
|
+
if (len < 52) return;
|
|
2312
|
+
counts.sbasL5Raw++;
|
|
2313
|
+
const r = feedGeoL5Block(
|
|
2314
|
+
view,
|
|
2315
|
+
b,
|
|
2316
|
+
opts.onSbasMessage,
|
|
2317
|
+
opts.onDfmcMessage
|
|
2318
|
+
);
|
|
2319
|
+
if (r.badCrc) counts.badFrames++;
|
|
2320
|
+
else if (r.kind === "l1") {
|
|
2321
|
+
if (r.eph) addEph(r.eph);
|
|
2322
|
+
} else if (r.kind === "l5" && r.dfmcType !== void 0) {
|
|
2323
|
+
dfmcByType[r.dfmcType] = (dfmcByType[r.dfmcType] ?? 0) + 1;
|
|
2324
|
+
const s = svidToPrn(view.getUint8(b + 14));
|
|
2325
|
+
if (s) dfmcPrns.add(s);
|
|
2326
|
+
}
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2212
2329
|
/* ---- iono / UTC ---- */
|
|
2213
2330
|
case 5893:
|
|
2214
2331
|
// GPSIon
|
|
@@ -2233,7 +2350,12 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2233
2350
|
return;
|
|
2234
2351
|
}
|
|
2235
2352
|
});
|
|
2236
|
-
|
|
2353
|
+
const dfmc = {
|
|
2354
|
+
byType: dfmcByType,
|
|
2355
|
+
prns: [...dfmcPrns].sort(),
|
|
2356
|
+
messages: Object.values(dfmcByType).reduce((a, v) => a + v, 0)
|
|
2357
|
+
};
|
|
2358
|
+
return { ephemerides, cnav, ionoCorrections, leapSeconds, dfmc, counts };
|
|
2237
2359
|
}
|
|
2238
2360
|
|
|
2239
2361
|
// src/navbits/rs255.ts
|
|
@@ -3428,12 +3550,18 @@ function parseSbfMeas(data) {
|
|
|
3428
3550
|
}
|
|
3429
3551
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3430
3552
|
0 && (module.exports = {
|
|
3553
|
+
SBAS_L5_MT_NAMES,
|
|
3554
|
+
SBAS_L5_PREAMBLE_UW,
|
|
3431
3555
|
decodeSbfNavigation,
|
|
3432
3556
|
feedGeoBlock,
|
|
3557
|
+
feedGeoL5Block,
|
|
3558
|
+
isSbasL1Preamble,
|
|
3559
|
+
isSbasL5Correction,
|
|
3433
3560
|
parseSbfAlmanac,
|
|
3434
3561
|
parseSbfBdsNav,
|
|
3435
3562
|
parseSbfCnav,
|
|
3436
3563
|
parseSbfGalNav,
|
|
3564
|
+
parseSbfGeoL5,
|
|
3437
3565
|
parseSbfGeoNav,
|
|
3438
3566
|
parseSbfGloNav,
|
|
3439
3567
|
parseSbfGpsNav,
|
|
@@ -3443,6 +3571,8 @@ function parseSbfMeas(data) {
|
|
|
3443
3571
|
parseSbfNav,
|
|
3444
3572
|
parseSbfPvt,
|
|
3445
3573
|
parseSbfReceiverSetup,
|
|
3574
|
+
sbasL5MessageName,
|
|
3575
|
+
sbasL5MessageType,
|
|
3446
3576
|
sbfCrc16,
|
|
3447
3577
|
scanSbfFrames
|
|
3448
3578
|
});
|
package/dist/sbf.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { S as SbfAlmanac, a as SbfAlmanacResult, b as SbfGlonassAlmanac, c as SbfKeplerAlmanac, d as SbfNavResult, p as parseSbfAlmanac, e as parseSbfNav } from './nav-BYmYoh9A.cjs';
|
|
2
2
|
import { R as ReceiverPvt } from './receiver-pvt-CVFvi4kT.cjs';
|
|
3
|
-
import { K as KeplerEphemeris, C as CnavEphemeris,
|
|
3
|
+
import { K as KeplerEphemeris, C as CnavEphemeris, G as GlonassEphemeris, E as Ephemeris } from './nav-DImXUdbp.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Septentrio SBF framing shared by the measurement and navigation
|
|
@@ -213,6 +213,91 @@ interface SbfCnavResult {
|
|
|
213
213
|
*/
|
|
214
214
|
declare function parseSbfCnav(data: Uint8Array): SbfCnavResult;
|
|
215
215
|
|
|
216
|
+
/** Callback fed every CRC-valid SBAS message (any type), as MSB-first bits. */
|
|
217
|
+
type SbasMessageCb = (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
218
|
+
/** Callback fed every CRC-valid native-DFMC (L5) message, with its type. */
|
|
219
|
+
type DfmcMessageCb = (msg: Uint8Array, prn: number, week: number, tow: number, type: number) => void;
|
|
220
|
+
/**
|
|
221
|
+
* Process one GEORawL1 block at frame offset `b`: extract the 250-bit
|
|
222
|
+
* SBAS L1 message, CRC-24Q gate it, and decode a GEO ephemeris if it is
|
|
223
|
+
* message type 9. Returns the ephemeris, `{ badCrc: true }` on a failed
|
|
224
|
+
* CRC, or `{}` for any other (non–type-9) message.
|
|
225
|
+
*/
|
|
226
|
+
declare function feedGeoBlock(view: DataView, b: number, onSbasMessage?: SbasMessageCb): {
|
|
227
|
+
eph?: GlonassEphemeris;
|
|
228
|
+
badCrc?: boolean;
|
|
229
|
+
};
|
|
230
|
+
/** Result of routing one GEORawL5 (4021) block. */
|
|
231
|
+
interface GeoL5Result {
|
|
232
|
+
eph?: GlonassEphemeris;
|
|
233
|
+
badCrc?: boolean;
|
|
234
|
+
/** 'l1' = DO-229 content relayed on L5 (fed to `onSbasMessage`, decodable by
|
|
235
|
+
* the L1 SbasProcessor); 'l5' = a native DFMC message (header only). */
|
|
236
|
+
kind?: 'l1' | 'l5';
|
|
237
|
+
/** Native-DFMC message type (Table B-98), when `kind === 'l5'`. */
|
|
238
|
+
dfmcType?: number;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Process one GEORawL5 block at frame offset `b`. The L5 signal carries a mix:
|
|
242
|
+
* GEOs relaying DO-229 (L1-format) content — routed to `onSbasMessage` and
|
|
243
|
+
* decoded for a GEO ephemeris exactly like {@link feedGeoBlock} — and GEOs
|
|
244
|
+
* broadcasting native DFMC frames, which are CRC-gated and surfaced via
|
|
245
|
+
* `onDfmcMessage` with their Table B-98 type but not field-decoded (see
|
|
246
|
+
* {@link ../navbits/sbas-l5}). Classification is by preamble.
|
|
247
|
+
*/
|
|
248
|
+
declare function feedGeoL5Block(view: DataView, b: number, onSbasMessage?: SbasMessageCb, onDfmcMessage?: DfmcMessageCb): GeoL5Result;
|
|
249
|
+
interface SbfGeoNavResult {
|
|
250
|
+
/** SBAS GEO ephemerides in stream order, unchanged repeats suppressed. */
|
|
251
|
+
ephemerides: GlonassEphemeris[];
|
|
252
|
+
/** GEORawL1 messages whose CRC-24Q check failed (dropped). */
|
|
253
|
+
badCrc: number;
|
|
254
|
+
/** Total GEORawL1 blocks seen (with valid SBF framing). */
|
|
255
|
+
messages: number;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Decode every GEORawL1 block in an SBF byte stream into SBAS GEO
|
|
259
|
+
* ephemerides (message type 9), de-duping unchanged rebroadcasts by
|
|
260
|
+
* (PRN, time-of-clock). The one-pass {@link decodeSbfNavigation} routes
|
|
261
|
+
* the same blocks through {@link feedGeoBlock}; this standalone parser
|
|
262
|
+
* mirrors the per-constellation `parseSbf*` helpers.
|
|
263
|
+
*/
|
|
264
|
+
declare function parseSbfGeoNav(data: Uint8Array, opts?: {
|
|
265
|
+
onSbasMessage?: (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
266
|
+
}): SbfGeoNavResult;
|
|
267
|
+
/** Census of the SBAS L5 (DFMC) frames in a stream. Correction content is not
|
|
268
|
+
* field-decoded (see {@link ../navbits/sbas-l5}). */
|
|
269
|
+
interface DfmcCensus {
|
|
270
|
+
/** Native-DFMC frame count by Table B-98 message type. */
|
|
271
|
+
byType: Record<number, number>;
|
|
272
|
+
/** GEO PRNs (e.g. 'S21') broadcasting native DFMC. */
|
|
273
|
+
prns: string[];
|
|
274
|
+
/** Total CRC-valid native-DFMC frames. */
|
|
275
|
+
messages: number;
|
|
276
|
+
}
|
|
277
|
+
interface SbfGeoL5Result {
|
|
278
|
+
/** GEO ephemerides from DO-229 (L1-format) content relayed on L5 (MT9). */
|
|
279
|
+
ephemerides: GlonassEphemeris[];
|
|
280
|
+
/** CRC-valid L5-signal frames carrying DO-229 (L1-format) content. */
|
|
281
|
+
legacyMessages: number;
|
|
282
|
+
/** Native-DFMC frame census. */
|
|
283
|
+
dfmc: DfmcCensus;
|
|
284
|
+
/** GEORawL5 frames whose CRC-24Q check failed (dropped). */
|
|
285
|
+
badCrc: number;
|
|
286
|
+
/** Total GEORawL5 blocks seen (with valid SBF framing). */
|
|
287
|
+
messages: number;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Decode every GEORawL5 (4021) block in an SBF byte stream. DO-229 (L1-format)
|
|
291
|
+
* content relayed on L5 is fed to `onSbasMessage` (usable by the L1
|
|
292
|
+
* SbasProcessor) and decoded for GEO ephemerides; native DFMC frames are
|
|
293
|
+
* CRC-gated and counted by message type. The one-pass
|
|
294
|
+
* {@link ../sbf/navigation.decodeSbfNavigation} performs the same routing.
|
|
295
|
+
*/
|
|
296
|
+
declare function parseSbfGeoL5(data: Uint8Array, opts?: {
|
|
297
|
+
onSbasMessage?: SbasMessageCb;
|
|
298
|
+
onDfmcMessage?: DfmcMessageCb;
|
|
299
|
+
}): SbfGeoL5Result;
|
|
300
|
+
|
|
216
301
|
/**
|
|
217
302
|
* One-pass SBF navigation decoder.
|
|
218
303
|
*
|
|
@@ -251,6 +336,8 @@ interface SbfNavCounts {
|
|
|
251
336
|
bdsRaw: number;
|
|
252
337
|
/** Raw SBAS L1 GEO message blocks (GEORawL1). */
|
|
253
338
|
sbasRaw: number;
|
|
339
|
+
/** Raw SBAS L5 GEO message blocks (GEORawL5) — DO-229-on-L5 + native DFMC. */
|
|
340
|
+
sbasL5Raw: number;
|
|
254
341
|
/** Frames dropped by a CRC/parity check across all raw decoders. */
|
|
255
342
|
badFrames: number;
|
|
256
343
|
}
|
|
@@ -270,6 +357,9 @@ interface SbfNavigation {
|
|
|
270
357
|
ionoCorrections: Record<string, number[]>;
|
|
271
358
|
/** GPS-UTC ΔtLS from the last GPSUtc block, if any. */
|
|
272
359
|
leapSeconds: number | null;
|
|
360
|
+
/** SBAS L5 (DFMC) native-frame census — message-type counts + GEO PRNs. The
|
|
361
|
+
* correction content is not field-decoded (see navbits/sbas-l5). */
|
|
362
|
+
dfmc: DfmcCensus;
|
|
273
363
|
counts: SbfNavCounts;
|
|
274
364
|
}
|
|
275
365
|
/**
|
|
@@ -282,6 +372,9 @@ declare function decodeSbfNavigation(data: Uint8Array, opts?: {
|
|
|
282
372
|
/** Called for every CRC-valid SBAS L1 message (all types) — feed an
|
|
283
373
|
* {@link ../positioning/sbas.SbasProcessor} to build SBAS corrections. */
|
|
284
374
|
onSbasMessage?: (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
375
|
+
/** Called for every CRC-valid native-DFMC (L5) message, with its Table
|
|
376
|
+
* B-98 type — for inspection; the payload is not field-decoded. */
|
|
377
|
+
onDfmcMessage?: DfmcMessageCb;
|
|
285
378
|
}): SbfNavigation;
|
|
286
379
|
|
|
287
380
|
/**
|
|
@@ -383,34 +476,25 @@ interface SbfGloNavResult {
|
|
|
383
476
|
}
|
|
384
477
|
declare function parseSbfGloNav(data: Uint8Array): SbfGloNavResult;
|
|
385
478
|
|
|
479
|
+
/** DFMC L5 preamble: 24-bit unique word 0x5C693A, distributed 4 bits over six
|
|
480
|
+
* successive blocks (Annex 10 §3.5.10.2). */
|
|
481
|
+
declare const SBAS_L5_PREAMBLE_UW = 6056250;
|
|
386
482
|
/**
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
483
|
+
* Classify a CRC-valid GEO message by its preamble. The L5 signal carries a
|
|
484
|
+
* mix: some GEOs relay DO-229 (L1-format) content on L5 — decodable by the
|
|
485
|
+
* existing L1 {@link ../positioning/sbas.SbasProcessor} — while others carry
|
|
486
|
+
* native DFMC frames. The 8-bit L1 preamble is checked first (definitive);
|
|
487
|
+
* anything else is treated as DFMC.
|
|
391
488
|
*/
|
|
392
|
-
declare function
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
/** Total GEORawL1 blocks seen (with valid SBF framing). */
|
|
402
|
-
messages: number;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Decode every GEORawL1 block in an SBF byte stream into SBAS GEO
|
|
406
|
-
* ephemerides (message type 9), de-duping unchanged rebroadcasts by
|
|
407
|
-
* (PRN, time-of-clock). The one-pass {@link decodeSbfNavigation} routes
|
|
408
|
-
* the same blocks through {@link feedGeoBlock}; this standalone parser
|
|
409
|
-
* mirrors the per-constellation `parseSbf*` helpers.
|
|
410
|
-
*/
|
|
411
|
-
declare function parseSbfGeoNav(data: Uint8Array, opts?: {
|
|
412
|
-
onSbasMessage?: (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
413
|
-
}): SbfGeoNavResult;
|
|
489
|
+
declare function isSbasL1Preamble(msg: Uint8Array): boolean;
|
|
490
|
+
/** L5 (DFMC) message type — 6 bits after the 4-bit preamble (Table B-98). */
|
|
491
|
+
declare function sbasL5MessageType(msg: Uint8Array): number;
|
|
492
|
+
/** Table B-98 — L5 (DFMC) broadcast message types. */
|
|
493
|
+
declare const SBAS_L5_MT_NAMES: Readonly<Record<number, string>>;
|
|
494
|
+
/** Human-readable name for an L5 (DFMC) message type. */
|
|
495
|
+
declare function sbasL5MessageName(type: number): string;
|
|
496
|
+
/** True for L5 types that carry actual corrections (vs test/null/spare). */
|
|
497
|
+
declare function isSbasL5Correction(type: number): boolean;
|
|
414
498
|
|
|
415
499
|
/** Constellations HAS corrects: GPS (GNSS ID 0), Galileo (GNSS ID 2). */
|
|
416
500
|
type HasSystem = 'G' | 'E';
|
|
@@ -647,4 +731,4 @@ interface SbfParseResult {
|
|
|
647
731
|
*/
|
|
648
732
|
declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
|
|
649
733
|
|
|
650
|
-
export { CnavEphemeris, type HasMessage, ReceiverPvt, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGeoNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfPvt, type SbfPvtResult, type SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, crc16 as sbfCrc16, scanSbfFrames };
|
|
734
|
+
export { CnavEphemeris, type DfmcCensus, type DfmcMessageCb, type GeoL5Result, type HasMessage, ReceiverPvt, SBAS_L5_MT_NAMES, SBAS_L5_PREAMBLE_UW, type SbasMessageCb, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGeoL5Result, type SbfGeoNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfPvt, type SbfPvtResult, type SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, feedGeoL5Block, isSbasL1Preamble, isSbasL5Correction, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoL5, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbasL5MessageName, sbasL5MessageType, crc16 as sbfCrc16, scanSbfFrames };
|
package/dist/sbf.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { S as SbfAlmanac, a as SbfAlmanacResult, b as SbfGlonassAlmanac, c as SbfKeplerAlmanac, d as SbfNavResult, p as parseSbfAlmanac, e as parseSbfNav } from './nav-CN8rxL4h.js';
|
|
2
2
|
import { R as ReceiverPvt } from './receiver-pvt-CVFvi4kT.js';
|
|
3
|
-
import { K as KeplerEphemeris, C as CnavEphemeris,
|
|
3
|
+
import { K as KeplerEphemeris, C as CnavEphemeris, G as GlonassEphemeris, E as Ephemeris } from './nav-DImXUdbp.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Septentrio SBF framing shared by the measurement and navigation
|
|
@@ -213,6 +213,91 @@ interface SbfCnavResult {
|
|
|
213
213
|
*/
|
|
214
214
|
declare function parseSbfCnav(data: Uint8Array): SbfCnavResult;
|
|
215
215
|
|
|
216
|
+
/** Callback fed every CRC-valid SBAS message (any type), as MSB-first bits. */
|
|
217
|
+
type SbasMessageCb = (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
218
|
+
/** Callback fed every CRC-valid native-DFMC (L5) message, with its type. */
|
|
219
|
+
type DfmcMessageCb = (msg: Uint8Array, prn: number, week: number, tow: number, type: number) => void;
|
|
220
|
+
/**
|
|
221
|
+
* Process one GEORawL1 block at frame offset `b`: extract the 250-bit
|
|
222
|
+
* SBAS L1 message, CRC-24Q gate it, and decode a GEO ephemeris if it is
|
|
223
|
+
* message type 9. Returns the ephemeris, `{ badCrc: true }` on a failed
|
|
224
|
+
* CRC, or `{}` for any other (non–type-9) message.
|
|
225
|
+
*/
|
|
226
|
+
declare function feedGeoBlock(view: DataView, b: number, onSbasMessage?: SbasMessageCb): {
|
|
227
|
+
eph?: GlonassEphemeris;
|
|
228
|
+
badCrc?: boolean;
|
|
229
|
+
};
|
|
230
|
+
/** Result of routing one GEORawL5 (4021) block. */
|
|
231
|
+
interface GeoL5Result {
|
|
232
|
+
eph?: GlonassEphemeris;
|
|
233
|
+
badCrc?: boolean;
|
|
234
|
+
/** 'l1' = DO-229 content relayed on L5 (fed to `onSbasMessage`, decodable by
|
|
235
|
+
* the L1 SbasProcessor); 'l5' = a native DFMC message (header only). */
|
|
236
|
+
kind?: 'l1' | 'l5';
|
|
237
|
+
/** Native-DFMC message type (Table B-98), when `kind === 'l5'`. */
|
|
238
|
+
dfmcType?: number;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Process one GEORawL5 block at frame offset `b`. The L5 signal carries a mix:
|
|
242
|
+
* GEOs relaying DO-229 (L1-format) content — routed to `onSbasMessage` and
|
|
243
|
+
* decoded for a GEO ephemeris exactly like {@link feedGeoBlock} — and GEOs
|
|
244
|
+
* broadcasting native DFMC frames, which are CRC-gated and surfaced via
|
|
245
|
+
* `onDfmcMessage` with their Table B-98 type but not field-decoded (see
|
|
246
|
+
* {@link ../navbits/sbas-l5}). Classification is by preamble.
|
|
247
|
+
*/
|
|
248
|
+
declare function feedGeoL5Block(view: DataView, b: number, onSbasMessage?: SbasMessageCb, onDfmcMessage?: DfmcMessageCb): GeoL5Result;
|
|
249
|
+
interface SbfGeoNavResult {
|
|
250
|
+
/** SBAS GEO ephemerides in stream order, unchanged repeats suppressed. */
|
|
251
|
+
ephemerides: GlonassEphemeris[];
|
|
252
|
+
/** GEORawL1 messages whose CRC-24Q check failed (dropped). */
|
|
253
|
+
badCrc: number;
|
|
254
|
+
/** Total GEORawL1 blocks seen (with valid SBF framing). */
|
|
255
|
+
messages: number;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Decode every GEORawL1 block in an SBF byte stream into SBAS GEO
|
|
259
|
+
* ephemerides (message type 9), de-duping unchanged rebroadcasts by
|
|
260
|
+
* (PRN, time-of-clock). The one-pass {@link decodeSbfNavigation} routes
|
|
261
|
+
* the same blocks through {@link feedGeoBlock}; this standalone parser
|
|
262
|
+
* mirrors the per-constellation `parseSbf*` helpers.
|
|
263
|
+
*/
|
|
264
|
+
declare function parseSbfGeoNav(data: Uint8Array, opts?: {
|
|
265
|
+
onSbasMessage?: (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
266
|
+
}): SbfGeoNavResult;
|
|
267
|
+
/** Census of the SBAS L5 (DFMC) frames in a stream. Correction content is not
|
|
268
|
+
* field-decoded (see {@link ../navbits/sbas-l5}). */
|
|
269
|
+
interface DfmcCensus {
|
|
270
|
+
/** Native-DFMC frame count by Table B-98 message type. */
|
|
271
|
+
byType: Record<number, number>;
|
|
272
|
+
/** GEO PRNs (e.g. 'S21') broadcasting native DFMC. */
|
|
273
|
+
prns: string[];
|
|
274
|
+
/** Total CRC-valid native-DFMC frames. */
|
|
275
|
+
messages: number;
|
|
276
|
+
}
|
|
277
|
+
interface SbfGeoL5Result {
|
|
278
|
+
/** GEO ephemerides from DO-229 (L1-format) content relayed on L5 (MT9). */
|
|
279
|
+
ephemerides: GlonassEphemeris[];
|
|
280
|
+
/** CRC-valid L5-signal frames carrying DO-229 (L1-format) content. */
|
|
281
|
+
legacyMessages: number;
|
|
282
|
+
/** Native-DFMC frame census. */
|
|
283
|
+
dfmc: DfmcCensus;
|
|
284
|
+
/** GEORawL5 frames whose CRC-24Q check failed (dropped). */
|
|
285
|
+
badCrc: number;
|
|
286
|
+
/** Total GEORawL5 blocks seen (with valid SBF framing). */
|
|
287
|
+
messages: number;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Decode every GEORawL5 (4021) block in an SBF byte stream. DO-229 (L1-format)
|
|
291
|
+
* content relayed on L5 is fed to `onSbasMessage` (usable by the L1
|
|
292
|
+
* SbasProcessor) and decoded for GEO ephemerides; native DFMC frames are
|
|
293
|
+
* CRC-gated and counted by message type. The one-pass
|
|
294
|
+
* {@link ../sbf/navigation.decodeSbfNavigation} performs the same routing.
|
|
295
|
+
*/
|
|
296
|
+
declare function parseSbfGeoL5(data: Uint8Array, opts?: {
|
|
297
|
+
onSbasMessage?: SbasMessageCb;
|
|
298
|
+
onDfmcMessage?: DfmcMessageCb;
|
|
299
|
+
}): SbfGeoL5Result;
|
|
300
|
+
|
|
216
301
|
/**
|
|
217
302
|
* One-pass SBF navigation decoder.
|
|
218
303
|
*
|
|
@@ -251,6 +336,8 @@ interface SbfNavCounts {
|
|
|
251
336
|
bdsRaw: number;
|
|
252
337
|
/** Raw SBAS L1 GEO message blocks (GEORawL1). */
|
|
253
338
|
sbasRaw: number;
|
|
339
|
+
/** Raw SBAS L5 GEO message blocks (GEORawL5) — DO-229-on-L5 + native DFMC. */
|
|
340
|
+
sbasL5Raw: number;
|
|
254
341
|
/** Frames dropped by a CRC/parity check across all raw decoders. */
|
|
255
342
|
badFrames: number;
|
|
256
343
|
}
|
|
@@ -270,6 +357,9 @@ interface SbfNavigation {
|
|
|
270
357
|
ionoCorrections: Record<string, number[]>;
|
|
271
358
|
/** GPS-UTC ΔtLS from the last GPSUtc block, if any. */
|
|
272
359
|
leapSeconds: number | null;
|
|
360
|
+
/** SBAS L5 (DFMC) native-frame census — message-type counts + GEO PRNs. The
|
|
361
|
+
* correction content is not field-decoded (see navbits/sbas-l5). */
|
|
362
|
+
dfmc: DfmcCensus;
|
|
273
363
|
counts: SbfNavCounts;
|
|
274
364
|
}
|
|
275
365
|
/**
|
|
@@ -282,6 +372,9 @@ declare function decodeSbfNavigation(data: Uint8Array, opts?: {
|
|
|
282
372
|
/** Called for every CRC-valid SBAS L1 message (all types) — feed an
|
|
283
373
|
* {@link ../positioning/sbas.SbasProcessor} to build SBAS corrections. */
|
|
284
374
|
onSbasMessage?: (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
375
|
+
/** Called for every CRC-valid native-DFMC (L5) message, with its Table
|
|
376
|
+
* B-98 type — for inspection; the payload is not field-decoded. */
|
|
377
|
+
onDfmcMessage?: DfmcMessageCb;
|
|
285
378
|
}): SbfNavigation;
|
|
286
379
|
|
|
287
380
|
/**
|
|
@@ -383,34 +476,25 @@ interface SbfGloNavResult {
|
|
|
383
476
|
}
|
|
384
477
|
declare function parseSbfGloNav(data: Uint8Array): SbfGloNavResult;
|
|
385
478
|
|
|
479
|
+
/** DFMC L5 preamble: 24-bit unique word 0x5C693A, distributed 4 bits over six
|
|
480
|
+
* successive blocks (Annex 10 §3.5.10.2). */
|
|
481
|
+
declare const SBAS_L5_PREAMBLE_UW = 6056250;
|
|
386
482
|
/**
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
483
|
+
* Classify a CRC-valid GEO message by its preamble. The L5 signal carries a
|
|
484
|
+
* mix: some GEOs relay DO-229 (L1-format) content on L5 — decodable by the
|
|
485
|
+
* existing L1 {@link ../positioning/sbas.SbasProcessor} — while others carry
|
|
486
|
+
* native DFMC frames. The 8-bit L1 preamble is checked first (definitive);
|
|
487
|
+
* anything else is treated as DFMC.
|
|
391
488
|
*/
|
|
392
|
-
declare function
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
/** Total GEORawL1 blocks seen (with valid SBF framing). */
|
|
402
|
-
messages: number;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Decode every GEORawL1 block in an SBF byte stream into SBAS GEO
|
|
406
|
-
* ephemerides (message type 9), de-duping unchanged rebroadcasts by
|
|
407
|
-
* (PRN, time-of-clock). The one-pass {@link decodeSbfNavigation} routes
|
|
408
|
-
* the same blocks through {@link feedGeoBlock}; this standalone parser
|
|
409
|
-
* mirrors the per-constellation `parseSbf*` helpers.
|
|
410
|
-
*/
|
|
411
|
-
declare function parseSbfGeoNav(data: Uint8Array, opts?: {
|
|
412
|
-
onSbasMessage?: (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
413
|
-
}): SbfGeoNavResult;
|
|
489
|
+
declare function isSbasL1Preamble(msg: Uint8Array): boolean;
|
|
490
|
+
/** L5 (DFMC) message type — 6 bits after the 4-bit preamble (Table B-98). */
|
|
491
|
+
declare function sbasL5MessageType(msg: Uint8Array): number;
|
|
492
|
+
/** Table B-98 — L5 (DFMC) broadcast message types. */
|
|
493
|
+
declare const SBAS_L5_MT_NAMES: Readonly<Record<number, string>>;
|
|
494
|
+
/** Human-readable name for an L5 (DFMC) message type. */
|
|
495
|
+
declare function sbasL5MessageName(type: number): string;
|
|
496
|
+
/** True for L5 types that carry actual corrections (vs test/null/spare). */
|
|
497
|
+
declare function isSbasL5Correction(type: number): boolean;
|
|
414
498
|
|
|
415
499
|
/** Constellations HAS corrects: GPS (GNSS ID 0), Galileo (GNSS ID 2). */
|
|
416
500
|
type HasSystem = 'G' | 'E';
|
|
@@ -647,4 +731,4 @@ interface SbfParseResult {
|
|
|
647
731
|
*/
|
|
648
732
|
declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
|
|
649
733
|
|
|
650
|
-
export { CnavEphemeris, type HasMessage, ReceiverPvt, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGeoNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfPvt, type SbfPvtResult, type SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, crc16 as sbfCrc16, scanSbfFrames };
|
|
734
|
+
export { CnavEphemeris, type DfmcCensus, type DfmcMessageCb, type GeoL5Result, type HasMessage, ReceiverPvt, SBAS_L5_MT_NAMES, SBAS_L5_PREAMBLE_UW, type SbasMessageCb, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGeoL5Result, type SbfGeoNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfPvt, type SbfPvtResult, type SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, feedGeoL5Block, isSbasL1Preamble, isSbasL5Correction, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoL5, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbasL5MessageName, sbasL5MessageType, crc16 as sbfCrc16, scanSbfFrames };
|
package/dist/sbf.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
SBAS_L5_MT_NAMES,
|
|
3
|
+
SBAS_L5_PREAMBLE_UW,
|
|
2
4
|
crc16,
|
|
3
5
|
decodeSbfNavigation,
|
|
4
6
|
feedGeoBlock,
|
|
7
|
+
feedGeoL5Block,
|
|
8
|
+
isSbasL1Preamble,
|
|
9
|
+
isSbasL5Correction,
|
|
5
10
|
parseSbfAlmanac,
|
|
6
11
|
parseSbfBdsNav,
|
|
7
12
|
parseSbfCnav,
|
|
8
13
|
parseSbfGalNav,
|
|
14
|
+
parseSbfGeoL5,
|
|
9
15
|
parseSbfGeoNav,
|
|
10
16
|
parseSbfGloNav,
|
|
11
17
|
parseSbfGpsNav,
|
|
@@ -15,8 +21,10 @@ import {
|
|
|
15
21
|
parseSbfNav,
|
|
16
22
|
parseSbfPvt,
|
|
17
23
|
parseSbfReceiverSetup,
|
|
24
|
+
sbasL5MessageName,
|
|
25
|
+
sbasL5MessageType,
|
|
18
26
|
scanSbfFrames
|
|
19
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-UHLUAU6H.js";
|
|
20
28
|
import "./chunk-FA2UTLEQ.js";
|
|
21
29
|
import "./chunk-WQX354KD.js";
|
|
22
30
|
import "./chunk-37QNKGTC.js";
|
|
@@ -26,12 +34,18 @@ import "./chunk-V2D5KUKH.js";
|
|
|
26
34
|
import "./chunk-HVXYFUCB.js";
|
|
27
35
|
import "./chunk-LEEU5OIO.js";
|
|
28
36
|
export {
|
|
37
|
+
SBAS_L5_MT_NAMES,
|
|
38
|
+
SBAS_L5_PREAMBLE_UW,
|
|
29
39
|
decodeSbfNavigation,
|
|
30
40
|
feedGeoBlock,
|
|
41
|
+
feedGeoL5Block,
|
|
42
|
+
isSbasL1Preamble,
|
|
43
|
+
isSbasL5Correction,
|
|
31
44
|
parseSbfAlmanac,
|
|
32
45
|
parseSbfBdsNav,
|
|
33
46
|
parseSbfCnav,
|
|
34
47
|
parseSbfGalNav,
|
|
48
|
+
parseSbfGeoL5,
|
|
35
49
|
parseSbfGeoNav,
|
|
36
50
|
parseSbfGloNav,
|
|
37
51
|
parseSbfGpsNav,
|
|
@@ -41,6 +55,8 @@ export {
|
|
|
41
55
|
parseSbfNav,
|
|
42
56
|
parseSbfPvt,
|
|
43
57
|
parseSbfReceiverSetup,
|
|
58
|
+
sbasL5MessageName,
|
|
59
|
+
sbasL5MessageType,
|
|
44
60
|
crc16 as sbfCrc16,
|
|
45
61
|
scanSbfFrames
|
|
46
62
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnss-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.57.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,
|