From 4bdb1e64b045650ea6e5348c648498d1720475ef Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Mon, 28 Sep 2026 04:07:44 +0200 Subject: [PATCH] Take bound()'s bind type as a string, name the fix in its refusals, and show the ESME's spelling --- CHANGELOG.md | 3 ++- MIGRATION.md | 5 +++-- README.md | 13 ++++++++----- src/session-options.ts | 8 ++++++-- src/session.ts | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c77c870..abdd134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,7 +77,8 @@ - `session.boundAs` and `session.peerInterfaceVersion` are read-only, and `session.loggedIn` is removed: read `session.boundAs !== undefined`. A session you wire yourself records the bind it accepted or had accepted with `session.bound(bindType, declaredVersion)`, which returns `err` for a - bind type or version it cannot record; an assignment to either field now throws a `TypeError`. + bind type or version it cannot record. An assignment to either field does not compile in + TypeScript, and throws a `TypeError` in strict-mode JavaScript, which every module is. ## 0.5.0 diff --git a/MIGRATION.md b/MIGRATION.md index 256297a..7d96689 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -36,8 +36,9 @@ shape is the same, connect, send, listen for delivery reports, with callbacks re Write `alert_on_message_delivery` and `broadcast_area_identifier`, the names they read back under, for `alert_on_msg_delivery` and `failed_broadcast_area_identifier`, which are gone from `tlvs` too. -- **`session.loggedIn` is gone**: read `session.boundAs !== undefined`. A session you construct - yourself records a bind with `session.bound()`. +- **`session.loggedIn` and the `loggedIn` event are gone.** `client()` resolves once bound, + `session.boundAs !== undefined` says a bind happened, and `disconnected`/`reconnected` say whether + the link is up now. A session you construct yourself records a bind with `session.bound()`. - **The `error` event is `sessionError`**, and `serverError` on the server handle. - **`log`** takes any object with `debug`, `error`, `info`, `verbose` and `warn` methods instead of a `larvitutils` one, and is silent by default: [README](README.md#logging). diff --git a/README.md b/README.md index f0af027..ffdf4eb 100644 --- a/README.md +++ b/README.md @@ -424,10 +424,13 @@ const { err, pduObj } = await session.send({ - `peerInterfaceVersion`: the version the peer declared, `0x00` if none, `undefined` before any bind. - `bindAllows(cmdName)` and `boundAs`: what the bind direction carries: [Bind direction](#bind-direction). - `boundAs` and `peerInterfaceVersion` are read-only, and hold through a reconnect's gap until the - next `bound()`. + link binds again. - `bound(bindType, declaredVersion)`: how a session you construct yourself records a bind, whichever - end accepted it, on every link it binds. `declaredVersion` is 0-255, or `undefined` where the peer - declared none; anything else, or an unknown `bindType`, returns `err` and records nothing. + end accepted it, on every link it binds. `bindType` is `receiver`, `transceiver` or `transmitter`; + `declaredVersion` is 0-255, or `undefined` where the peer declared none. Anything else returns `err` + and records nothing. +- An ESME records the bind from its `bind_resp`, in `reconnect.onConnected` on every rebind: + `session.bound('transmitter', pduObj.tlvs.sc_interface_version?.tagValue)`. ## Receiving in depth @@ -545,8 +548,8 @@ if (err) throw err; the link. Guard on the command name, as above, and a failing hook costs only its own request. - A `Session` you construct yourself takes the same hook as a session option, and that is where a peer's bind gets accepted, since a hand-wired session has no bind handling of its own: call - `session.bound(bindType, pduObj.params.interface_version)` before answering it, and refuse the bind - with `ESME_RBINDFAIL` where that returns `err`. + `session.bound(pduObj.cmdName.slice('bind_'.length), pduObj.params.interface_version)` before + answering it, and refuse the bind with `ESME_RBINDFAIL` where that returns `err`. **`sendDlr()`** takes `SCHEDULED`, `ENROUTE`, `DELIVERED`, `EXPIRED`, `DELETED`, `UNDELIVERABLE`, `ACCEPTED`, `UNKNOWN`, `REJECTED` or `SKIPPED`. The first two go out as intermediate delivery diff --git a/src/session-options.ts b/src/session-options.ts index 15d8405..882ffdf 100644 --- a/src/session-options.ts +++ b/src/session-options.ts @@ -123,6 +123,10 @@ export const undeclaredInterfaceVersion = 0x00; export type SessionBind = { as: BindType; peerVersion: number }; +function quoted(value: unknown): string { + return typeof value === 'string' ? JSON.stringify(value) : namedValue(value); +} + function isBindType(value: unknown): value is BindType { return typeof value === 'string' && bindTypeFromCommand(`bind_${value}`) !== undefined; } @@ -130,13 +134,13 @@ function isBindType(value: unknown): value is BindType { /** A bind as `Session.bound()` records it: undefined declares no version, which is pre-3.4. */ export function checkedBind(bindType: unknown, declaredVersion: unknown): Result<{ bind: SessionBind }> { if (!isBindType(bindType)) { - return { err: new Error(`bindType must be receiver, transceiver or transmitter, got ${namedValue(bindType)}`) }; + return { err: new Error(`bindType must be receiver, transceiver or transmitter, the bind command's name without "bind_", got ${quoted(bindType)}`) }; } if (declaredVersion === undefined) return { bind: { as: bindType, peerVersion: undeclaredInterfaceVersion } }; if (typeof declaredVersion !== 'number' || !Number.isInteger(declaredVersion) || declaredVersion < 0 || declaredVersion > 0xFF) { - return { err: new Error(`declaredVersion must be 0-255, or undefined where the peer declared none, got ${namedValue(declaredVersion)}`) }; + return { err: new Error(`declaredVersion must be an integer 0-255, the interface_version param or the sc_interface_version TLV's tagValue, or undefined where the peer declared none, got ${quoted(declaredVersion)}`) }; } return { bind: { as: bindType, peerVersion: declaredVersion } }; diff --git a/src/session.ts b/src/session.ts index e92b7d4..b165697 100644 --- a/src/session.ts +++ b/src/session.ts @@ -162,7 +162,7 @@ export class Session extends EventEmitter { } /** Records a bind this link accepted or had accepted, until the next one. */ - bound(bindType: BindType, declaredVersion: unknown): VoidResult { + bound(bindType: string, declaredVersion: unknown): VoidResult { const checked = checkedBind(bindType, declaredVersion); if (!checked.err) this.bind = checked.bind;