@packet-net/pdn-aprs 0.1.0 → 0.2.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/CHANGELOG.md +22 -1
- package/README.md +2 -2
- package/dist/bytes.d.ts.map +1 -1
- package/dist/bytes.js +2 -1
- package/dist/bytes.js.map +1 -1
- package/dist/codes.js +8 -8
- package/dist/codes.js.map +1 -1
- package/dist/decode/index.js +3 -5
- package/dist/decode/index.js.map +1 -1
- package/dist/decode/message.d.ts +2 -0
- package/dist/decode/message.d.ts.map +1 -1
- package/dist/decode/message.js +59 -33
- package/dist/decode/message.js.map +1 -1
- package/dist/decode/other.d.ts +20 -2
- package/dist/decode/other.d.ts.map +1 -1
- package/dist/decode/other.js +110 -48
- package/dist/decode/other.js.map +1 -1
- package/dist/decode/positioned.d.ts +10 -2
- package/dist/decode/positioned.d.ts.map +1 -1
- package/dist/decode/positioned.js +129 -77
- package/dist/decode/positioned.js.map +1 -1
- package/dist/decode/reports.d.ts.map +1 -1
- package/dist/decode/reports.js +33 -4
- package/dist/decode/reports.js.map +1 -1
- package/dist/deviceid.d.ts.map +1 -1
- package/dist/deviceid.js +18 -4
- package/dist/deviceid.js.map +1 -1
- package/dist/encode/index.d.ts.map +1 -1
- package/dist/encode/index.js +29 -12
- package/dist/encode/index.js.map +1 -1
- package/dist/encode/other.d.ts.map +1 -1
- package/dist/encode/other.js +35 -15
- package/dist/encode/other.js.map +1 -1
- package/dist/encode/position.d.ts +4 -2
- package/dist/encode/position.d.ts.map +1 -1
- package/dist/encode/position.js +65 -24
- package/dist/encode/position.js.map +1 -1
- package/dist/header.d.ts +5 -2
- package/dist/header.d.ts.map +1 -1
- package/dist/header.js +8 -3
- package/dist/header.js.map +1 -1
- package/dist/neutral.d.ts.map +1 -1
- package/dist/neutral.js +2 -0
- package/dist/neutral.js.map +1 -1
- package/dist/types.d.ts +6 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bytes.ts +2 -1
- package/src/codes.ts +8 -8
- package/src/decode/index.ts +3 -4
- package/src/decode/message.ts +54 -37
- package/src/decode/other.ts +116 -44
- package/src/decode/positioned.ts +133 -88
- package/src/decode/reports.ts +31 -3
- package/src/deviceid.ts +17 -2
- package/src/encode/index.ts +30 -12
- package/src/encode/other.ts +27 -11
- package/src/encode/position.ts +62 -21
- package/src/header.ts +9 -2
- package/src/neutral.ts +2 -0
- package/src/types.ts +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.2.0
|
|
6
|
+
|
|
7
|
+
- Faster decoding, about a third less time per packet: the device a destination identifies is remembered rather than matched against the whole device database for every packet, and bytes become text without an intermediate copy.
|
|
8
|
+
- Brought into line with the rulings from seven rounds of differential fuzzing of all five implementations (packet-net/aprs-vectors, commit dc3854a, 159 new cases). Passes every check.
|
|
9
|
+
- **API change:** `NmeaSentence` gains `comment`, the text after the checksum as sent (TinyTrack and FreeTrak send one), and the neutral form writes it as `comment`. `sentence` now ends at the checksum. A sentence is `$`, an address of five upper-case letters or digits (or `P` and three or more), at least one field, printable ASCII, and at most one `*`, which must start a two-digit checksum; anything else is `invalid-nmea`, found before a checksum mismatch. Only GGA, GLL, RMC, VTG and WPL are read, and only from an approved address, so a proprietary sentence such as `$PGRMC` is kept as text. A position needs both coordinates, and a time must be in range. A speed, course or altitude may start with its decimal point (`.30`).
|
|
10
|
+
- **API change:** `CommentTelemetry.digital` is the eight binary channels, 0-255; bits 9-13 of the value are reserved and ignored, and the encoder refuses a value over 255. `Dao.datum` may be a digit, a local datum, which only carries precision `none`.
|
|
11
|
+
- Messages: an addressee field whose tenth byte is `:` is read as the addressee whatever it holds; `ack` or `rej` and an ID followed by anything but a message ID is a plain message; bulletins, NWS bulletins and telemetry metadata do not take the reply-ack form (`{12}` stays in the text, with `brace-in-message-text`); an `EQNS.` coefficient has no `+`, only spaces around it, and must be a finite number. A directed query's target may follow one space, and spaces after it are padding; the encoder pads an APRSH target to 9 characters and writes a target after a type the spec does not define after one space.
|
|
12
|
+
- Station capabilities: spaces (and only spaces) around an item, a token or a value are padding, so `MSG_CNT = 43` is `MSG_CNT` and `43`; a control character in a token or a value makes the report free text. The encoder refuses anything that would not read back the same.
|
|
13
|
+
- A general query footprint outside 90 degrees of latitude or 180 of longitude is `invalid-general-query`, a positive longitude may have a leading space, and each value is a number as a telemetry value is, so it may start with its decimal point (`-.1715`). An Agrelo DF report is exactly `%nnn/n` with a bearing of 0 to 360. A status `^` beam heading needs an ERP code of 1 to K; `^B0` is text.
|
|
14
|
+
- A third-party header's source may be any 1-9 printable ASCII characters but `>` and `:` (APRS12c ch. 17). A q-construct is read only in the outer header, so a third-party packet no longer has a `qConstruct` from its own path. A third-party packet whose inner information field is empty re-encodes as it came.
|
|
15
|
+
- Positions: a latitude whose ambiguity centres it past the pole (`90 . N`) is `invalid-latitude`, and a longitude centred past 180 degrees is `invalid-longitude`; a longitude place the latitude's ambiguity blanks may hold a digit or a space; a DF bearing over 360 is `out-of-range-value` and the whole `/BRG/NRQ` is dropped; a microwave band letter is upper case (`n47.150MHz` is comment text); a `!DAO!` with a digit datum and spaces is read; a signpost is printable ASCII, and the encoder writes one with a space in it (`{5 }`), which it refused; a signpost or corridor is the first well-formed braces, so braces that do not qualify (`{AB}` before a corridor's `{5}`) no longer stop the search, and when a comment holds braces that would be taken for the signpost or corridor, the encoder writes the braces before the comment (`{5p5}{AB}`) instead of refusing; the `!DAO!` is judged before the comment's encoding; and a compressed GGA altitude of 1 foot or less is written as the nearest cs value with a `/A=`, where it was refused.
|
|
16
|
+
- Weather: the wind speed in a compressed weather position's cs bytes is converted from knots with the exact factor, 1852 / 1609.344, not a rounded one, so it agrees with the other implementations past the ninth significant figure. In a position, object or item report, the wind is judged where the `DDD/SSS` extension belongs, before any field, so strict decoding rejects missing wind or wind fields before a field's width; a `c` field without an `s` leaves the wind incomplete; `L` and `l` are one field; snowfall may be written with a decimal point (`s.50` is 0.5 inches), and a run of dots is read only up to the field's width, and is not a field when a digit follows it (`s..6` is text); the encoder writes a snowfall exactly in its three characters, with a decimal point where it needs one (0.32 as `.32`), where it refused 0.32 and 0.05; and a positionless report keeps base-91 telemetry and `!DAO!` text in its comment.
|
|
17
|
+
- Mic-E: the Rev 0 data type identifiers 0x1C and 0x1D get an `obsolete-format` info, before anything else is checked; a destination latitude of 90 degrees with blanked digits, whose centre is past the pole, is `invalid-mic-e-destination`; a data extension straight after the type code is read before an altitude is looked for later in the text, so `0PH}` in `PHG3330PH}` is not an altitude; a `!DAO!` is never read across an altitude taken out of the text; and status text that would start with 0x1D is written after a `/`, as APRS12c requires, where it was written plainly when it could not be read as Rev 0 telemetry.
|
|
18
|
+
- `scripts/diff-dump.mjs` re-decodes a re-encoded packet under a well-formed header (the computed destination for Mic-E), so a defect in the original header, such as an empty destination, is no longer counted against the encoder.
|
|
19
|
+
|
|
20
|
+
## 0.1.1
|
|
21
|
+
|
|
22
|
+
- Mic-E Rev 0 binary telemetry (0x1D and five bytes after the symbol) is read into `legacyTelemetry`, with an `obsolete-format` info, and written back; it was left in the comment and refused on encoding. A value of 255 is refused. The ruling is shared by all five implementations (packet-net/aprs-vectors, "Mic-E Rev 0 binary telemetry").
|
|
23
|
+
|
|
24
|
+
## 0.1.0
|
|
4
25
|
|
|
5
26
|
First release.
|
|
6
27
|
|
package/README.md
CHANGED
|
@@ -145,7 +145,7 @@ try {
|
|
|
145
145
|
}
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
-
The encoder also works on data directly: `encodeInformation(data)` returns the information field bytes (and for Mic-E the destination), and `encodeTnc2` / `encodeAx25` a whole packet. Decoding and encoding again round-trips: data from the decoder encodes back to the same bytes, or to bytes that decode to the same data.
|
|
148
|
+
The encoder also works on data directly: `encodeInformation(data)` returns the information field bytes (and for Mic-E the destination), and `encodeTnc2` / `encodeAx25` a whole packet. Decoding and encoding again round-trips: data from the decoder encodes back to the same bytes, or to bytes that decode to the same data, or is refused when there are none. It is never written as bytes that read back as different data, apart from wind or a range going back into a compressed position's cs bytes, which carry them in steps.
|
|
149
149
|
|
|
150
150
|
## Symbols
|
|
151
151
|
|
|
@@ -174,7 +174,7 @@ console.log(identifyTocall('APDW18')?.model); // DireWolf
|
|
|
174
174
|
|
|
175
175
|
## Conformance
|
|
176
176
|
|
|
177
|
-
The conformance vectors are a git submodule at `vectors/`. The test suite runs every case with every check the vectors' README defines (the lenient result, the strict result, the single-tolerance check, re-encoding, and the encode cases), one test per check per case:
|
|
177
|
+
The conformance vectors are a git submodule at `vectors/`. The test suite runs every case with every check the vectors' README defines (the lenient result, the strict result, the single-tolerance check, re-encoding, and the encode cases), one test per check per case: 6,015 tests, all passing. A check this implementation could not pass would be listed in `test/known-differences.json` with the reason and skipped; the list is empty.
|
|
178
178
|
|
|
179
179
|
`scripts/diff-dump.mjs` writes the differential dump that the vectors' `tools/compare.py` reads, for comparing implementations over a whole capture:
|
|
180
180
|
|
package/dist/bytes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"AAIA,8BAA8B;AAC9B,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,SAAI,EAAE,GAAG,SAAe,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"AAIA,8BAA8B;AAC9B,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,SAAI,EAAE,GAAG,SAAe,GAAG,MAAM,CAQtF;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAInD;AAED,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAG1C;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA2C9D;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAEhE;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBrD;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEnD;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAMlD;AAED,uCAAuC;AACvC,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD"}
|
package/dist/bytes.js
CHANGED
|
@@ -6,7 +6,8 @@ export function bytesToBinary(bytes, start = 0, end = bytes.length) {
|
|
|
6
6
|
let s = '';
|
|
7
7
|
const CHUNK = 8192;
|
|
8
8
|
for (let i = start; i < end; i += CHUNK) {
|
|
9
|
-
|
|
9
|
+
// apply takes the typed array directly; copying it into an Array first doubled the cost.
|
|
10
|
+
s += String.fromCharCode.apply(null, bytes.subarray(i, Math.min(end, i + CHUNK)));
|
|
10
11
|
}
|
|
11
12
|
return s;
|
|
12
13
|
}
|
package/dist/bytes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,2FAA2F;AAC3F,kFAAkF;AAElF,8BAA8B;AAC9B,MAAM,UAAU,aAAa,CAAC,KAAiB,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM;IAC5E,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,MAAM,KAAK,GAAG,IAAI,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;QACxC,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../src/bytes.ts"],"names":[],"mappings":"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"}
|
package/dist/codes.js
CHANGED
|
@@ -16,7 +16,7 @@ export const DIAGNOSTIC_MEANINGS = {
|
|
|
16
16
|
'truncated': "The information field is shorter than its format requires.",
|
|
17
17
|
'not-aprs': "The first byte is not a data type identifier (APRS12c ch. 20).",
|
|
18
18
|
'reserved-data-type': "A reserved data type identifier with no defined format (APRS12c ch. 5).",
|
|
19
|
-
'obsolete-format': "A format the spec marks obsolete or not recommended, e.g. raw NMEA or
|
|
19
|
+
'obsolete-format': "A format the spec marks obsolete or not recommended, e.g. raw NMEA, raw weather, or the Rev 0 Mic-E data type identifiers 0x1C and 0x1D.",
|
|
20
20
|
'out-of-range-value': "A value in a well-formed field is out of range and was dropped.",
|
|
21
21
|
'invalid-timestamp': "A timestamp is malformed or out of range (APRS12c ch. 6, UAP 5.8).",
|
|
22
22
|
'invalid-position': "The position is missing or starts with something that cannot begin one.",
|
|
@@ -37,7 +37,7 @@ export const DIAGNOSTIC_MEANINGS = {
|
|
|
37
37
|
'invalid-weather': "Positionless or raw weather data that could not be decoded.",
|
|
38
38
|
'invalid-mic-e-destination': "The destination address is not a valid Mic-E encoding (APRS12c ch. 10).",
|
|
39
39
|
'invalid-mic-e-information': "The Mic-E information field is malformed (APRS12c ch. 10).",
|
|
40
|
-
'kenwood-ff-padding': "Kenwood TM-D710 0xFF padding was removed (UAP 5.10).",
|
|
40
|
+
'kenwood-ff-padding': "Kenwood TM-D710 0xFF padding was removed from Mic-E status text, after the destination and the nine fixed bytes decoded (UAP 5.10).",
|
|
41
41
|
'mic-e-missing-device-type': "A Mic-E report without a device type prefix (UAP 5.4).",
|
|
42
42
|
'invalid-message': "A message is malformed (APRS12c ch. 14).",
|
|
43
43
|
'unpadded-addressee': "The addressee is not padded to 9 characters.",
|
|
@@ -47,13 +47,13 @@ export const DIAGNOSTIC_MEANINGS = {
|
|
|
47
47
|
'invalid-telemetry': "A telemetry report is malformed (APRS12c ch. 13).",
|
|
48
48
|
'invalid-status': "A status report is malformed (APRS12c ch. 16).",
|
|
49
49
|
'invalid-locator': "A Maidenhead locator is malformed.",
|
|
50
|
-
'invalid-nmea': "
|
|
50
|
+
'invalid-nmea': "The text after $ is not an NMEA 0183 sentence: not printable ASCII, no valid address field, or a reserved character in a field.",
|
|
51
51
|
'nmea-checksum-mismatch': "An NMEA sentence's checksum does not match, so the sentence is corrupt and is not decoded.",
|
|
52
|
-
'invalid-third-party': "A third-party header is malformed (APRS12c ch. 17).",
|
|
53
|
-
'invalid-general-query': "A general query is malformed (APRS12c ch. 15).",
|
|
52
|
+
'invalid-third-party': "A third-party header is malformed, or (strict) its inner header has a defect a lenient decoder tolerates (APRS12c ch. 17).",
|
|
53
|
+
'invalid-general-query': "A general query is malformed, or its footprint is out of range (APRS12c ch. 15).",
|
|
54
54
|
'invalid-capabilities': "A station capabilities report is malformed (APRS12c ch. 15).",
|
|
55
55
|
'invalid-user-defined': "A user-defined packet is shorter than its 3-byte header (APRS12c ch. 19).",
|
|
56
|
-
'invalid-agrelo-df': "An Agrelo DF report is
|
|
56
|
+
'invalid-agrelo-df': "An Agrelo DF report is not exactly %, a bearing of 000 to 360, / and a quality digit.",
|
|
57
57
|
'missing-space-after-locator': "A grid-locator status report lacks the mandatory space before its text (UAP 5.17).",
|
|
58
58
|
'compression-type-reserved-bits': "A compressed position's type byte sets its unused high bits (APRS12c ch. 9).",
|
|
59
59
|
'malformed-timestamp': "A timestamped position report whose timestamp is missing or not timestamp-shaped (UAP 5.8).",
|
|
@@ -62,10 +62,10 @@ export const DIAGNOSTIC_MEANINGS = {
|
|
|
62
62
|
'wind-fields-instead-of-extension': "Wind sent as c/s fields in a position weather report instead of the DDD/SSS extension, or after a compressed position whose cs bytes carry no wind.",
|
|
63
63
|
'wind-extension-after-compressed': "An uncompressed wind extension after a compressed weather position (UAP 5.33).",
|
|
64
64
|
'mic-e-altitude-not-first': "A Mic-E altitude after other status text instead of first (APRS12c ch. 10).",
|
|
65
|
-
'brace-in-message-text': "Message text contains a { that does not start a valid message ID (APRS12c ch. 14).",
|
|
65
|
+
'brace-in-message-text': "Message, bulletin or telemetry metadata text contains a { that does not start a valid message ID, including the reply-ack form on a bulletin or metadata (APRS12c ch. 14).",
|
|
66
66
|
'invalid-addressee-characters': "A message addressee contains a space or : (APRS12c ch. 14).",
|
|
67
67
|
'letter-group-bulletin': "A bulletin addressee has a group name after a letter, e.g. BLNCNET; group bulletins use a digit (APRS12c ch. 14).",
|
|
68
|
-
'free-text-capabilities': "A < station capabilities packet holds free text rather than TOKEN / TOKEN=VALUE items (APRS12c ch. 15).",
|
|
68
|
+
'free-text-capabilities': "A < station capabilities packet holds free text rather than TOKEN / TOKEN=VALUE items: a token that is empty or holds a space or a control character, or a value that holds a control character (APRS12c ch. 15).",
|
|
69
69
|
};
|
|
70
70
|
/** Every tolerable code. */
|
|
71
71
|
export const TOLERABLE_CODES = [
|
package/dist/codes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codes.js","sourceRoot":"","sources":["../src/codes.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,2DAA2D;AAwG3D,4CAA4C;AAC5C,MAAM,CAAC,MAAM,mBAAmB,GAA6C;IAC3E,gBAAgB,EAAE,6CAA6C;IAC/D,iBAAiB,EAAE,6EAA6E;IAChG,mBAAmB,EAAE,6CAA6C;IAClE,kBAAkB,EAAE,mDAAmD;IACvE,uBAAuB,EAAE,8FAA8F;IACvH,gBAAgB,EAAE,mFAAmF;IACrG,oBAAoB,EAAE,oEAAoE;IAC1F,iCAAiC,EAAE,2EAA2E;IAC9G,sBAAsB,EAAE,uDAAuD;IAC/E,qBAAqB,EAAE,qEAAqE;IAC5F,eAAe,EAAE,0CAA0C;IAC3D,WAAW,EAAE,4DAA4D;IACzE,UAAU,EAAE,gEAAgE;IAC5E,oBAAoB,EAAE,yEAAyE;IAC/F,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"codes.js","sourceRoot":"","sources":["../src/codes.ts"],"names":[],"mappings":"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"}
|
package/dist/decode/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// The information field decoder: picks the format by the data type identifier.
|
|
2
2
|
import { binaryToBytes, bytesToBinary } from '../bytes.js';
|
|
3
|
-
import {
|
|
3
|
+
import { parseHeaderText } from '../header.js';
|
|
4
4
|
import { DecodeContext, Rejected } from './context.js';
|
|
5
5
|
import { decodeMessage } from './message.js';
|
|
6
6
|
import { decodeAgrelo, decodeCapabilities, decodeDollar, decodeMaidenhead, decodeQuery, decodeRawWeather, decodeStatus, decodeTelemetry, decodeTest, decodeUserDefined, } from './other.js';
|
|
@@ -98,7 +98,7 @@ function decodeThirdParty(ctx, s, options) {
|
|
|
98
98
|
const headerDiags = [];
|
|
99
99
|
let header;
|
|
100
100
|
try {
|
|
101
|
-
header = parseHeaderText(body.slice(0, colon), options, headerDiags);
|
|
101
|
+
header = parseHeaderText(body.slice(0, colon), options, headerDiags, true);
|
|
102
102
|
}
|
|
103
103
|
catch {
|
|
104
104
|
return ctx.fail('invalid-third-party');
|
|
@@ -113,9 +113,7 @@ function decodeThirdParty(ctx, s, options) {
|
|
|
113
113
|
data: inner.data,
|
|
114
114
|
diagnostics: [...headerDiags, ...inner.diagnostics],
|
|
115
115
|
};
|
|
116
|
-
|
|
117
|
-
if (q)
|
|
118
|
-
packet.qConstruct = q;
|
|
116
|
+
// A q-construct is read only in the outer header: the third-party path is kept as sent.
|
|
119
117
|
return { type: 'third-party', packet };
|
|
120
118
|
}
|
|
121
119
|
//# sourceMappingURL=index.js.map
|
package/dist/decode/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decode/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAE/E,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decode/index.ts"],"names":[],"mappings":"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"}
|
package/dist/decode/message.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AprsData } from '../types.js';
|
|
2
2
|
import type { DecodeContext } from './context.js';
|
|
3
|
+
/** Known directed query types (APRS12c ch. 15), longest first. */
|
|
4
|
+
export declare const DIRECTED_QUERY_TYPES: readonly string[];
|
|
3
5
|
/** `:`: a message, or one of the things sent in message form. */
|
|
4
6
|
export declare function decodeMessage(ctx: DecodeContext, s: string): AprsData;
|
|
5
7
|
//# sourceMappingURL=message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/decode/message.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/decode/message.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAA6E,CAAC;AAsChI,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CA0ErE"}
|
package/dist/decode/message.js
CHANGED
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
// Messages, acks and rejects, bulletins, telemetry metadata and directed queries (APRS12c ch.
|
|
2
2
|
// 13-15).
|
|
3
3
|
/** Known directed query types (APRS12c ch. 15), longest first. */
|
|
4
|
-
const DIRECTED_QUERY_TYPES = ['APRSD', 'APRSH', 'APRSM', 'APRSO', 'APRSP', 'APRSS', 'APRST', 'PING?'];
|
|
4
|
+
export const DIRECTED_QUERY_TYPES = ['APRSD', 'APRSH', 'APRSM', 'APRSO', 'APRSP', 'APRSS', 'APRST', 'PING?'];
|
|
5
5
|
const MESSAGE_ID_RE = /^([A-Za-z0-9]{1,5})(?:\}([A-Za-z0-9]{0,5}))?$/;
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const PLAIN_ID_RE = /^([A-Za-z0-9]{1,5})$/;
|
|
7
|
+
// ack or rej, the ID, an optional reply-ack, and an optional message ID of its own.
|
|
8
|
+
const ACK_RE = /^(ack|rej)([A-Za-z0-9]{1,5})(?:\}([A-Za-z0-9]{0,5}))?(\{[A-Za-z0-9]{1,5})?$/;
|
|
9
|
+
// A number: an optional -, digits with an optional point, and for a coefficient an exponent.
|
|
10
|
+
const COEFFICIENT_RE = /^-?(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
11
|
+
const METADATA_PREFIXES = ['PARM.', 'UNIT.', 'EQNS.', 'BITS.'];
|
|
12
|
+
/**
|
|
13
|
+
* Splits `text{id}ack` into its parts. Bulletins and telemetry metadata are not acknowledged, so
|
|
14
|
+
* for them (`replyAcks` false) the reply-ack form is not an ID and stays in the text (vectors
|
|
15
|
+
* interpretations.md, "Reply-acks are for messages").
|
|
16
|
+
*/
|
|
17
|
+
function splitMessageId(text, replyAcks) {
|
|
10
18
|
const brace = text.lastIndexOf('{');
|
|
11
19
|
if (brace < 0)
|
|
12
|
-
return { text };
|
|
13
|
-
const m = MESSAGE_ID_RE.exec(text.slice(brace + 1));
|
|
14
|
-
if (!m)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
const out = { text: text.slice(0, brace), messageId: m[1] };
|
|
20
|
+
return { text, strayBrace: false };
|
|
21
|
+
const m = (replyAcks ? MESSAGE_ID_RE : PLAIN_ID_RE).exec(text.slice(brace + 1));
|
|
22
|
+
if (!m)
|
|
23
|
+
return { text, strayBrace: true };
|
|
24
|
+
const out = { text: text.slice(0, brace), messageId: m[1], strayBrace: false };
|
|
19
25
|
if (m[2] !== undefined)
|
|
20
26
|
out.replyAck = m[2];
|
|
21
27
|
if (out.text.includes('{'))
|
|
22
|
-
|
|
28
|
+
out.strayBrace = true;
|
|
23
29
|
return out;
|
|
24
30
|
}
|
|
25
31
|
function parseList(body) {
|
|
@@ -27,13 +33,14 @@ function parseList(body) {
|
|
|
27
33
|
}
|
|
28
34
|
/** `:`: a message, or one of the things sent in message form. */
|
|
29
35
|
export function decodeMessage(ctx, s) {
|
|
30
|
-
|
|
31
|
-
ctx.fail('invalid-message');
|
|
36
|
+
// When the tenth byte is :, the addressee is the nine bytes before it, whatever they hold.
|
|
32
37
|
let colon = -1;
|
|
33
38
|
if (s.length > 10 && s[10] === ':') {
|
|
34
39
|
colon = 10;
|
|
35
40
|
}
|
|
36
41
|
else {
|
|
42
|
+
if (s[1] === ':')
|
|
43
|
+
ctx.fail('invalid-message');
|
|
37
44
|
for (let k = 2; k <= 9 && k < s.length; k++) {
|
|
38
45
|
if (s[k] === ':') {
|
|
39
46
|
colon = k;
|
|
@@ -69,12 +76,16 @@ export function decodeMessage(ctx, s) {
|
|
|
69
76
|
if (/^BLN[0-9]/.test(addressee) || /^BLN[A-Z]$/.test(addressee) || /^BLN[A-Z]./.test(addressee)) {
|
|
70
77
|
if (/^BLN[A-Z]./.test(addressee))
|
|
71
78
|
ctx.tolerate('letter-group-bulletin');
|
|
72
|
-
const split = splitMessageId(
|
|
79
|
+
const split = splitMessageId(body, false);
|
|
80
|
+
if (split.strayBrace)
|
|
81
|
+
ctx.tolerate('brace-in-message-text');
|
|
73
82
|
const text = ctx.text(split.text);
|
|
74
83
|
return withId({ type: 'bulletin', addressee, text }, split.messageId);
|
|
75
84
|
}
|
|
76
85
|
if (/^NWS[-_]/.test(addressee)) {
|
|
77
|
-
const split = splitMessageId(
|
|
86
|
+
const split = splitMessageId(body, false);
|
|
87
|
+
if (split.strayBrace)
|
|
88
|
+
ctx.tolerate('brace-in-message-text');
|
|
78
89
|
const text = ctx.text(split.text);
|
|
79
90
|
return withId({ type: 'nws-bulletin', addressee, text }, split.messageId);
|
|
80
91
|
}
|
|
@@ -84,11 +95,15 @@ export function decodeMessage(ctx, s) {
|
|
|
84
95
|
if (query)
|
|
85
96
|
return query;
|
|
86
97
|
}
|
|
87
|
-
const split = splitMessageId(ctx, body);
|
|
88
98
|
// Telemetry metadata: its structure is checked before the text's encoding.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
99
|
+
if (METADATA_PREFIXES.includes(body.slice(0, 5))) {
|
|
100
|
+
const meta = telemetryMetadata(ctx, addressee, body);
|
|
101
|
+
if (meta)
|
|
102
|
+
return meta;
|
|
103
|
+
}
|
|
104
|
+
const split = splitMessageId(body, true);
|
|
105
|
+
if (split.strayBrace)
|
|
106
|
+
ctx.tolerate('brace-in-message-text');
|
|
92
107
|
const text = ctx.text(split.text);
|
|
93
108
|
const message = {
|
|
94
109
|
type: 'message',
|
|
@@ -129,11 +144,11 @@ function directedQuery(ctx, addressee, body) {
|
|
|
129
144
|
queryType = m[1];
|
|
130
145
|
rest = q.slice(queryType.length);
|
|
131
146
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const target = rest.
|
|
147
|
+
// One space between the type and the target is a separator, and spaces after the target are
|
|
148
|
+
// padding (APRSH pads its target to 9 characters).
|
|
149
|
+
if (rest.startsWith(' '))
|
|
150
|
+
rest = rest.slice(1);
|
|
151
|
+
const target = rest.replace(/ +$/, '');
|
|
137
152
|
if (target.length === 0)
|
|
138
153
|
return { type: 'directed-query', addressee, queryType };
|
|
139
154
|
if (/^[A-Za-z0-9-]{1,9}$/.test(target))
|
|
@@ -141,19 +156,26 @@ function directedQuery(ctx, addressee, body) {
|
|
|
141
156
|
ctx.info('invalid-query');
|
|
142
157
|
return undefined;
|
|
143
158
|
}
|
|
144
|
-
/** Telemetry metadata sent as a message; `
|
|
145
|
-
function telemetryMetadata(ctx, addressee,
|
|
159
|
+
/** Telemetry metadata sent as a message; `body` is the text's bytes, decoded once it is valid. */
|
|
160
|
+
function telemetryMetadata(ctx, addressee, body) {
|
|
161
|
+
// Metadata takes a message ID, but not the reply-ack form.
|
|
162
|
+
const split = splitMessageId(body, false);
|
|
163
|
+
const binary = split.text;
|
|
164
|
+
const messageId = split.messageId;
|
|
146
165
|
const kind = binary.slice(0, 5);
|
|
147
|
-
if (kind !== 'PARM.' && kind !== 'UNIT.' && kind !== 'EQNS.' && kind !== 'BITS.')
|
|
148
|
-
return undefined;
|
|
149
166
|
const rawBody = binary.slice(5);
|
|
150
167
|
const invalid = () => {
|
|
151
168
|
ctx.info('invalid-telemetry-metadata');
|
|
152
169
|
return undefined;
|
|
153
170
|
};
|
|
171
|
+
const braces = () => {
|
|
172
|
+
if (split.strayBrace)
|
|
173
|
+
ctx.tolerate('brace-in-message-text');
|
|
174
|
+
};
|
|
154
175
|
if (kind === 'PARM.' || kind === 'UNIT.') {
|
|
155
176
|
if (parseList(rawBody).length > 13)
|
|
156
177
|
return invalid();
|
|
178
|
+
braces();
|
|
157
179
|
const list = parseList(ctx.text(rawBody));
|
|
158
180
|
return kind === 'PARM.'
|
|
159
181
|
? withId({ type: 'telemetry-names', addressee, names: list }, messageId)
|
|
@@ -162,22 +184,26 @@ function telemetryMetadata(ctx, addressee, binary, messageId) {
|
|
|
162
184
|
if (kind === 'EQNS.') {
|
|
163
185
|
const list = parseList(rawBody);
|
|
164
186
|
// Trailing empty entries (commas and spaces) are the list stopping.
|
|
165
|
-
while (list.length > 0 && list[list.length - 1]
|
|
187
|
+
while (list.length > 0 && /^ *$/.test(list[list.length - 1]))
|
|
166
188
|
list.pop();
|
|
167
189
|
if (list.length === 0 || list.length > 15)
|
|
168
190
|
return invalid();
|
|
169
191
|
const texts = [];
|
|
170
192
|
for (const item of list) {
|
|
171
|
-
|
|
172
|
-
|
|
193
|
+
// Spaces (U+0020 only) around a coefficient are padding (vectors interpretations.md,
|
|
194
|
+
// "Numbers in telemetry").
|
|
195
|
+
const t = item.replace(/^ +| +$/g, '');
|
|
196
|
+
if (!COEFFICIENT_RE.test(t) || !Number.isFinite(Number(t)))
|
|
173
197
|
return invalid();
|
|
174
198
|
texts.push(t);
|
|
175
199
|
}
|
|
200
|
+
braces();
|
|
176
201
|
return withId({ type: 'telemetry-coefficients', addressee, coefficients: texts.map(Number), coefficientsText: texts }, messageId);
|
|
177
202
|
}
|
|
178
203
|
const m = /^([01]{8})(?:,(.*))?$/s.exec(rawBody);
|
|
179
204
|
if (!m)
|
|
180
205
|
return invalid();
|
|
206
|
+
braces();
|
|
181
207
|
const bits = {
|
|
182
208
|
type: 'telemetry-bits',
|
|
183
209
|
addressee,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/decode/message.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,UAAU;AAKV,kEAAkE;AAClE,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/decode/message.ts"],"names":[],"mappings":"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"}
|
package/dist/decode/other.d.ts
CHANGED
|
@@ -8,8 +8,26 @@ export declare function decodeTelemetry(ctx: DecodeContext, s: string): Telemetr
|
|
|
8
8
|
export declare function decodeQuery(ctx: DecodeContext, s: string): Query;
|
|
9
9
|
/** `<`: station capabilities. */
|
|
10
10
|
export declare function decodeCapabilities(ctx: DecodeContext, s: string): Capabilities;
|
|
11
|
-
/**
|
|
12
|
-
export
|
|
11
|
+
/** An NMEA 0183 sentence taken apart. */
|
|
12
|
+
export interface NmeaParts {
|
|
13
|
+
/** The sentence, up to and including any `*hh` checksum. */
|
|
14
|
+
sentence: string;
|
|
15
|
+
/** The comma-separated fields before any checksum, the address field first. */
|
|
16
|
+
fields: string[];
|
|
17
|
+
/** Whether the sentence has a checksum. */
|
|
18
|
+
hasChecksum: boolean;
|
|
19
|
+
/** Whether the checksum matches; true when there is none. */
|
|
20
|
+
checksumOk: boolean;
|
|
21
|
+
/** Whatever follows the checksum. */
|
|
22
|
+
rest: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Takes the text after `$` apart as an NMEA 0183 sentence (vectors interpretations.md, "What $
|
|
26
|
+
* text is an NMEA sentence"): printable ASCII, an address field of five upper-case letters or
|
|
27
|
+
* digits (or `P` and three or more), at least one field, no `$`, and no `*` but the one that
|
|
28
|
+
* starts a checksum of two hex digits, which ends the sentence. `undefined` when it is not one.
|
|
29
|
+
*/
|
|
30
|
+
export declare function splitNmea(text: string): NmeaParts | undefined;
|
|
13
31
|
/** `$`: raw NMEA, or Ultimeter raw weather (`$ULTW`). */
|
|
14
32
|
export declare function decodeDollar(ctx: DecodeContext, s: string): NmeaSentence | RawWeather;
|
|
15
33
|
/** Raw weather station data, kept as text. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"other.d.ts","sourceRoot":"","sources":["../../src/decode/other.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,QAAQ,EAER,YAAY,EAEZ,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAYlD,4BAA4B;AAC5B,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"other.d.ts","sourceRoot":"","sources":["../../src/decode/other.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,QAAQ,EAER,YAAY,EAEZ,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAYlD,4BAA4B;AAC5B,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,CAqCxE;AAID,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,eAAe,CA0D9E;AAMD,4BAA4B;AAC5B,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAiBhE;AAcD,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,CAmB9E;AAwCD,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACxB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,2CAA2C;IAC3C,WAAW,EAAE,OAAO,CAAC;IACrB,6DAA6D;IAC7D,UAAU,EAAE,OAAO,CAAC;IACpB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAgB7D;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,CA8DrF;AAED,8CAA8C;AAC9C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAIvG;AAED,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAU5E;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAGlE;AAED,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAKpE;AAED,wCAAwC;AACxC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAWhF"}
|