@packet-net/pdn-aprs 0.1.1 → 0.3.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.
Files changed (81) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/README.md +9 -5
  3. package/dist/builder.d.ts +33 -8
  4. package/dist/builder.d.ts.map +1 -1
  5. package/dist/builder.js +64 -10
  6. package/dist/builder.js.map +1 -1
  7. package/dist/bytes.d.ts.map +1 -1
  8. package/dist/bytes.js +2 -1
  9. package/dist/bytes.js.map +1 -1
  10. package/dist/codes.js +8 -8
  11. package/dist/codes.js.map +1 -1
  12. package/dist/decode/index.d.ts.map +1 -1
  13. package/dist/decode/index.js +8 -5
  14. package/dist/decode/index.js.map +1 -1
  15. package/dist/decode/message.d.ts +2 -0
  16. package/dist/decode/message.d.ts.map +1 -1
  17. package/dist/decode/message.js +59 -33
  18. package/dist/decode/message.js.map +1 -1
  19. package/dist/decode/other.d.ts +20 -2
  20. package/dist/decode/other.d.ts.map +1 -1
  21. package/dist/decode/other.js +110 -48
  22. package/dist/decode/other.js.map +1 -1
  23. package/dist/decode/positioned.d.ts +26 -2
  24. package/dist/decode/positioned.d.ts.map +1 -1
  25. package/dist/decode/positioned.js +145 -79
  26. package/dist/decode/positioned.js.map +1 -1
  27. package/dist/decode/reports.d.ts.map +1 -1
  28. package/dist/decode/reports.js +47 -5
  29. package/dist/decode/reports.js.map +1 -1
  30. package/dist/decoder.d.ts.map +1 -1
  31. package/dist/decoder.js +2 -4
  32. package/dist/decoder.js.map +1 -1
  33. package/dist/deviceid.d.ts +8 -2
  34. package/dist/deviceid.d.ts.map +1 -1
  35. package/dist/deviceid.js +28 -6
  36. package/dist/deviceid.js.map +1 -1
  37. package/dist/encode/common.d.ts +13 -2
  38. package/dist/encode/common.d.ts.map +1 -1
  39. package/dist/encode/common.js +36 -4
  40. package/dist/encode/common.js.map +1 -1
  41. package/dist/encode/index.d.ts.map +1 -1
  42. package/dist/encode/index.js +59 -22
  43. package/dist/encode/index.js.map +1 -1
  44. package/dist/encode/other.d.ts.map +1 -1
  45. package/dist/encode/other.js +45 -17
  46. package/dist/encode/other.js.map +1 -1
  47. package/dist/encode/position.d.ts +9 -3
  48. package/dist/encode/position.d.ts.map +1 -1
  49. package/dist/encode/position.js +258 -124
  50. package/dist/encode/position.js.map +1 -1
  51. package/dist/header.d.ts +5 -2
  52. package/dist/header.d.ts.map +1 -1
  53. package/dist/header.js +8 -3
  54. package/dist/header.js.map +1 -1
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/neutral.d.ts.map +1 -1
  59. package/dist/neutral.js +22 -3
  60. package/dist/neutral.js.map +1 -1
  61. package/dist/types.d.ts +19 -9
  62. package/dist/types.d.ts.map +1 -1
  63. package/package.json +1 -1
  64. package/src/builder.ts +77 -14
  65. package/src/bytes.ts +2 -1
  66. package/src/codes.ts +8 -8
  67. package/src/decode/index.ts +7 -4
  68. package/src/decode/message.ts +54 -37
  69. package/src/decode/other.ts +116 -44
  70. package/src/decode/positioned.ts +159 -90
  71. package/src/decode/reports.ts +47 -4
  72. package/src/decoder.ts +2 -5
  73. package/src/deviceid.ts +29 -5
  74. package/src/encode/common.ts +34 -4
  75. package/src/encode/index.ts +57 -20
  76. package/src/encode/other.ts +39 -13
  77. package/src/encode/position.ts +261 -119
  78. package/src/header.ts +9 -2
  79. package/src/index.ts +1 -0
  80. package/src/neutral.ts +24 -3
  81. package/src/types.ts +20 -5
