Lead the changelog with the read-side break, and show each repeatable TLV's shape
Mirror / push (push) Successful in 4s
Test / lint (pull_request) Successful in 29s
Test / test (20) (pull_request) Successful in 35s
Test / test (18) (pull_request) Successful in 37s
Test / test (24) (pull_request) Successful in 30s
Test / test (22) (pull_request) Successful in 31s
Test / test (26) (pull_request) Successful in 28s

This commit is contained in:
2026-09-24 00:27:01 +02:00
parent f2ee8aa016
commit 11ff349333
4 changed files with 21 additions and 5 deletions
+9 -3
View File
@@ -38,9 +38,15 @@
- `server()` refuses a `maxOctets` below 1 or not a whole number, `Infinity` included, like its
other limits. `server({ maxOctets: 0 })` used to start and then refuse every multipart message.
- `callback_num`, `callback_num_atag`, `callback_num_pres_ind`, `broadcast_area_identifier` and
`broadcast_error_status`, the TLVs SMPP allows more than once in a PDU, read as an array of every
occurrence in wire order, even where only one arrived, and `objToPdu()` takes an array for them and
refuses a lone value. A PDU carrying two of one used to keep only the last.
`broadcast_error_status`, the TLVs SMPP allows more than once in a PDU, keep every occurrence in
wire order. A PDU carrying two of one used to keep only the last.
**Reading one of these now needs an index.** `pduObj.tlvs.callback_num?.tagValue` is a `Buffer[]`
even where one arrived (a `number[]` for `callback_num_pres_ind` and `broadcast_error_status`), so a
`Buffer.isBuffer()` or `typeof` check written for 0.5.0 now reads it as absent. Read `tagValue[0]`
for the first occurrence. `objToPdu()`, `session.send()` and `session.sendReturn()` take
`{ tagValue: [value] }` for them and refuse a lone value before anything goes out.
- `cmds.broadcast_sm_resp.tlvMap` is removed; nothing read it.
## 0.5.0
+4 -1
View File
@@ -610,7 +610,8 @@ if (isCommand(pduObj, 'submit_sm')) {
carried them, `'udh'` or `'sar'`, or `undefined` for a whole message.
- `callback_num`, `callback_num_atag`, `callback_num_pres_ind`, `broadcast_area_identifier` and
`broadcast_error_status` may repeat in one PDU, so each reads as an array of every occurrence in wire
order, and `objToPdu()` writes one TLV per element of the array it takes for them.
order: `number[]` for `callback_num_pres_ind` and `broadcast_error_status`, `Buffer[]` for the rest.
A `broadcast_sm_resp`'s `failed_broadcast_area_identifier` reads as `broadcast_area_identifier`.
- `messageClassOf(dataCoding)`: `0` for the flash class, `1`, `2` and `3` for the ME-, SIM- and
TE-specific ones, `undefined` where that `data_coding`'s coding group carries no class.
@@ -621,6 +622,8 @@ if (isCommand(pduObj, 'submit_sm')) {
naming the character, its code point and where it is.
- Every text field is latin1: addresses, `system_id`, `message_id`, `service_type` and the C-Octet
String TLVs. A character past `U+00FF` is refused, as is a `U+0000` in a C-Octet String.
- The five repeatable TLVs take an array, written as one TLV per element; a lone value or an empty
array is refused.
- A `Buffer` goes out exactly as given under any `data_coding`: binary payloads, hand-built user
data headers, deliberately malformed bodies.
- `session.send()` and `session.sendReturn()` build through the same codec and refuse the same bodies.
+1 -1
View File
@@ -154,7 +154,7 @@ function occurrences(value: TlvValue, multiple: boolean): Result<{ values: Param
return Array.isArray(value) ? { err: new Error('takes one value, not an array') } : { values: [value] };
}
if (!Array.isArray(value)) return { err: new Error('is repeatable, give an array of its values') };
if (!Array.isArray(value)) return { err: new Error('is repeatable, wrap it in an array: [value]') };
if (value.length === 0) return { err: new Error('holds no values, omit it instead') };
+7
View File
@@ -197,6 +197,13 @@ and is also what the panel ranked hardest — two methods, one answer.
### Correctness, ahead of everything below
- [ ] **Type each known TLV's value by its tag, on read and on write, before 0.6.0 is cut.** Every
`tagValue` is `TlvValue`, so `{ callback_num: { tagValue: buf } }` compiles and is refused
only at runtime, and reading `receipted_message_id` has to narrow out arrays it can never
hold. Derive the types from the specs' own wire types and `multiple` flag. It has to land in
the same minor as the arrays, or narrowing the types is a second break. From the
product-owner review of #25.
- [ ] **Settle what a repeated tag not marked `multiple` reads as, and pin it in a test.** A vendor
tag or a known single-value tag a peer sends twice keeps the last occurrence and drops the
rest silently, which goal 3 argues against; listing it would change every such tag's shape.