ui: name REFRESH and the rest of the TS 102 223 command types (v2.7.17)
The proactive command log showed 'Cmd 0x01' for REFRESH: 0x01 was missing from both CMD_NAMES (frontend) and PROACTIVE_TYPE_NAMES (server), so the log fell back to the generic placeholder. Both tables now carry the full TS 102 223 9.4 command type list (REFRESH, MORE TIME, POLLING OFF, SET UP CALL, SEND SS/USSD/DTMF, GEOGRAPHICAL LOCATION REQUEST, SET UP IDLE MODE TEXT, PERFORM CARD APDU, POWER ON/OFF CARD, GET READER STATUS, RUN AT COMMAND, LANGUAGE NOTIFICATION, SERVICE SEARCH/INFORMATION, DECLARE SERVICE, frames, multimedia, COMMAND CONTAINER, ...). - tests: event_forms CMD_NAMES cases; new tests/test_proactive_names.py (REFRESH + spec spot checks).
This commit is contained in:
+20
-9
@@ -1413,7 +1413,7 @@
|
||||
// ===== Version =====
|
||||
// Single source of truth for the PWA version: shown in the header and used
|
||||
// by the server version check in pysimConnect().
|
||||
const SIMPLE_VERSION = '2.7.16';
|
||||
const SIMPLE_VERSION = '2.7.17';
|
||||
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
||||
|
||||
// ===== Tab switching =====
|
||||
@@ -8303,15 +8303,26 @@ function pysimProactiveSeqChanged(seq) {
|
||||
_pysimProactiveSeq = seq;
|
||||
return true;
|
||||
}
|
||||
// TS 102 223 9.4 command types (values equal the proactive command template
|
||||
// tags); the log falls back to 'Cmd 0xNN' for anything not listed.
|
||||
const CMD_NAMES = {
|
||||
'03': 'POLL INTERVAL', '05': 'SET UP EVENT LIST',
|
||||
'13': 'SEND SHORT MESSAGE', '20': 'PLAY TONE',
|
||||
'21': 'DISPLAY TEXT', '22': 'GET INKEY', '23': 'GET INPUT',
|
||||
'24': 'SELECT ITEM', '25': 'SET UP MENU',
|
||||
'26': 'PROVIDE LOCAL INFORMATION', '27': 'TIMER MANAGEMENT',
|
||||
'15': 'LAUNCH BROWSER', '70': 'ACTIVATE',
|
||||
'40': 'OPEN CHANNEL', '41': 'CLOSE CHANNEL',
|
||||
'42': 'RECEIVE DATA', '43': 'SEND DATA', '44': 'GET CHANNEL STATUS',
|
||||
'01': 'REFRESH', '02': 'MORE TIME', '03': 'POLL INTERVAL', '04': 'POLLING OFF',
|
||||
'05': 'SET UP EVENT LIST', '10': 'SET UP CALL', '11': 'SEND SS', '12': 'SEND USSD',
|
||||
'13': 'SEND SHORT MESSAGE', '14': 'SEND DTMF', '15': 'LAUNCH BROWSER',
|
||||
'16': 'GEOGRAPHICAL LOCATION REQUEST',
|
||||
'20': 'PLAY TONE', '21': 'DISPLAY TEXT', '22': 'GET INKEY', '23': 'GET INPUT',
|
||||
'24': 'SELECT ITEM', '25': 'SET UP MENU', '26': 'PROVIDE LOCAL INFORMATION',
|
||||
'27': 'TIMER MANAGEMENT', '28': 'SET UP IDLE MODE TEXT',
|
||||
'30': 'PERFORM CARD APDU', '31': 'POWER ON CARD', '32': 'POWER OFF CARD',
|
||||
'33': 'GET READER STATUS', '34': 'RUN AT COMMAND', '35': 'LANGUAGE NOTIFICATION',
|
||||
'40': 'OPEN CHANNEL', '41': 'CLOSE CHANNEL', '42': 'RECEIVE DATA', '43': 'SEND DATA',
|
||||
'44': 'GET CHANNEL STATUS', '45': 'SERVICE SEARCH', '46': 'GET SERVICE INFORMATION',
|
||||
'47': 'DECLARE SERVICE', '50': 'SET FRAMES', '51': 'GET FRAMES STATUS',
|
||||
'60': 'RETRIEVE MULTIMEDIA MESSAGE', '61': 'SUBMIT MULTIMEDIA MESSAGE',
|
||||
'62': 'DISPLAY MULTIMEDIA MESSAGE', '70': 'ACTIVATE',
|
||||
'71': 'CONTACTLESS STATE CHANGED', '72': 'COMMAND CONTAINER',
|
||||
'73': 'ENCAPSULATED SESSION CONTROL', '79': 'LSI COMMAND',
|
||||
'81': 'End of the proactive UICC session',
|
||||
};
|
||||
|
||||
const CMD_QUALIFIER_SHORT = {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
const CACHE = 'simple-v219';
|
||||
const CACHE = 'simple-v220';
|
||||
const URLS = [
|
||||
'index.html',
|
||||
'help.html',
|
||||
|
||||
@@ -35,7 +35,10 @@ eval(extractBlock('const REJECTION_CAUSES = [', 'const EVENT_FORMS = {').replace
|
||||
eval(extractBlock('const EVENT_FORMS = {', 'const PLI_QUALIFIERS = [').replace(/^const /gm, 'var '));
|
||||
|
||||
test('CMD_NAMES decodes timer management and the BIP commands', () => {
|
||||
assert.strictEqual(CMD_NAMES['01'], 'REFRESH');
|
||||
assert.strictEqual(CMD_NAMES['10'], 'SET UP CALL');
|
||||
assert.strictEqual(CMD_NAMES['27'], 'TIMER MANAGEMENT');
|
||||
assert.strictEqual(CMD_NAMES['28'], 'SET UP IDLE MODE TEXT');
|
||||
assert.strictEqual(CMD_NAMES['40'], 'OPEN CHANNEL');
|
||||
assert.strictEqual(CMD_NAMES['41'], 'CLOSE CHANNEL');
|
||||
assert.strictEqual(CMD_NAMES['42'], 'RECEIVE DATA');
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pysim-simple-server"
|
||||
version = "2.7.16"
|
||||
version = "2.7.17"
|
||||
description = "HTTP REST server wrapping pysim for the SIMple PWA"
|
||||
requires-python = ">=3.8"
|
||||
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
|
||||
|
||||
@@ -26,7 +26,7 @@ from osmocom.tlv import BER_TLV_IE
|
||||
from osmocom.utils import rpad
|
||||
|
||||
|
||||
VERSION = '2.7.16'
|
||||
VERSION = '2.7.17'
|
||||
|
||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||
|
||||
@@ -1086,15 +1086,29 @@ _PROACTIVE_LOG = []
|
||||
_PROACTIVE_SESSION_START = None
|
||||
_PROACTIVE_ENTRY_ID = 0
|
||||
|
||||
# TS 102 223 §9.4 command types (the values are also the proactive command
|
||||
# template tags). Unknown values fall back to 'UNKNOWN' in the log.
|
||||
PROACTIVE_TYPE_NAMES = {
|
||||
0x03: 'POLL INTERVAL', 0x05: 'SET UP EVENT LIST',
|
||||
0x13: 'SEND SHORT MESSAGE', 0x20: 'PLAY TONE',
|
||||
0x01: 'REFRESH', 0x02: 'MORE TIME', 0x03: 'POLL INTERVAL',
|
||||
0x04: 'POLLING OFF', 0x05: 'SET UP EVENT LIST', 0x10: 'SET UP CALL',
|
||||
0x11: 'SEND SS', 0x12: 'SEND USSD', 0x13: 'SEND SHORT MESSAGE',
|
||||
0x14: 'SEND DTMF', 0x15: 'LAUNCH BROWSER',
|
||||
0x16: 'GEOGRAPHICAL LOCATION REQUEST', 0x20: 'PLAY TONE',
|
||||
0x21: 'DISPLAY TEXT', 0x22: 'GET INKEY', 0x23: 'GET INPUT',
|
||||
0x24: 'SELECT ITEM', 0x25: 'SET UP MENU',
|
||||
0x26: 'PROVIDE LOCAL INFORMATION', 0x27: 'TIMER MANAGEMENT',
|
||||
0x15: 'LAUNCH BROWSER', 0x70: 'ACTIVATE',
|
||||
0x40: 'OPEN CHANNEL', 0x41: 'CLOSE CHANNEL',
|
||||
0x42: 'RECEIVE DATA', 0x43: 'SEND DATA', 0x44: 'GET CHANNEL STATUS',
|
||||
0x28: 'SET UP IDLE MODE TEXT', 0x30: 'PERFORM CARD APDU',
|
||||
0x31: 'POWER ON CARD', 0x32: 'POWER OFF CARD', 0x33: 'GET READER STATUS',
|
||||
0x34: 'RUN AT COMMAND', 0x35: 'LANGUAGE NOTIFICATION',
|
||||
0x40: 'OPEN CHANNEL', 0x41: 'CLOSE CHANNEL', 0x42: 'RECEIVE DATA',
|
||||
0x43: 'SEND DATA', 0x44: 'GET CHANNEL STATUS', 0x45: 'SERVICE SEARCH',
|
||||
0x46: 'GET SERVICE INFORMATION', 0x47: 'DECLARE SERVICE',
|
||||
0x50: 'SET FRAMES', 0x51: 'GET FRAMES STATUS',
|
||||
0x60: 'RETRIEVE MULTIMEDIA MESSAGE', 0x61: 'SUBMIT MULTIMEDIA MESSAGE',
|
||||
0x62: 'DISPLAY MULTIMEDIA MESSAGE', 0x70: 'ACTIVATE',
|
||||
0x71: 'CONTACTLESS STATE CHANGED', 0x72: 'COMMAND CONTAINER',
|
||||
0x73: 'ENCAPSULATED SESSION CONTROL', 0x79: 'LSI COMMAND',
|
||||
0x81: 'End of the proactive UICC session',
|
||||
}
|
||||
|
||||
PLI_QUALIFIER_NAMES = {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# coding=utf-8
|
||||
"""Tests for the proactive command type names (TS 102 223 §9.4).
|
||||
|
||||
The live card issues REFRESH (0x01) right after a Location status event; a
|
||||
missing entry makes the proactive log show the generic 'Cmd 0x01' fallback.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from pysim_simple_server.server import PROACTIVE_TYPE_NAMES
|
||||
|
||||
|
||||
class ProactiveTypeNamesTests(unittest.TestCase):
|
||||
def test_refresh_is_named(self):
|
||||
self.assertEqual(PROACTIVE_TYPE_NAMES[0x01], 'REFRESH')
|
||||
|
||||
def test_common_types_match_the_spec(self):
|
||||
for value, name in [
|
||||
(0x02, 'MORE TIME'), (0x03, 'POLL INTERVAL'), (0x04, 'POLLING OFF'),
|
||||
(0x05, 'SET UP EVENT LIST'), (0x10, 'SET UP CALL'),
|
||||
(0x11, 'SEND SS'), (0x12, 'SEND USSD'),
|
||||
(0x13, 'SEND SHORT MESSAGE'), (0x14, 'SEND DTMF'),
|
||||
(0x15, 'LAUNCH BROWSER'), (0x16, 'GEOGRAPHICAL LOCATION REQUEST'),
|
||||
(0x21, 'DISPLAY TEXT'), (0x24, 'SELECT ITEM'), (0x25, 'SET UP MENU'),
|
||||
(0x26, 'PROVIDE LOCAL INFORMATION'), (0x27, 'TIMER MANAGEMENT'),
|
||||
(0x28, 'SET UP IDLE MODE TEXT'), (0x40, 'OPEN CHANNEL'),
|
||||
(0x44, 'GET CHANNEL STATUS'), (0x70, 'ACTIVATE'),
|
||||
]:
|
||||
self.assertEqual(PROACTIVE_TYPE_NAMES[value], name, hex(value))
|
||||
|
||||
def test_names_are_nonempty_strings(self):
|
||||
for value, name in PROACTIVE_TYPE_NAMES.items():
|
||||
self.assertIsInstance(value, int)
|
||||
self.assertTrue(isinstance(name, str) and name, hex(value))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user