@@ -1,6 +1,7 @@
1
1
  // The information field decoder: picks the format by the data type identifier.
2
2
  import { binaryToBytes, bytesToBinary } from '../bytes.js';
3
- import { findQConstruct, parseHeaderText } from '../header.js';
3
+ import { identifyDevice } from '../deviceid.js';
4
+ import { parseHeaderText } from '../header.js';
4
5
  import { DecodeContext, Rejected } from './context.js';
5
6
  import { decodeMessage } from './message.js';
6
7
  import { decodeAgrelo, decodeCapabilities, decodeDollar, decodeMaidenhead, decodeQuery, decodeRawWeather, decodeStatus, decodeTelemetry, decodeTest, decodeUserDefined, } from './other.js';
@@ -98,7 +99,7 @@ function decodeThirdParty(ctx, s, options) {
98
99
  const headerDiags = [];
99
100
  let header;
100
101
  try {
101
- header = parseHeaderText(body.slice(0, colon), options, headerDiags);
102
+ header = parseHeaderText(body.slice(0, colon), options, headerDiags, true);
102
103
  }
103
104
  catch {
104
105
  return ctx.fail('invalid-third-party');
@@ -113,9 +114,11 @@ function decodeThirdParty(ctx, s, options) {
113
114
  data: inner.data,
114
115
  diagnostics: [...headerDiags, ...inner.diagnostics],
115
116
  };
116
- const q = findQConstruct(header.path);
117
- if (q)
118
- packet.qConstruct = q;
117
+ // The inner packet has its device too, from its own destination (vectors rulings, A2).
118
+ const device = identifyDevice(inner.data, header.destination);
119
+ if (device)
120
+ packet.device = device;
121
+ // A q-construct is read only in the outer header: the third-party path is kept as sent.
119
122
  return { type: 'third-party', packet };
120
123
  }
121
124
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decode/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decode/index.ts"],"names":[],"mappings":"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"}
@@ -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;AAkClD,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAqErE"}
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"}
@@ -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 ACK_RE = /^(ack|rej)([A-Za-z0-9]{1,5})(?:\}([A-Za-z0-9]{0,5}))?(\{.*)?$/;
7
- const COEFFICIENT_RE = /^[+-]?(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
8
- /** Splits `text{id}ack` into its parts; reports a brace that does not start an ID. */
9
- function splitMessageId(ctx, text) {
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
- ctx.tolerate('brace-in-message-text');
16
- return { text };
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
- ctx.tolerate('brace-in-message-text');
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
- if (s[1] === ':')
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(ctx, body);
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(ctx, body);
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
- const meta = telemetryMetadata(ctx, addressee, split.text, split.messageId);
90
- if (meta)
91
- return meta;
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
- if (rest.includes('{')) {
133
- ctx.info('invalid-query');
134
- return undefined;
135
- }
136
- const target = rest.trim();
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; `binary` is the text's bytes, decoded once it is valid. */
145
- function telemetryMetadata(ctx, addressee, binary, messageId) {
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].trim() === '')
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
- const t = item.trim();
172
- if (!COEFFICIENT_RE.test(t))
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":"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"}
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/decode/message.ts"],"names":[],"mappings":"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"}
@@ -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
- /** Verifies an NMEA sentence's checksum; `undefined` when it has none. */
12
- export declare function nmeaChecksumOk(sentence: string): boolean | undefined;
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,CAoCxE;AAID,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,eAAe,CA0D9E;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAWhE;AAED,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,CAe9E;AAiCD,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAMpE;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,CAsDrF;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,CAIpE;AAED,wCAAwC;AACxC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAWhF"}
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"}
@@ -42,7 +42,8 @@ export function decodeStatus(ctx, s) {
42
42
  }
43
43
  }
44
44
  }
