feat: Push commands pill — GP administration trigger + TS 102 226 §9 pushes (v3.5.0)
The former HTTP OTA pill becomes "Push commands" (RU: Пуш/триггер) and groups everything that makes the card dial out: - Administrative session (GP Amd B §4.7): the existing Trigger/Store UI, unchanged, as the first section (most used). - BIP / CAT_TP trigger (§9): request 01 BIP channel opening (optional OPEN CHANNEL COMPREHENSION-TLVs) or 02 CAT_TP link (destination port, optional max SDU / identification data). - TCP trigger (§9): request 03 TCP connection (bearer, transport level with protocol type 02, destination address 21/57/F0, NAA/APN, extra TLVs) or 04 identification packet (optional data, ICCID when absent — sent over an already open channel). The guided sections reuse chainPushData (the RAM/GP chain PUSH encoder) and preview the C-APDU; mandatory parameters (02 port, 03 port + address) are enforced there while the chain row stays lenient. Actions: Pack into Secured packet (no auto-TAR — a §9 PUSH goes to the target application) and → Expanded Script (22 Command TLV import; berAppendApdu extracted from loadExpandedScript). Each §9 request has a note separating it from the administration session. Chain-builder PUSH command and the expanded-script C-APDU picker are unchanged. Tests: pushSectionApdu vectors in ts102226.test.js; help 2.7 EN/RU restructured, READMEs, AGENTS; sw cache -> simple-v246.
This commit is contained in:
@@ -31,7 +31,7 @@ function extractFunc(src, name) {
|
||||
const FNS = ['berLenStr', 'buildApdu', 'buildSelect', 'escHtml', 'esc', 'chainInit',
|
||||
'chainKind', 'chainIsEmbedded', 'chainCommands', 'chainBuildRowHex',
|
||||
'chainSimBuildRowHex', 'chainRamBuildRowHex', 'chainPushData', '_hotaAsciiHex',
|
||||
'chainApduList', 'chainBuildFcp'];
|
||||
'chainApduList', 'chainBuildFcp', 'pushSectionApdu'];
|
||||
let code = '';
|
||||
for (const f of FNS) code += extractFunc(html, f) + '\n';
|
||||
for (const c of ['CHAIN_CMDS_SIM', 'CHAIN_CMDS_USIM', 'CHAIN_CMDS_RAM']) {
|
||||
@@ -227,6 +227,24 @@ test('CREATE FILE FCP template skeleton (TS 102 222 table 4)', () => {
|
||||
assert.strictEqual(r4.fields.fcp, '620883026F0780020010');
|
||||
});
|
||||
|
||||
test('pushSectionApdu builds the guided §9 push commands (Remote APDU pill)', () => {
|
||||
// BIP channel opening: OPEN CHANNEL TLVs are optional.
|
||||
assert.strictEqual(pushSectionApdu('bip', { request: '01', pushData: '350103' }), '80EC010103350103');
|
||||
assert.strictEqual(pushSectionApdu('bip', { request: '01', pushData: '' }), '80EC0101');
|
||||
// CAT_TP: the destination port is mandatory (9.2.2).
|
||||
assert.strictEqual(pushSectionApdu('bip', { request: '02', pushPort: '1F90' }), '80EC0102053C03001F90');
|
||||
assert.strictEqual(pushSectionApdu('bip', { request: '02', pushPort: '' }), '');
|
||||
// TCP: port and destination address are mandatory (9.2.3).
|
||||
assert.strictEqual(
|
||||
pushSectionApdu('tcp', { request: '03', pushPort: '0050', pushAddr: '210A000001', pushApn: 'internet' }),
|
||||
'80EC010319' + '3501033C030200503E05210A0000014708696E7465726E6574');
|
||||
assert.strictEqual(pushSectionApdu('tcp', { request: '03', pushPort: '0050' }), '');
|
||||
assert.strictEqual(pushSectionApdu('tcp', { request: '03', pushAddr: '210A000001' }), '');
|
||||
// Identification packet: optional data, ICCID is used when absent (9.2.4).
|
||||
assert.strictEqual(pushSectionApdu('tcp', { request: '04', pushIdent: '0102' }), '80EC01040436020102');
|
||||
assert.strictEqual(pushSectionApdu('tcp', { request: '04', pushIdent: '' }), '80EC0104');
|
||||
});
|
||||
|
||||
test('chainApduList drops GET RESPONSE and splits multi-APDU rows', () => {
|
||||
_chains['ber-usim-1'] = { rows: [
|
||||
row('read-binary', { offset: '0000', le: '00' }),
|
||||
|
||||
Reference in New Issue
Block a user