Extended logical channels: CLA 0-19, ATR card capabilities, MANAGE CHANNEL (v2.6.0)
- CLA decode (TS 102 221 §10.1.1/§10.3): standard channels 0-3 from b2-b1
and the extended channels 4-19 from b4-b1. The old further-format rule
read only b2-b1 (channel 8 read as 6, 19 as 7) and the ETSI '11x0 xxxx'
coding (0xC0-0xEF) was not handled at all; the class ranges now follow the
specs (0x80-0x8F UICC, 0xA0-0xAF SIM, 0xC0-0xEF ETSI extended, 0x20-0x3F
reserved, 0xFF invalid) and SM/chain are decoded per family — the SM
extraction and the chaining bit (b5, not b6) were off by one bit
- per-channel state: database._decode_rows/_replay_context use the shared
cla_channel() helper — before, CLA & 0x03 with no +4, so a channel-5
SELECT clobbered channel 1's selection and a channel-8 one channel 0's
(the local traces already open channels: 29 MANAGE CHANNEL opens, 1-2)
- COMPRION T=0 import: the synthesized GET RESPONSE keeps the channel —
a plain CLA for 0-3 (as real terminals do) and 01x0 for 4-19
- ATR historical bytes: the UICC's COMPACT-TLV objects (TS 102 221 §6.3.1)
with card service data, the card capabilities (ISO 7816-4 §8.1.1.2.7
Table 88: assignment methods and max logical channels — the workspace
cards announce 4 and "8 or more") and the status indicator ('00' trailing
bytes / the '8Y' TLV); a truncated ATR no longer raises
- MANAGE CHANNEL success replies decode the assigned channel byte
- capture/import: a 'tpdu' packet that is not APDU-shaped (shorter than the
header, CLA FF, ISO-reserved class) is skipped and counted, so a
character-level or mis-sampled stream no longer pollutes the decode
(the local DB's outlier sessions are exactly that)
- tests: CLA table vectors, per-channel state isolation on channels 8/12,
COMPRION GR channels, filetrack extended channels, ATR compact-TLV and
card-capability cases, the capture skip counter, the PWA rows; 527 Python
+ 47 Node tests
- README/README_RUS document the extended channels, card capabilities and
the skip counter; PWA_VERSION/pyproject/version.py 2.6.0, SW v72
This commit is contained in:
1 parent
cbeeed3608
commit
64433f9739
18 files changed
+683
-88
No files matched your search
@@ -0,0 +1,80 @@
|
||||
// ATR/historical rows, the card-capabilities summary and the MANAGE CHANNEL
|
||||
// response row (server-decoded fields rendered by the detail panel).
|
||||
|
||||
const { test } = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const { loadSrc, extractFunc } = require('./helpers.js');
|
||||
|
||||
const src = loadSrc();
|
||||
eval(
|
||||
extractFunc(src, 'ifaceValue') + '\n' +
|
||||
extractFunc(src, 'atrPpsRows') + '\n' +
|
||||
extractFunc(src, 'responseRows')
|
||||
);
|
||||
|
||||
function row(rows, label) {
|
||||
const found = rows.find(r => r[0] === label);
|
||||
return found ? found[1] : undefined;
|
||||
}
|
||||
|
||||
test('atrPpsRows: COMPACT-TLV historical and card capabilities', () => {
|
||||
const rows = atrPpsRows({
|
||||
type: 'atr',
|
||||
historical: {
|
||||
raw: '8031E073FE211B66D0022A761300',
|
||||
category: 'COMPACT-TLV objects',
|
||||
card_capabilities: {
|
||||
raw: 'FE211B', tables: 3,
|
||||
max_channels: 4,
|
||||
channel_assignment: ['by the card', 'by the interface device'],
|
||||
},
|
||||
objects: [
|
||||
{ tag: '3', name: 'Card service data', value: 'E0' },
|
||||
{ tag: '7', name: 'Card capabilities', value: 'FE211B' },
|
||||
{ tag: '6', name: 'Pre-issuing data', value: 'D0022A761300' },
|
||||
],
|
||||
},
|
||||
});
|
||||
assert.match(row(rows, 'Historical'), /COMPACT-TLV objects/);
|
||||
const caps = row(rows, 'Card capabilities');
|
||||
assert.match(caps, /logical channels: up to 4/);
|
||||
assert.match(caps, /assigned by the card, by the interface device/);
|
||||
assert.match(caps, /FE211B/);
|
||||
assert.match(row(rows, 'Historical objects'), /Card service data \(E0\)/);
|
||||
assert.match(row(rows, 'Historical objects'), /Pre-issuing data/);
|
||||
});
|
||||
|
||||
test('atrPpsRows: "8 or more" logical channels', () => {
|
||||
const rows = atrPpsRows({
|
||||
type: 'atr',
|
||||
historical: {
|
||||
raw: '8031E073FE2157',
|
||||
category: 'COMPACT-TLV objects',
|
||||
card_capabilities: {
|
||||
raw: 'FE2157', tables: 3,
|
||||
max_channels: '8 or more',
|
||||
channel_assignment: ['by the card'],
|
||||
extended_lc_le: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
const caps = row(rows, 'Card capabilities');
|
||||
assert.match(caps, /logical channels: 8 or more/);
|
||||
assert.match(caps, /extended Lc\/Le/);
|
||||
});
|
||||
|
||||
test('atrPpsRows: a plain status-indicator historical stays short', () => {
|
||||
const rows = atrPpsRows({
|
||||
type: 'atr',
|
||||
historical: { raw: '808105', category: 'COMPACT-TLV objects',
|
||||
life_cycle: 'operational state (activated)' },
|
||||
});
|
||||
assert.match(row(rows, 'Historical'), /operational state \(activated\)/);
|
||||
assert.equal(row(rows, 'Card capabilities'), undefined);
|
||||
});
|
||||
|
||||
test('responseRows: MANAGE CHANNEL assigned channel', () => {
|
||||
const html = responseRows({ channel: 5 });
|
||||
assert.match(html, /Assigned channel/);
|
||||
assert.match(html, /<td class="value">5<\/td>/);
|
||||
});
|
||||
Reference in new issue
Block a user