@blockcast/mmt-alta-parse 0.1.0 → 0.3.0-main.2515e5ca4858
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/package.json +7 -2
- package/src/index.test.ts +0 -144
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blockcast/mmt-alta-parse",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-main.2515e5ca4858",
|
|
4
4
|
"description": "Zero-dependency leaf: extract the detached ALTA authenticator trailer from an MMTP source packet",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,7 +13,12 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
-
"src"
|
|
16
|
+
"src",
|
|
17
|
+
"!src/**/*.test.ts",
|
|
18
|
+
"!src/**/*.spec.ts",
|
|
19
|
+
"!src/**/__tests__",
|
|
20
|
+
"!dist/**/*.test.*",
|
|
21
|
+
"!dist/**/*.spec.*"
|
|
17
22
|
],
|
|
18
23
|
"scripts": {
|
|
19
24
|
"build": "tsc",
|
package/src/index.test.ts
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
MMTP_EXT_TRAILER_HEADER_SIZE,
|
|
4
|
-
MMTP_EXT_TYPE_ALTA_AUTH,
|
|
5
|
-
extractAltaTrailer,
|
|
6
|
-
} from './index.js'
|
|
7
|
-
|
|
8
|
-
const MMTP_HEADER_SIZE = 12
|
|
9
|
-
const MPU_HEADER_SIZE = 8
|
|
10
|
-
const TIMED_MFU_DU_HEADER_SIZE = 14
|
|
11
|
-
|
|
12
|
-
function buildPacket(options?: {
|
|
13
|
-
auth?: Uint8Array
|
|
14
|
-
appendFecId?: boolean
|
|
15
|
-
fecType?: number
|
|
16
|
-
fi?: number
|
|
17
|
-
media?: Uint8Array
|
|
18
|
-
payloadLength?: number
|
|
19
|
-
packetType?: number
|
|
20
|
-
timed?: boolean
|
|
21
|
-
trailing?: Uint8Array
|
|
22
|
-
wireDuSize?: number
|
|
23
|
-
}): Uint8Array {
|
|
24
|
-
const auth = options?.auth
|
|
25
|
-
const appendFecId = options?.appendFecId ?? false
|
|
26
|
-
const fecType = options?.fecType ?? (appendFecId ? 1 : 0)
|
|
27
|
-
const fi = options?.fi ?? 0
|
|
28
|
-
const media = options?.media ?? new Uint8Array([0xaa, 0xbb, 0xcc])
|
|
29
|
-
const timed = options?.timed ?? true
|
|
30
|
-
const structuralDuSize = fi <= 1 ? (timed ? TIMED_MFU_DU_HEADER_SIZE : 4) : 0
|
|
31
|
-
const duSize = options?.wireDuSize ?? structuralDuSize
|
|
32
|
-
const payloadLength = options?.payloadLength ?? (MPU_HEADER_SIZE - 2 + duSize + media.length)
|
|
33
|
-
const bytes: number[] = []
|
|
34
|
-
|
|
35
|
-
bytes.push((fecType & 0x03) << 3)
|
|
36
|
-
bytes.push(options?.packetType ?? 0)
|
|
37
|
-
bytes.push(0, 1)
|
|
38
|
-
bytes.push(0, 0, 0, 1)
|
|
39
|
-
bytes.push(0, 0, 0, 2)
|
|
40
|
-
|
|
41
|
-
bytes.push((payloadLength >> 8) & 0xff, payloadLength & 0xff)
|
|
42
|
-
bytes.push((2 << 4) | (timed ? 1 << 3 : 0) | (fi << 1))
|
|
43
|
-
bytes.push(0)
|
|
44
|
-
bytes.push(0, 0, 0, 3)
|
|
45
|
-
|
|
46
|
-
for (let i = 0; i < duSize; i++) bytes.push(0)
|
|
47
|
-
for (const value of media) bytes.push(value)
|
|
48
|
-
|
|
49
|
-
if (auth) {
|
|
50
|
-
bytes.push((MMTP_EXT_TYPE_ALTA_AUTH >> 8) & 0xff, MMTP_EXT_TYPE_ALTA_AUTH & 0xff)
|
|
51
|
-
bytes.push((auth.length >> 8) & 0xff, auth.length & 0xff)
|
|
52
|
-
for (const value of auth) bytes.push(value)
|
|
53
|
-
}
|
|
54
|
-
if (options?.trailing) {
|
|
55
|
-
for (const value of options.trailing) bytes.push(value)
|
|
56
|
-
}
|
|
57
|
-
if (appendFecId) bytes.push(0, 0, 0, 9)
|
|
58
|
-
|
|
59
|
-
return new Uint8Array(bytes)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
describe('extractAltaTrailer', () => {
|
|
63
|
-
it('locates ALTA after the canonical ISO-declared span and before Source FEC ID', () => {
|
|
64
|
-
const media = new Uint8Array([0x10, 0x20, 0x30, 0x40])
|
|
65
|
-
const auth = new Uint8Array([0xde, 0xad, 0xbe, 0xef])
|
|
66
|
-
const packet = buildPacket({ media, auth, appendFecId: true })
|
|
67
|
-
|
|
68
|
-
expect(extractAltaTrailer(packet)).toEqual({
|
|
69
|
-
auth,
|
|
70
|
-
signedEnd: MMTP_HEADER_SIZE + MPU_HEADER_SIZE + TIMED_MFU_DU_HEADER_SIZE + media.length,
|
|
71
|
-
})
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
it('locates ALTA in a recovered source symbol with the FEC ID already stripped', () => {
|
|
75
|
-
const auth = new Uint8Array([1, 2, 3, 4, 5])
|
|
76
|
-
const packet = buildPacket({ auth, fecType: 1 })
|
|
77
|
-
expect(extractAltaTrailer(packet, { skipFecId: true })?.auth).toEqual(auth)
|
|
78
|
-
expect(extractAltaTrailer(packet)).toBeNull()
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it.each([
|
|
82
|
-
{ fi: 0, duSize: TIMED_MFU_DU_HEADER_SIZE },
|
|
83
|
-
{ fi: 1, duSize: TIMED_MFU_DU_HEADER_SIZE },
|
|
84
|
-
{ fi: 2, duSize: 0 },
|
|
85
|
-
{ fi: 3, duSize: 0 },
|
|
86
|
-
])('uses the same declared coordinate for FI=$fi', ({ fi, duSize }) => {
|
|
87
|
-
const media = new Uint8Array([0x55, 0x66])
|
|
88
|
-
const auth = new Uint8Array([0x77])
|
|
89
|
-
const result = extractAltaTrailer(buildPacket({ fi, media, auth }))
|
|
90
|
-
expect(result?.signedEnd).toBe(MMTP_HEADER_SIZE + MPU_HEADER_SIZE + duSize + media.length)
|
|
91
|
-
expect(result?.auth).toEqual(auth)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it.each([0, 5])('rejects payload_length=%i because it cannot contain the MPU header remainder', (payloadLength) => {
|
|
95
|
-
expect(extractAltaTrailer(buildPacket({ auth: new Uint8Array([1]), payloadLength }))).toBeNull()
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it.each([
|
|
99
|
-
{ fi: 0, timed: true, payloadLength: 6, wireDuSize: 0 },
|
|
100
|
-
{ fi: 0, timed: true, payloadLength: 20, wireDuSize: TIMED_MFU_DU_HEADER_SIZE },
|
|
101
|
-
{ fi: 0, timed: false, payloadLength: 10, wireDuSize: 4 },
|
|
102
|
-
{ fi: 2, timed: true, payloadLength: 6, wireDuSize: 0 },
|
|
103
|
-
])('rejects an FT=2/FI=$fi declaration with no media after its structural DU header', (options) => {
|
|
104
|
-
expect(extractAltaTrailer(buildPacket({
|
|
105
|
-
...options,
|
|
106
|
-
auth: new Uint8Array([1]),
|
|
107
|
-
media: new Uint8Array(),
|
|
108
|
-
}))).toBeNull()
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('rejects a declaration that overruns the packet', () => {
|
|
112
|
-
expect(extractAltaTrailer(buildPacket({
|
|
113
|
-
auth: new Uint8Array([1]),
|
|
114
|
-
payloadLength: 0xffff,
|
|
115
|
-
}))).toBeNull()
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it('rejects the obsolete media-only declaration without scanning for ALTA', () => {
|
|
119
|
-
const media = new Uint8Array([0xf0, 0xa1, 0, 1, 0x99])
|
|
120
|
-
const packet = buildPacket({
|
|
121
|
-
media,
|
|
122
|
-
auth: new Uint8Array([0xaa]),
|
|
123
|
-
payloadLength: media.length,
|
|
124
|
-
})
|
|
125
|
-
expect(extractAltaTrailer(packet)).toBeNull()
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it('returns null when the exact declared end has no ALTA trailer', () => {
|
|
129
|
-
expect(extractAltaTrailer(buildPacket({ appendFecId: true }))).toBeNull()
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it('rejects bytes after the authenticator instead of accepting a partial suffix', () => {
|
|
133
|
-
const packet = buildPacket({
|
|
134
|
-
auth: new Uint8Array([0xaa, 0xbb]),
|
|
135
|
-
appendFecId: true,
|
|
136
|
-
trailing: new Uint8Array([0xcc]),
|
|
137
|
-
})
|
|
138
|
-
expect(extractAltaTrailer(packet)).toBeNull()
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
it('exports the four-byte ALTA trailer header size', () => {
|
|
142
|
-
expect(MMTP_EXT_TRAILER_HEADER_SIZE).toBe(4)
|
|
143
|
-
})
|
|
144
|
-
})
|