45
- const beam = /\^([0-9A-Z])([0-9:;<=>?@A-K])$/.exec(body);
45
+ // The ERP codes run 1-9, : to @, then A-K; there is no 0 (APRS12c ch. 16).
46
+ const beam = /\^([0-9A-Z])([1-9:;<=>?@A-K])$/.exec(body);
46
47
  if (beam) {
47
48
  out.beam = { headingCode: beam[1], powerCode: beam[2] };
48
49
  body = body.slice(0, beam.index);
@@ -123,6 +124,9 @@ export function decodeTelemetry(ctx, s) {
123
124
  out.comment = ctx.text(comment);
124
125
  return out;
125
126
  }
127
+ const FOOTPRINT_NUMBER = '[0-9]+\\.?[0-9]*|\\.[0-9]+';
128
+ const FOOTPRINT_VALUE = `( ?(?:${FOOTPRINT_NUMBER})|-(?:${FOOTPRINT_NUMBER}))`;
129
+ const FOOTPRINT_RE = new RegExp(`^${FOOTPRINT_VALUE},${FOOTPRINT_VALUE},([0-9]{4})$`);
126
130
  /** `?`: a general query. */
127
131
  export function decodeQuery(ctx, s) {
128
132
  const m = /^\?([A-Z]+)\?(.*)$/s.exec(s);
@@ -131,27 +135,51 @@ export function decodeQuery(ctx, s) {
131
135
  const out = { type: 'query', queryType: m[1] };
132
136
  const rest = m[2];
133
137
  if (rest.length > 0) {
134
- const f = /^ ?(-?[0-9]+(?:\.[0-9]*)?),(-?[0-9]+(?:\.[0-9]*)?),([0-9]{4})$/.exec(rest);
138
+ // Decimal degrees, each a number as a telemetry value is (`-.1715`), a positive one with or
139
+ // without a leading space, and a 4-digit radius.
140
+ const f = FOOTPRINT_RE.exec(rest);
135
141
  if (!f)
136
142
  ctx.fail('invalid-general-query');
137
- out.footprint = { latitude: Number(f[1]), longitude: Number(f[2]), radiusMiles: Number(f[3]) };
143
+ const latitude = Number(f[1]);
144
+ const longitude = Number(f[2]);
145
+ // A footprint is a real place (vectors interpretations.md).
146
+ if (Math.abs(latitude) > 90 || Math.abs(longitude) > 180)
147
+ ctx.fail('invalid-general-query');
148
+ out.footprint = { latitude, longitude, radiusMiles: Number(f[3]), latitudeText: f[1], longitudeText: f[2] };
138
149
  }
139
150
  return out;
140
151
  }
152
+ /** Drops U+0020 spaces, and no other character, from both ends. */
153
+ function trimSpaces(text) {
154
+ let a = 0;
155
+ let b = text.length;
156
+ while (a < b && text[a] === ' ')
157
+ a++;
158
+ while (b > a && text[b - 1] === ' ')
159
+ b--;
160
+ return text.slice(a, b);
161
+ }
162
+ /** A control character: below U+0020, or U+007F. */
163
+ const CONTROL_RE = /[\x00-\x1f\x7f]/;
141
164
  /** `<`: station capabilities. */
142
165
  export function decodeCapabilities(ctx, s) {
143
166
  const text = ctx.text(s.slice(1));
144
167
  const capabilities = [];
145
168
  let freeText = false;
146
169
  for (const raw of text.split(',')) {
147
- const item = raw.trim();
170
+ // Spaces around an item, a token or a value are padding; nothing else is (vectors
171
+ // interpretations.md, "Station capabilities: items, tokens and values").
172
+ const item = trimSpaces(raw);
148
173
  if (item.length === 0)
149
174
  continue; // empty items are skipped
150
175
  const eq = item.indexOf('=');
151
- const token = eq < 0 ? item : item.slice(0, eq);
152
- if (/\s/.test(token) || token.length === 0)
176
+ const token = eq < 0 ? item : trimSpaces(item.slice(0, eq));
177
+ const value = eq < 0 ? undefined : trimSpaces(item.slice(eq + 1));
178
+ if (token.length === 0 || token.includes(' ') || CONTROL_RE.test(token))
179
+ freeText = true;
180
+ if (value !== undefined && CONTROL_RE.test(value))
153
181
  freeText = true;
154
- capabilities.push(eq < 0 ? [item] : [token, item.slice(eq + 1)]);
182
+ capabilities.push(value === undefined ? [token] : [token, value]);
155
183
  }
156
184
  if (capabilities.length === 0)
157
185
  ctx.fail('invalid-capabilities');
@@ -159,79 +187,112 @@ export function decodeCapabilities(ctx, s) {
159
187
  ctx.tolerate('free-text-capabilities');
160
188
  return { type: 'capabilities', capabilities };
161
189
  }
162
- function nmeaDegrees(value, hemisphere, width) {
190
+ /** A coordinate: at least three digits before an optional `.` and fraction, the last two minutes. */
191
+ function nmeaDegrees(value, hemisphere, limit) {
163
192
  if (value === undefined || hemisphere === undefined)
164
193
  return undefined;
165
- if (!/^[0-9]+(?:\.[0-9]*)?$/.test(value))
166
- return undefined;
167
- const dot = value.indexOf('.');
168
- const intPart = dot < 0 ? value : value.slice(0, dot);
169
- if (intPart.length < 3)
194
+ const m = /^([0-9]+)([0-9]{2}(?:\.[0-9]*)?)$/.exec(value);
195
+ if (!m)
170
196
  return undefined;
171
- const degrees = Number(intPart.slice(0, intPart.length - 2));
172
- const minutes = Number(value.slice(intPart.length - 2));
197
+ const degrees = Number(m[1]);
198
+ const minutes = Number(m[2]);
173
199
  if (minutes >= 60)
174
200
  return undefined;
175
201
  const v = degrees + minutes / 60;
176
- if (v > width)
202
+ if (v > limit)
177
203
  return undefined;
178
- if (hemisphere === 'S' || hemisphere === 'W')
204
+ if (hemisphere === (limit === 90 ? 'S' : 'W'))
179
205
  return v === 0 ? 0 : -v;
180
- if (hemisphere === 'N' || hemisphere === 'E')
206
+ if (hemisphere === (limit === 90 ? 'N' : 'E'))
181
207
  return v;
182
208
  return undefined;
183
209
  }
210
+ /** `hhmmss` with an optional fraction, as `HH:MM:SS` and the fraction as sent, less trailing zeros. */
184
211
  function nmeaTime(value) {
185
212
  if (value === undefined)
186
213
  return undefined;
187
214
  const m = /^([0-9]{2})([0-9]{2})([0-9]{2})(?:\.([0-9]*))?$/.exec(value);
188
215
  if (!m)
189
216
  return undefined;
217
+ if (Number(m[1]) > 23 || Number(m[2]) > 59 || Number(m[3]) > 59)
218
+ return undefined;
190
219
  let t = `${m[1]}:${m[2]}:${m[3]}`;
191
220
  const fraction = (m[4] ?? '').replace(/0+$/, '');
192
221
  if (fraction.length > 0)
193
222
  t += `.${fraction}`;
194
223
  return t;
195
224
  }
225
+ /**
226
+ * An optional `-`, then digits with an optional `.` and fraction. NMEA 0183 makes leading zeros
227
+ * optional, so a number may start with its decimal point (`.30`).
228
+ */
196
229
  function nmeaNumber(value) {
197
- if (value === undefined || !/^-?(?:[0-9]+\.?[0-9]*|\.[0-9]+)$/.test(value))
230
+ if (value === undefined || !/^-?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)$/.test(value))
198
231
  return undefined;
199
232
  return Number(value);
200
233
  }
201
- /** Verifies an NMEA sentence's checksum; `undefined` when it has none. */
202
- export function nmeaChecksumOk(sentence) {
203
- const m = /\*([0-9A-Fa-f]{2})$/.exec(sentence);
204
- if (!m)
234
+ const NMEA_ADDRESS_RE = /^(?:[A-Z0-9]{5}|P[A-Z0-9]{3,})$/;
235
+ /**
236
+ * Takes the text after `$` apart as an NMEA 0183 sentence (vectors interpretations.md, "What $
237
+ * text is an NMEA sentence"): printable ASCII, an address field of five upper-case letters or
238
+ * digits (or `P` and three or more), at least one field, no `$`, and no `*` but the one that
239
+ * starts a checksum of two hex digits, which ends the sentence. `undefined` when it is not one.
240
+ */
241
+ export function splitNmea(text) {
242
+ const star = text.indexOf('*');
243
+ const hasChecksum = star >= 0;
244
+ if (hasChecksum && !/^[0-9A-Fa-f]{2}$/.test(text.slice(star + 1, star + 3)))
245
+ return undefined;
246
+ const body = hasChecksum ? text.slice(0, star) : text;
247
+ if (!/^[\x20-\x7e]*$/.test(body) || body.includes('$'))
248
+ return undefined;
249
+ const fields = body.split(',');
250
+ if (fields.length < 2 || !NMEA_ADDRESS_RE.test(fields[0]))
205
251
  return undefined;
206
- let x = 0;
207
- for (let k = 0; k < m.index; k++)
208
- x ^= sentence.charCodeAt(k);
209
- return x === parseInt(m[1], 16);
252
+ const end = hasChecksum ? star + 3 : text.length;
253
+ let checksumOk = true;
254
+ if (hasChecksum) {
255
+ let x = 0;
256
+ for (let k = 0; k < body.length; k++)
257
+ x ^= body.charCodeAt(k);
258
+ checksumOk = x === parseInt(text.slice(star + 1, star + 3), 16);
259
+ }
260
+ return { sentence: text.slice(0, end), fields, hasChecksum, checksumOk, rest: text.slice(end) };
210
261
  }
211
262
  /** `$`: raw NMEA, or Ultimeter raw weather (`$ULTW`). */
212
263
  export function decodeDollar(ctx, s) {
213
264
  if (s.startsWith('$ULTW'))
214
265
  return decodeRawWeather(ctx, s.slice(5), 'ultimeter-packet');
215
266
  ctx.info('obsolete-format');
216
- const sentence = s.slice(1);
217
- if (!/^[A-Z]{5},[\x20-\x7e]*$/.test(sentence))
218
- ctx.fail('invalid-nmea');
219
- const checksum = nmeaChecksumOk(sentence);
220
- if (checksum === false)
267
+ // The structure is checked before the checksum.
268
+ const parts = splitNmea(s.slice(1));
269
+ if (!parts)
270
+ return ctx.fail('invalid-nmea');
271
+ if (!parts.checksumOk)
221
272
  ctx.fail('nmea-checksum-mismatch');
222
- const body = checksum === undefined ? sentence : sentence.slice(0, sentence.length - 3);
223
- const f = body.split(',');
224
- const out = { type: 'nmea', sentence };
225
- if (checksum !== undefined)
273
+ const f = parts.fields;
274
+ const out = { type: 'nmea', sentence: parts.sentence };
275
+ if (parts.hasChecksum)
226
276
  out.hasChecksum = true;
227
277
  const set = (key, value) => {
228
278
  if (value !== undefined)
229
279
  out[key] = value;
230
280
  };
231
- switch (f[0].slice(2)) {
281
+ // A position needs both coordinates.
282
+ const position = (lat, lon) => {
283
+ const latitude = nmeaDegrees(f[lat], f[lat + 1], 90);
284
+ const longitude = nmeaDegrees(f[lon], f[lon + 1], 180);
285
+ if (latitude === undefined || longitude === undefined)
286
+ return;
287
+ out.latitude = latitude;
288
+ out.longitude = longitude;
289
+ };
290
+ // Only an approved address (five characters, not P) has a sentence formatter.
291
+ const address = f[0];
292
+ const formatter = address.length === 5 && address[0] !== 'P' ? address.slice(2) : '';
293
+ switch (formatter) {
232
294
  case 'GGA': {
233
- set('latitude', nmeaDegrees(f[2], f[3], 90));
234
- set('longitude', nmeaDegrees(f[4], f[5], 180));
295
+ position(2, 4);
235
296
  if (f[6] !== undefined && /^[0-9]$/.test(f[6]))
236
297
  out.fix = f[6] === '0' ? 'invalid' : 'valid';
237
298
  set('altitudeM', nmeaNumber(f[9]));
@@ -239,8 +300,7 @@ export function decodeDollar(ctx, s) {
239
300
  break;
240
301
  }
241
302
  case 'GLL': {
242
- set('latitude', nmeaDegrees(f[1], f[2], 90));
243
- set('longitude', nmeaDegrees(f[3], f[4], 180));
303
+ position(1, 3);
244
304
  set('time', nmeaTime(f[5]));
245
305
  if (f[6] === 'A')
246
306
  out.fix = 'valid';
@@ -254,8 +314,7 @@ export function decodeDollar(ctx, s) {
254
314
  out.fix = 'valid';
255
315
  else if (f[2] === 'V')
256
316
  out.fix = 'invalid';
257
- set('latitude', nmeaDegrees(f[3], f[4], 90));
258
- set('longitude', nmeaDegrees(f[5], f[6], 180));
317
+ position(3, 5);
259
318
  set('speedKnots', nmeaNumber(f[7]));
260
319
  set('courseDegrees', nmeaNumber(f[8]));
261
320
  break;
@@ -266,13 +325,15 @@ export function decodeDollar(ctx, s) {
266
325
  break;
267
326
  }
268
327
  case 'WPL': {
269
- set('latitude', nmeaDegrees(f[1], f[2], 90));
270
- set('longitude', nmeaDegrees(f[3], f[4], 180));
328
+ position(1, 3);
271
329
  if (f[5] !== undefined && f[5].length > 0)
272
330
  out.waypoint = f[5];
273
331
  break;
274
332
  }
275
333
  }
334
+ // Text after the checksum is a comment, kept as sent.
335
+ if (parts.rest.length > 0)
336
+ out.comment = ctx.text(parts.rest);
276
337
  return out;
277
338
  }
278
339
  /** Raw weather station data, kept as text. */
@@ -303,9 +364,10 @@ export function decodeTest(ctx, s) {
303
364
  }
304
365
  /** `%`: an Agrelo DFJr / MicroFinder report. */
305
366
  export function decodeAgrelo(ctx, s) {
306
- const m = /^%([0-9]{3})\/([0-9])/.exec(s);
307
- if (!m)
308
- ctx.fail('invalid-agrelo-df');
367
+ // Exactly %, a bearing of 000 to 360, / and a quality digit (vectors interpretations.md).
368
+ const m = /^%([0-9]{3})\/([0-9])$/.exec(s);
369
+ if (!m || Number(m[1]) > 360)
370
+ return ctx.fail('invalid-agrelo-df');
309
371
  return { type: 'agrelo-df', bearingDegrees: Number(m[1]), quality: Number(m[2]) };
310
372
  }
311
373
  /** `[`: a Maidenhead locator beacon. */