@blockcast/mmt-base 0.1.0 → 0.3.0-main.36c5f6abe867
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/README.md +16 -2
- package/dist/fec-block-profile.d.ts +55 -0
- package/dist/fec-block-profile.d.ts.map +1 -0
- package/dist/fec-block-profile.js +128 -0
- package/dist/fec-block-profile.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/mmtp.d.ts +77 -56
- package/dist/mmtp.d.ts.map +1 -1
- package/dist/mmtp.js +260 -216
- package/dist/mmtp.js.map +1 -1
- package/dist/net-constants.d.ts +18 -0
- package/dist/net-constants.d.ts.map +1 -0
- package/dist/net-constants.js +18 -0
- package/dist/net-constants.js.map +1 -0
- package/dist/ntp-short.d.ts +47 -0
- package/dist/ntp-short.d.ts.map +1 -0
- package/dist/ntp-short.js +54 -0
- package/dist/ntp-short.js.map +1 -0
- package/dist/serial-number.d.ts +57 -0
- package/dist/serial-number.d.ts.map +1 -0
- package/dist/serial-number.js +98 -0
- package/dist/serial-number.js.map +1 -0
- package/dist/signalling.d.ts +312 -0
- package/dist/signalling.d.ts.map +1 -0
- package/dist/signalling.js +637 -0
- package/dist/signalling.js.map +1 -0
- package/package.json +9 -4
- package/src/fec-block-profile.ts +145 -0
- package/src/index.ts +5 -0
- package/src/mmtp.ts +334 -188
- package/src/net-constants.ts +17 -0
- package/src/ntp-short.ts +67 -0
- package/src/serial-number.ts +107 -0
- package/src/signalling.ts +862 -0
- package/src/alfec.test.ts +0 -176
- package/src/mmtp.test.ts +0 -769
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AMT well-known UDP port (RFC 7450 §4).
|
|
3
|
+
*
|
|
4
|
+
* The single definition for the whole repo. It lives here, in the one package
|
|
5
|
+
* both `@blockcast/mmt-transport` and `@blockcast/mmt-container` already
|
|
6
|
+
* depend on, because the two apply it on opposite sides of a boundary that
|
|
7
|
+
* does not otherwise share code:
|
|
8
|
+
*
|
|
9
|
+
* - container resolves it where `networkSource` semantics live, so a catalog
|
|
10
|
+
* relay that names no port is reachable instead of handing a join a
|
|
11
|
+
* portless relay that fails.
|
|
12
|
+
* - transport applies it when reading a catalog, dialling a gateway, and
|
|
13
|
+
* answering DRIAD — but deliberately not at every boundary. Which call
|
|
14
|
+
* sites do and do not take the default is transport's business; the
|
|
15
|
+
* reasoning lives beside those call sites, not here.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_AMT_RELAY_PORT = 2268;
|
|
18
|
+
//# sourceMappingURL=net-constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"net-constants.d.ts","sourceRoot":"","sources":["../src/net-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AMT well-known UDP port (RFC 7450 §4).
|
|
3
|
+
*
|
|
4
|
+
* The single definition for the whole repo. It lives here, in the one package
|
|
5
|
+
* both `@blockcast/mmt-transport` and `@blockcast/mmt-container` already
|
|
6
|
+
* depend on, because the two apply it on opposite sides of a boundary that
|
|
7
|
+
* does not otherwise share code:
|
|
8
|
+
*
|
|
9
|
+
* - container resolves it where `networkSource` semantics live, so a catalog
|
|
10
|
+
* relay that names no port is reachable instead of handing a join a
|
|
11
|
+
* portless relay that fails.
|
|
12
|
+
* - transport applies it when reading a catalog, dialling a gateway, and
|
|
13
|
+
* answering DRIAD — but deliberately not at every boundary. Which call
|
|
14
|
+
* sites do and do not take the default is transport's business; the
|
|
15
|
+
* reasoning lives beside those call sites, not here.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_AMT_RELAY_PORT = 2268;
|
|
18
|
+
//# sourceMappingURL=net-constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"net-constants.js","sourceRoot":"","sources":["../src/net-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NTP short format (RFC 5905 §6): an unsigned 32-bit, 16.16 fixed-point count
|
|
3
|
+
* of seconds. The MMTP header `timestamp` field (ISO/IEC 23008-1 §9.2.2)
|
|
4
|
+
* carries each packet's UTC sending instant in this format, so the value wraps
|
|
5
|
+
* to 0 every 2^16 s (~18.2 h).
|
|
6
|
+
*
|
|
7
|
+
* Plain numeric order on these values breaks at every wrap: a retained
|
|
8
|
+
* `Math.max` stays at the pre-wrap value and every later instant compares as
|
|
9
|
+
* older. Order send times only with {@link compareNtpShort}, which applies
|
|
10
|
+
* RFC 1982 serial-number arithmetic over the field's width.
|
|
11
|
+
*/
|
|
12
|
+
/** Width in bits of the MMTP `timestamp` field (NTP short). */
|
|
13
|
+
export declare const NTP_SHORT_BITS = 32;
|
|
14
|
+
/** Number of distinct NTP-short values; the field wraps to 0 here. */
|
|
15
|
+
export declare const NTP_SHORT_MODULUS: number;
|
|
16
|
+
/**
|
|
17
|
+
* RFC 1982 §3.2's `2^(SERIAL_BITS - 1)`. Two values whose forward distance is
|
|
18
|
+
* below this are ordered; exactly this far apart they are not ordered at all.
|
|
19
|
+
* Two instants must be less than this far apart (2^15 s, ~9.1 h of send time)
|
|
20
|
+
* for the comparison to give their true order.
|
|
21
|
+
*/
|
|
22
|
+
export declare const NTP_SHORT_HALF_RANGE: number;
|
|
23
|
+
/**
|
|
24
|
+
* Serial order of one NTP-short value relative to another.
|
|
25
|
+
*
|
|
26
|
+
* `'unordered'` is RFC 1982's undefined case: the values are exactly
|
|
27
|
+
* {@link NTP_SHORT_HALF_RANGE} apart, so neither precedes the other. It is
|
|
28
|
+
* never folded into `'before'` or `'after'`; each caller decides what an
|
|
29
|
+
* unorderable pair means for it.
|
|
30
|
+
*/
|
|
31
|
+
export type NtpShortOrder = 'before' | 'equal' | 'after' | 'unordered';
|
|
32
|
+
/** True when `value` is an NTP-short value: an integer in [0, NTP_SHORT_MODULUS). */
|
|
33
|
+
export declare function isNtpShort(value: number): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* RFC 1982 serial comparison of NTP-short `a` against `b`: `'after'` when `a`
|
|
36
|
+
* is the later instant, `'before'` when it is the earlier one.
|
|
37
|
+
*
|
|
38
|
+
* The answer is the true order only while the two instants are less than
|
|
39
|
+
* {@link NTP_SHORT_HALF_RANGE} apart. Past that a 32-bit field cannot tell
|
|
40
|
+
* later from earlier, and the result names whichever direction is nearer.
|
|
41
|
+
* This is not a total order (it is not transitive across the whole space), so
|
|
42
|
+
* it must never be used to sort.
|
|
43
|
+
*
|
|
44
|
+
* @throws {RangeError} if either operand is not an NTP-short value
|
|
45
|
+
*/
|
|
46
|
+
export declare function compareNtpShort(a: number, b: number): NtpShortOrder;
|
|
47
|
+
//# sourceMappingURL=ntp-short.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ntp-short.d.ts","sourceRoot":"","sources":["../src/ntp-short.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,+DAA+D;AAC/D,eAAO,MAAM,cAAc,KAAK,CAAA;AAEhC,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,QAAsB,CAAA;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,QAA4B,CAAA;AAE7D;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,CAAA;AAEtE,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,aAAa,CAanE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NTP short format (RFC 5905 §6): an unsigned 32-bit, 16.16 fixed-point count
|
|
3
|
+
* of seconds. The MMTP header `timestamp` field (ISO/IEC 23008-1 §9.2.2)
|
|
4
|
+
* carries each packet's UTC sending instant in this format, so the value wraps
|
|
5
|
+
* to 0 every 2^16 s (~18.2 h).
|
|
6
|
+
*
|
|
7
|
+
* Plain numeric order on these values breaks at every wrap: a retained
|
|
8
|
+
* `Math.max` stays at the pre-wrap value and every later instant compares as
|
|
9
|
+
* older. Order send times only with {@link compareNtpShort}, which applies
|
|
10
|
+
* RFC 1982 serial-number arithmetic over the field's width.
|
|
11
|
+
*/
|
|
12
|
+
/** Width in bits of the MMTP `timestamp` field (NTP short). */
|
|
13
|
+
export const NTP_SHORT_BITS = 32;
|
|
14
|
+
/** Number of distinct NTP-short values; the field wraps to 0 here. */
|
|
15
|
+
export const NTP_SHORT_MODULUS = 2 ** NTP_SHORT_BITS;
|
|
16
|
+
/**
|
|
17
|
+
* RFC 1982 §3.2's `2^(SERIAL_BITS - 1)`. Two values whose forward distance is
|
|
18
|
+
* below this are ordered; exactly this far apart they are not ordered at all.
|
|
19
|
+
* Two instants must be less than this far apart (2^15 s, ~9.1 h of send time)
|
|
20
|
+
* for the comparison to give their true order.
|
|
21
|
+
*/
|
|
22
|
+
export const NTP_SHORT_HALF_RANGE = 2 ** (NTP_SHORT_BITS - 1);
|
|
23
|
+
/** True when `value` is an NTP-short value: an integer in [0, NTP_SHORT_MODULUS). */
|
|
24
|
+
export function isNtpShort(value) {
|
|
25
|
+
return Number.isInteger(value) && value >= 0 && value < NTP_SHORT_MODULUS;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* RFC 1982 serial comparison of NTP-short `a` against `b`: `'after'` when `a`
|
|
29
|
+
* is the later instant, `'before'` when it is the earlier one.
|
|
30
|
+
*
|
|
31
|
+
* The answer is the true order only while the two instants are less than
|
|
32
|
+
* {@link NTP_SHORT_HALF_RANGE} apart. Past that a 32-bit field cannot tell
|
|
33
|
+
* later from earlier, and the result names whichever direction is nearer.
|
|
34
|
+
* This is not a total order (it is not transitive across the whole space), so
|
|
35
|
+
* it must never be used to sort.
|
|
36
|
+
*
|
|
37
|
+
* @throws {RangeError} if either operand is not an NTP-short value
|
|
38
|
+
*/
|
|
39
|
+
export function compareNtpShort(a, b) {
|
|
40
|
+
if (!isNtpShort(a) || !isNtpShort(b)) {
|
|
41
|
+
throw new RangeError(`NTP-short values must be integers in [0, 2^${NTP_SHORT_BITS}), got ${String(a)} and ${String(b)}`);
|
|
42
|
+
}
|
|
43
|
+
if (a === b)
|
|
44
|
+
return 'equal';
|
|
45
|
+
// Forward distance from b to a, reduced into [1, NTP_SHORT_MODULUS). Both
|
|
46
|
+
// operands are below 2^32, so every step is exact in a double.
|
|
47
|
+
const forward = (a - b + NTP_SHORT_MODULUS) % NTP_SHORT_MODULUS;
|
|
48
|
+
if (forward < NTP_SHORT_HALF_RANGE)
|
|
49
|
+
return 'after';
|
|
50
|
+
if (forward > NTP_SHORT_HALF_RANGE)
|
|
51
|
+
return 'before';
|
|
52
|
+
return 'unordered';
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=ntp-short.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ntp-short.js","sourceRoot":"","sources":["../src/ntp-short.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAA;AAEhC,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAI,cAAc,CAAA;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,CAAA;AAY7D,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,iBAAiB,CAAA;AAC3E,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,UAAU,CAClB,8CAA8C,cAAc,UAAU,MAAM,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,CAAC,EAAE,CACnG,CAAA;IACH,CAAC;IACD,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAA;IAC3B,0EAA0E;IAC1E,+DAA+D;IAC/D,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,iBAAiB,CAAA;IAC/D,IAAI,OAAO,GAAG,oBAAoB;QAAE,OAAO,OAAO,CAAA;IAClD,IAAI,OAAO,GAAG,oBAAoB;QAAE,OAAO,QAAQ,CAAA;IACnD,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 1982 serial-number arithmetic for the 32-bit MMTP AL-FEC symbol
|
|
3
|
+
* counters (ISO/IEC 23008-1:2023 C.5.2 SS_ID, C.5.3 SS_Start).
|
|
4
|
+
*
|
|
5
|
+
* SS_ID is a 32-bit field, so a stream that runs long enough wraps it to 0.
|
|
6
|
+
* Ordering two SS_IDs (or two blocks by their first SS_ID) with `<` reads
|
|
7
|
+
* every post-wrap value as older than every pre-wrap one. Serial order
|
|
8
|
+
* agrees with `<` whenever the two values are less than 2^31 apart, so for
|
|
9
|
+
* every stream that has not reached the wrap the result is unchanged; only
|
|
10
|
+
* the order across the wrap point differs (BLO-35597 iso:5).
|
|
11
|
+
*/
|
|
12
|
+
/** 2^SERIAL_BITS for SERIAL_BITS = 32. */
|
|
13
|
+
export declare const SERIAL32_SPAN = 4294967296;
|
|
14
|
+
/** RFC 1982 §3.2's 2^(SERIAL_BITS - 1). */
|
|
15
|
+
export declare const SERIAL32_HALF = 2147483648;
|
|
16
|
+
/**
|
|
17
|
+
* RFC 1982 §3.1 addition, extended to negative `n` for the matching
|
|
18
|
+
* subtraction: `(s + n) mod 2^32`. `n` must lie in (-2^31, 2^31).
|
|
19
|
+
*/
|
|
20
|
+
export declare function serial32Add(s: number, n: number): number;
|
|
21
|
+
/** Forward distance from `from` to `to`: `(to - from) mod 2^32`. */
|
|
22
|
+
export declare function serial32Distance(from: number, to: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* RFC 1982 §3.2: `a` precedes `b`. Values exactly 2^31 apart are unordered
|
|
25
|
+
* (neither precedes the other).
|
|
26
|
+
*/
|
|
27
|
+
export declare function serial32Precedes(a: number, b: number): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* First SS_ID of block `sbn` under the K-stride numbering every current
|
|
30
|
+
* sender uses (`SS_ID = SBN * K + ESI`, C.5.2), reduced mod 2^32.
|
|
31
|
+
*/
|
|
32
|
+
export declare function kStrideBlockStart(sbn: number, k: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Whether block `a` precedes block `b`, ordering the blocks by their first
|
|
35
|
+
* SS_ID in serial arithmetic. Identical to `a < b` for any two blocks of a
|
|
36
|
+
* stream that has not wrapped SS_ID.
|
|
37
|
+
*/
|
|
38
|
+
export declare function kStrideBlockPrecedes(a: number, b: number, k: number): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* How many blocks `a` lies behind `b`: 0 when `a` does not precede `b`,
|
|
41
|
+
* otherwise `ceil(distance / K)` over the SS_ID distance between their first
|
|
42
|
+
* symbols. Without a wrap that is exactly `b - a`; across the wrap the one
|
|
43
|
+
* short pre-wrap block (2^32 mod K symbols) still counts as one block.
|
|
44
|
+
*/
|
|
45
|
+
export declare function kStrideBlocksBehind(a: number, b: number, k: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Whether `sbn` and `k` describe a block of the K-stride numbering:
|
|
48
|
+
* `sbn` a uint32, `k` an integer in 1..2^31-1.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isKStrideBlock(sbn: number, k: number): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* The block after `sbn`: `sbn + 1`, or 0 once `(sbn + 1) * K` reaches 2^32
|
|
53
|
+
* and the next SS_ID wraps (C.5.2). There are `ceil(2^32 / K)` blocks per
|
|
54
|
+
* wrap, the last of them short when K does not divide 2^32.
|
|
55
|
+
*/
|
|
56
|
+
export declare function kStrideNextBlock(sbn: number, k: number): number;
|
|
57
|
+
//# sourceMappingURL=serial-number.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serial-number.d.ts","sourceRoot":"","sources":["../src/serial-number.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0CAA0C;AAC1C,eAAO,MAAM,aAAa,aAAgB,CAAA;AAE1C,2CAA2C;AAC3C,eAAO,MAAM,aAAa,aAAc,CAAA;AAQxC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUhE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAK3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAI/D"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 1982 serial-number arithmetic for the 32-bit MMTP AL-FEC symbol
|
|
3
|
+
* counters (ISO/IEC 23008-1:2023 C.5.2 SS_ID, C.5.3 SS_Start).
|
|
4
|
+
*
|
|
5
|
+
* SS_ID is a 32-bit field, so a stream that runs long enough wraps it to 0.
|
|
6
|
+
* Ordering two SS_IDs (or two blocks by their first SS_ID) with `<` reads
|
|
7
|
+
* every post-wrap value as older than every pre-wrap one. Serial order
|
|
8
|
+
* agrees with `<` whenever the two values are less than 2^31 apart, so for
|
|
9
|
+
* every stream that has not reached the wrap the result is unchanged; only
|
|
10
|
+
* the order across the wrap point differs (BLO-35597 iso:5).
|
|
11
|
+
*/
|
|
12
|
+
/** 2^SERIAL_BITS for SERIAL_BITS = 32. */
|
|
13
|
+
export const SERIAL32_SPAN = 0x1_0000_0000;
|
|
14
|
+
/** RFC 1982 §3.2's 2^(SERIAL_BITS - 1). */
|
|
15
|
+
export const SERIAL32_HALF = 0x8000_0000;
|
|
16
|
+
function assertUint32(value, name) {
|
|
17
|
+
if (!Number.isInteger(value) || value < 0 || value >= SERIAL32_SPAN) {
|
|
18
|
+
throw new RangeError(`${name} must be a uint32 (got ${value})`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* RFC 1982 §3.1 addition, extended to negative `n` for the matching
|
|
23
|
+
* subtraction: `(s + n) mod 2^32`. `n` must lie in (-2^31, 2^31).
|
|
24
|
+
*/
|
|
25
|
+
export function serial32Add(s, n) {
|
|
26
|
+
assertUint32(s, 's');
|
|
27
|
+
if (!Number.isInteger(n) || n <= -SERIAL32_HALF || n >= SERIAL32_HALF) {
|
|
28
|
+
throw new RangeError(`serial addend must lie in (-2^31, 2^31) (got ${n})`);
|
|
29
|
+
}
|
|
30
|
+
return (s + n + SERIAL32_SPAN) % SERIAL32_SPAN;
|
|
31
|
+
}
|
|
32
|
+
/** Forward distance from `from` to `to`: `(to - from) mod 2^32`. */
|
|
33
|
+
export function serial32Distance(from, to) {
|
|
34
|
+
return (to - from) >>> 0;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* RFC 1982 §3.2: `a` precedes `b`. Values exactly 2^31 apart are unordered
|
|
38
|
+
* (neither precedes the other).
|
|
39
|
+
*/
|
|
40
|
+
export function serial32Precedes(a, b) {
|
|
41
|
+
const distance = serial32Distance(a, b);
|
|
42
|
+
return distance !== 0 && distance < SERIAL32_HALF;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* First SS_ID of block `sbn` under the K-stride numbering every current
|
|
46
|
+
* sender uses (`SS_ID = SBN * K + ESI`, C.5.2), reduced mod 2^32.
|
|
47
|
+
*/
|
|
48
|
+
export function kStrideBlockStart(sbn, k) {
|
|
49
|
+
assertUint32(sbn, 'sbn');
|
|
50
|
+
if (!Number.isInteger(k) || k < 1 || k >= SERIAL32_HALF) {
|
|
51
|
+
throw new RangeError(`k must be a positive integer below 2^31 (got ${k})`);
|
|
52
|
+
}
|
|
53
|
+
// sbn < 2^32 and k < 2^31 keep the product below 2^63, but a double is
|
|
54
|
+
// exact only to 2^53; split the product so every step is exact.
|
|
55
|
+
const high = Math.floor(sbn / 0x1_0000); // < 2^16
|
|
56
|
+
const low = sbn % 0x1_0000; // < 2^16
|
|
57
|
+
return (((high * k) % SERIAL32_SPAN) * 0x1_0000 + low * k) % SERIAL32_SPAN;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether block `a` precedes block `b`, ordering the blocks by their first
|
|
61
|
+
* SS_ID in serial arithmetic. Identical to `a < b` for any two blocks of a
|
|
62
|
+
* stream that has not wrapped SS_ID.
|
|
63
|
+
*/
|
|
64
|
+
export function kStrideBlockPrecedes(a, b, k) {
|
|
65
|
+
return serial32Precedes(kStrideBlockStart(a, k), kStrideBlockStart(b, k));
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* How many blocks `a` lies behind `b`: 0 when `a` does not precede `b`,
|
|
69
|
+
* otherwise `ceil(distance / K)` over the SS_ID distance between their first
|
|
70
|
+
* symbols. Without a wrap that is exactly `b - a`; across the wrap the one
|
|
71
|
+
* short pre-wrap block (2^32 mod K symbols) still counts as one block.
|
|
72
|
+
*/
|
|
73
|
+
export function kStrideBlocksBehind(a, b, k) {
|
|
74
|
+
const from = kStrideBlockStart(a, k);
|
|
75
|
+
const to = kStrideBlockStart(b, k);
|
|
76
|
+
if (!serial32Precedes(from, to))
|
|
77
|
+
return 0;
|
|
78
|
+
return Math.ceil(serial32Distance(from, to) / k);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether `sbn` and `k` describe a block of the K-stride numbering:
|
|
82
|
+
* `sbn` a uint32, `k` an integer in 1..2^31-1.
|
|
83
|
+
*/
|
|
84
|
+
export function isKStrideBlock(sbn, k) {
|
|
85
|
+
return Number.isInteger(sbn) && sbn >= 0 && sbn < SERIAL32_SPAN &&
|
|
86
|
+
Number.isInteger(k) && k >= 1 && k < SERIAL32_HALF;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The block after `sbn`: `sbn + 1`, or 0 once `(sbn + 1) * K` reaches 2^32
|
|
90
|
+
* and the next SS_ID wraps (C.5.2). There are `ceil(2^32 / K)` blocks per
|
|
91
|
+
* wrap, the last of them short when K does not divide 2^32.
|
|
92
|
+
*/
|
|
93
|
+
export function kStrideNextBlock(sbn, k) {
|
|
94
|
+
assertUint32(sbn, 'sbn');
|
|
95
|
+
kStrideBlockStart(sbn, k); // validates k
|
|
96
|
+
return (sbn + 1) * k >= SERIAL32_SPAN ? 0 : sbn + 1;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=serial-number.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serial-number.js","sourceRoot":"","sources":["../src/serial-number.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the signalling payload of an MMTP packet was framed.
|
|
3
|
+
*
|
|
4
|
+
* - `iso-9.3.4.2`: the 2-byte `f_i(2) RES(4) H(1) A(1) | frag_counter(8)`
|
|
5
|
+
* header of ISO/IEC 23008-1:2023 9.3.4.2 precedes the message(s).
|
|
6
|
+
* - `legacy-bare-alfec`: the pre-remediation Blockcast form, where the
|
|
7
|
+
* AL-FEC message starts directly after the MMTP header. It is recognised
|
|
8
|
+
* only by its first two bytes being `0x02 0x03` (message_id 0x0203). That
|
|
9
|
+
* pair is never a valid 9.3.4.2 header for a complete message: f_i=00 with
|
|
10
|
+
* frag_counter=3 claims three further fragments of a message the same
|
|
11
|
+
* header declares complete. The peek is therefore exact, not a heuristic.
|
|
12
|
+
* The legacy branch is deleted once no legacy sender remains (BLO-35597
|
|
13
|
+
* plan, Phase L).
|
|
14
|
+
*/
|
|
15
|
+
export type SignallingPayloadForm = 'iso-9.3.4.2' | 'legacy-bare-alfec';
|
|
16
|
+
export interface SignallingPayload {
|
|
17
|
+
form: SignallingPayloadForm;
|
|
18
|
+
/** Each complete signalling message, starting at its message_id. */
|
|
19
|
+
messages: Uint8Array[];
|
|
20
|
+
}
|
|
21
|
+
/** f_i (Table 19): payload contains one or more complete signalling messages. */
|
|
22
|
+
export declare const SIGNALLING_FRAGMENTATION_COMPLETE = 0;
|
|
23
|
+
/**
|
|
24
|
+
* Split the payload of an MMTP signalling packet into its complete
|
|
25
|
+
* signalling messages.
|
|
26
|
+
*
|
|
27
|
+
* Returns null when the packet is not a well-formed, unprotected (FEC_type 0)
|
|
28
|
+
* signalling packet, or when it carries a fragment (f_i != 00): reassembly
|
|
29
|
+
* across packets is not implemented, and a fragment is not a message.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseSignallingPayload(mmtpPacket: Uint8Array): SignallingPayload | null;
|
|
32
|
+
export declare const PA_MESSAGE_ID = 0;
|
|
33
|
+
export declare const MPI_MESSAGE_ID_FIRST = 1;
|
|
34
|
+
export declare const MPI_MESSAGE_ID_LAST = 16;
|
|
35
|
+
export declare const MPT_MESSAGE_ID_FIRST = 17;
|
|
36
|
+
/** MPT message carrying the complete MP table (Table 101). */
|
|
37
|
+
export declare const MPT_MESSAGE_ID_COMPLETE = 32;
|
|
38
|
+
/**
|
|
39
|
+
* Whether a message's `length` field is 32 bits (Table 20: PA and MPI
|
|
40
|
+
* messages; Table 101: the 0x7000-0x7FFF range "32-bit length message").
|
|
41
|
+
*/
|
|
42
|
+
export declare function signallingMessageHas32BitLength(messageId: number): boolean;
|
|
43
|
+
/** fec_coding_structure values (Table C.8 as replaced by Amd 1:2025). */
|
|
44
|
+
export declare const FEC_CODING_STRUCTURE_NONE = 0;
|
|
45
|
+
export declare const FEC_CODING_STRUCTURE_ONE_STAGE = 1;
|
|
46
|
+
export declare const FEC_CODING_STRUCTURE_TWO_STAGE = 2;
|
|
47
|
+
export declare const FEC_CODING_STRUCTURE_LAYER_AWARE = 3;
|
|
48
|
+
export declare const FEC_CODING_STRUCTURE_ADAPTIVE = 4;
|
|
49
|
+
/** ssbg_mode values (Table C.5). b11 is reserved. */
|
|
50
|
+
export declare const SSBG_MODE_0 = 0;
|
|
51
|
+
export declare const SSBG_MODE_1 = 1;
|
|
52
|
+
export declare const SSBG_MODE_2 = 2;
|
|
53
|
+
export interface AlFecPrivateField {
|
|
54
|
+
privateFlag: 0 | 1;
|
|
55
|
+
data: Uint8Array;
|
|
56
|
+
}
|
|
57
|
+
export interface AlFecRepairFlow {
|
|
58
|
+
/**
|
|
59
|
+
* repair_flow_id (16 bits under Amd 1:2025 for one-stage, two-stage and
|
|
60
|
+
* LA-FEC). Blockcast senders set it to the repair flow's MMTP packet_id.
|
|
61
|
+
*/
|
|
62
|
+
repairFlowId: number;
|
|
63
|
+
/**
|
|
64
|
+
* fec_code_id_for_repair_flow. Under LA-FEC (0011) one value is signalled
|
|
65
|
+
* per FEC flow and is repeated here on every layer.
|
|
66
|
+
*/
|
|
67
|
+
fecCodeId: number;
|
|
68
|
+
/**
|
|
69
|
+
* The private_flag/private_field_length/private_field triple, present
|
|
70
|
+
* exactly when the message's private_fec_flag is 1. Shared by every layer
|
|
71
|
+
* under LA-FEC, like fecCodeId.
|
|
72
|
+
*/
|
|
73
|
+
privateField?: AlFecPrivateField;
|
|
74
|
+
maximumK: number;
|
|
75
|
+
maximumP: number;
|
|
76
|
+
protectionWindowTime: number;
|
|
77
|
+
protectionWindowSize: number;
|
|
78
|
+
}
|
|
79
|
+
export interface AlFecFlow {
|
|
80
|
+
fecFlowId: number;
|
|
81
|
+
sourceFlowId: number;
|
|
82
|
+
/** Every asset packet_id of the FEC source flow, in signalled order. */
|
|
83
|
+
packetIds: number[];
|
|
84
|
+
fecCodingStructure: number;
|
|
85
|
+
ssbgMode: number;
|
|
86
|
+
ffsrptsFlag: 0 | 1;
|
|
87
|
+
/**
|
|
88
|
+
* The low bit of the coding byte. Amd 1:2025 Table C.3 names it
|
|
89
|
+
* fec_payload_id_mode (Table C.7: 0 = mode 0, Source FEC Payload ID added
|
|
90
|
+
* to each packet; 1 = mode 1, C.7, packets unmodified). The unamended 2023
|
|
91
|
+
* Table C.3 lists the same bit as reserved "1". The parse never depends on
|
|
92
|
+
* it — no later field is conditional on it — so both readings are
|
|
93
|
+
* accepted and the value is reported, not interpreted (BLO-35597 N1).
|
|
94
|
+
*/
|
|
95
|
+
fecPayloadIdMode: 0 | 1;
|
|
96
|
+
/** length_of_repair_symbol, in bytes. */
|
|
97
|
+
repairSymbolSize: number;
|
|
98
|
+
/** Present exactly when ssbg_mode is b10. */
|
|
99
|
+
ssbgMode2?: {
|
|
100
|
+
numRepairSymbolPerPacket: number;
|
|
101
|
+
numSymbolElementPerSourceSymbol: number;
|
|
102
|
+
};
|
|
103
|
+
/** num_of_sub_block_per_source_block, two-stage (0010) only. */
|
|
104
|
+
numSubBlockPerSourceBlock?: number;
|
|
105
|
+
/** One entry for one-stage; N3 parity flows; N4 LA-FEC layers; none for 0000. */
|
|
106
|
+
repairFlows: AlFecRepairFlow[];
|
|
107
|
+
}
|
|
108
|
+
export interface AlFecMessageBody {
|
|
109
|
+
/** The message's version counter (C.6.3). Any value is accepted. */
|
|
110
|
+
version: number;
|
|
111
|
+
fecFlag: 0 | 1;
|
|
112
|
+
privateFecFlag: 0 | 1;
|
|
113
|
+
/** Empty exactly when fec_flag is 0 (no FEC source flow). */
|
|
114
|
+
flows: AlFecFlow[];
|
|
115
|
+
}
|
|
116
|
+
export interface AlFecMessage extends AlFecMessageBody {
|
|
117
|
+
payloadForm: SignallingPayloadForm;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse a complete AL-FEC message (Table C.3, Amd 1:2025), starting at its
|
|
121
|
+
* message_id. Every FEC flow, every asset packet_id and every
|
|
122
|
+
* coding-structure-conditional field is returned.
|
|
123
|
+
*/
|
|
124
|
+
export declare function parseAlFecMessageBody(message: Uint8Array): AlFecMessageBody | null;
|
|
125
|
+
/**
|
|
126
|
+
* Parse the AL-FEC message carried by a full MMTP signalling packet, in
|
|
127
|
+
* either payload form (see SignallingPayloadForm). Returns null when the
|
|
128
|
+
* packet carries no AL-FEC message, more than one, or a malformed one.
|
|
129
|
+
*/
|
|
130
|
+
export declare function parseAlFecMessage(mmtpPacket: Uint8Array): AlFecMessage | null;
|
|
131
|
+
/**
|
|
132
|
+
* Decoder geometry of one FEC flow under the Blockcast one-stage RaptorQ
|
|
133
|
+
* profile: private_field = RaptorQ FEC OTI (RFC 6330 3.3.2-3.3.3, 12 bytes)
|
|
134
|
+
* followed by the interleave depth (1 byte).
|
|
135
|
+
*/
|
|
136
|
+
export interface AlFecRaptorQFlowConfig {
|
|
137
|
+
sourcePacketIds: number[];
|
|
138
|
+
repairFlowId: number;
|
|
139
|
+
ssbgMode: number;
|
|
140
|
+
fecPayloadIdMode: 0 | 1;
|
|
141
|
+
repairSymbolSize: number;
|
|
142
|
+
maximumK: number;
|
|
143
|
+
maximumP: number;
|
|
144
|
+
interleaveDepth: number;
|
|
145
|
+
oti: Uint8Array;
|
|
146
|
+
protectionWindowTime: number;
|
|
147
|
+
protectionWindowSize: number;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Validate one parsed FEC flow against the Blockcast one-stage RaptorQ
|
|
151
|
+
* profile and return its decoder geometry, or null when the flow is outside
|
|
152
|
+
* the profile. Nothing is inferred: K comes from the OTI and must equal
|
|
153
|
+
* maximum_k_for_repair_flow.
|
|
154
|
+
*
|
|
155
|
+
* ssbg_mode 0 and 1 are both returned as signalled: which source-symbol
|
|
156
|
+
* construction a decoder applies is the stream's FEC block profile, decided
|
|
157
|
+
* by its consumer, not here. ffsrpts_flag=1 is refused because the FFSRP_TS
|
|
158
|
+
* word changes the source/repair packet trailer layout that every Blockcast
|
|
159
|
+
* receiver assumes.
|
|
160
|
+
*/
|
|
161
|
+
export declare function alFecRaptorQFlowConfig(flow: AlFecFlow): AlFecRaptorQFlowConfig | null;
|
|
162
|
+
/** location_type values (Table 96) a receiver may meet in an asset location. */
|
|
163
|
+
export type MmtGeneralLocation = {
|
|
164
|
+
locationType: 0x00;
|
|
165
|
+
packetId: number;
|
|
166
|
+
} | {
|
|
167
|
+
locationType: 0x01;
|
|
168
|
+
srcAddress: Uint8Array;
|
|
169
|
+
dstAddress: Uint8Array;
|
|
170
|
+
dstPort: number;
|
|
171
|
+
packetId: number;
|
|
172
|
+
} | {
|
|
173
|
+
locationType: 0x02;
|
|
174
|
+
srcAddress: Uint8Array;
|
|
175
|
+
dstAddress: Uint8Array;
|
|
176
|
+
dstPort: number;
|
|
177
|
+
packetId: number;
|
|
178
|
+
} | {
|
|
179
|
+
locationType: 0x03;
|
|
180
|
+
networkId: number;
|
|
181
|
+
transportStreamId: number;
|
|
182
|
+
mpeg2Pid: number;
|
|
183
|
+
} | {
|
|
184
|
+
locationType: 0x04;
|
|
185
|
+
srcAddress: Uint8Array;
|
|
186
|
+
dstAddress: Uint8Array;
|
|
187
|
+
dstPort: number;
|
|
188
|
+
mpeg2Pid: number;
|
|
189
|
+
} | {
|
|
190
|
+
locationType: 0x05;
|
|
191
|
+
url: Uint8Array;
|
|
192
|
+
} | {
|
|
193
|
+
locationType: 0x06;
|
|
194
|
+
data: Uint8Array;
|
|
195
|
+
};
|
|
196
|
+
/** Identifier_mapping() (Table 98). */
|
|
197
|
+
export type MmtIdentifierMapping = {
|
|
198
|
+
identifierType: 0x00;
|
|
199
|
+
assetIdScheme: number;
|
|
200
|
+
assetId: Uint8Array;
|
|
201
|
+
} | {
|
|
202
|
+
identifierType: 0x01;
|
|
203
|
+
urls: Uint8Array[];
|
|
204
|
+
} | {
|
|
205
|
+
identifierType: 0x02;
|
|
206
|
+
regex: Uint8Array;
|
|
207
|
+
} | {
|
|
208
|
+
identifierType: 0x03;
|
|
209
|
+
representationId: Uint8Array;
|
|
210
|
+
} | {
|
|
211
|
+
identifierType: number;
|
|
212
|
+
privateIdentifier: Uint8Array;
|
|
213
|
+
};
|
|
214
|
+
/** table_id range of the MP table (Table 102): subset 0..14, then complete. */
|
|
215
|
+
export declare const MP_TABLE_ID_SUBSET_0 = 17;
|
|
216
|
+
export declare const MP_TABLE_ID_COMPLETE = 32;
|
|
217
|
+
export declare const MPI_TABLE_ID_FIRST = 1;
|
|
218
|
+
export declare const MPI_TABLE_ID_LAST = 16;
|
|
219
|
+
export interface MpAsset {
|
|
220
|
+
identifier: MmtIdentifierMapping;
|
|
221
|
+
/** asset_type, a 4CC (for example 'hvc1', 'mp4a'). */
|
|
222
|
+
assetType: string;
|
|
223
|
+
assetModificationFlag: boolean;
|
|
224
|
+
defaultAssetFlag: boolean;
|
|
225
|
+
/** Present exactly when asset_clock_relation_flag is 1. */
|
|
226
|
+
assetClockRelationId?: number;
|
|
227
|
+
/** Present exactly when asset_timescale_flag is 1. */
|
|
228
|
+
assetTimescale?: number;
|
|
229
|
+
locations: MmtGeneralLocation[];
|
|
230
|
+
descriptors: Uint8Array;
|
|
231
|
+
}
|
|
232
|
+
export interface MpTable {
|
|
233
|
+
tableId: number;
|
|
234
|
+
version: number;
|
|
235
|
+
/** MP_table_mode (Table 30); b11 is reserved and reported as read. */
|
|
236
|
+
mpTableMode: number;
|
|
237
|
+
/** Present exactly for the complete table (0x20) and subset 0 (0x11). */
|
|
238
|
+
packageId?: Uint8Array;
|
|
239
|
+
/** Present exactly for the complete table (0x20) and subset 0 (0x11). */
|
|
240
|
+
descriptors?: Uint8Array;
|
|
241
|
+
assets: MpAsset[];
|
|
242
|
+
}
|
|
243
|
+
/** Parse a complete MP table (Table 29), starting at its table_id. */
|
|
244
|
+
export declare function parseMpTable(bytes: Uint8Array): MpTable | null;
|
|
245
|
+
/**
|
|
246
|
+
* The packet_ids an Asset is delivered on: every location of type 0x00
|
|
247
|
+
* (same MMTP packet flow), 0x01 (UDP/IPv4) or 0x02 (UDP/IPv6), in
|
|
248
|
+
* signalled order.
|
|
249
|
+
*/
|
|
250
|
+
export declare function mpAssetPacketIds(asset: MpAsset): number[];
|
|
251
|
+
export interface MmtSignallingTable {
|
|
252
|
+
tableId: number;
|
|
253
|
+
version: number;
|
|
254
|
+
/** The complete table, starting at its table_id. */
|
|
255
|
+
bytes: Uint8Array;
|
|
256
|
+
}
|
|
257
|
+
export interface PaMessage {
|
|
258
|
+
version: number;
|
|
259
|
+
/** Every table of the message payload, in order. */
|
|
260
|
+
tables: MmtSignallingTable[];
|
|
261
|
+
/** The MP tables among `tables`, decoded. */
|
|
262
|
+
mpTables: MpTable[];
|
|
263
|
+
}
|
|
264
|
+
export interface MptMessage {
|
|
265
|
+
/** 0x0011-0x001F carry subset 0-14, 0x0020 the complete MP table. */
|
|
266
|
+
messageId: number;
|
|
267
|
+
version: number;
|
|
268
|
+
table: MpTable;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Parse a complete PA message (Table 21), starting at its message_id.
|
|
272
|
+
*
|
|
273
|
+
* Every table in the payload is delimited by its own 16-bit `length` and
|
|
274
|
+
* must match the extension's table_id and table_version. For non-MPI tables
|
|
275
|
+
* table_length is "a copy of the length field" (10.3.2.3) and must match it
|
|
276
|
+
* too; for an MPI table it is derived differently, so it is not compared.
|
|
277
|
+
*/
|
|
278
|
+
export declare function parsePaMessageBody(message: Uint8Array): PaMessage | null;
|
|
279
|
+
/** Parse a complete MPT message (Table 23), starting at its message_id. */
|
|
280
|
+
export declare function parseMptMessageBody(message: Uint8Array): MptMessage | null;
|
|
281
|
+
export type MmtSignallingMessage = {
|
|
282
|
+
kind: 'al-fec';
|
|
283
|
+
message: AlFecMessageBody;
|
|
284
|
+
} | {
|
|
285
|
+
kind: 'pa';
|
|
286
|
+
message: PaMessage;
|
|
287
|
+
} | {
|
|
288
|
+
kind: 'mpt';
|
|
289
|
+
message: MptMessage;
|
|
290
|
+
}
|
|
291
|
+
/** A message this module does not decode, delimited and length-checked. */
|
|
292
|
+
| {
|
|
293
|
+
kind: 'other';
|
|
294
|
+
messageId: number;
|
|
295
|
+
version: number;
|
|
296
|
+
bytes: Uint8Array;
|
|
297
|
+
};
|
|
298
|
+
export interface MmtSignallingPacket {
|
|
299
|
+
payloadForm: SignallingPayloadForm;
|
|
300
|
+
messages: MmtSignallingMessage[];
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Parse every signalling message of a full MMTP signalling packet (the
|
|
304
|
+
* packet_id 0 flow). Returns null when the packet or any message in it is
|
|
305
|
+
* malformed: one unparseable message leaves the receiver unable to say what
|
|
306
|
+
* the packet signalled.
|
|
307
|
+
*
|
|
308
|
+
* The legacy bare form carries exactly one AL-FEC message; any other message
|
|
309
|
+
* is only accepted inside a 9.3.4.2 payload.
|
|
310
|
+
*/
|
|
311
|
+
export declare function parseSignallingPacket(mmtpPacket: Uint8Array): MmtSignallingPacket | null;
|
|
312
|
+
//# sourceMappingURL=signalling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signalling.d.ts","sourceRoot":"","sources":["../src/signalling.ts"],"names":[],"mappings":"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"}
|