v3.14.0: event form object-set fixes + the slices single-envelope mandate

An audit of every event form against the pinned specs (31.111 7.5.x/9.3,
102 223 8.87, TS 101 220's master tag table) found three missing objects,
three malformed/wrong ones, and settled the slice-data scope.

- 0x00 MT call: the IMS URI object is cut at 100 bytes and now carries the
  URI truncated object (8.135, F3 00) when the cut happened.
- 0x1F Slices: the form gains the Partial NSSAI object (8.154, F9, rel 18);
  a single envelope carrying it is marked as the Last Envelope (8.79,
  F0 00) automatically (7.5.27.2).
- 0x06 Card reader status and 0x07 Language: the builders now emit their
  object tags (A0 01 ..., AD ...) - they emitted bare values before.
- 0x18 Incoming IMS data: the IARI tag is F6 (76/F6), not F7 (which is the
  IMPU list tag - the two-column 9.3 table had been misread).
- Single-envelope mandate: the event data is capped at 244 bytes (inner 252;
  the D6 long-form length and the APDU Lc stay in one byte).  The server
  refuses more with a 400 and the PWA shows the size error before sending.
  Chained (multi-envelope) delivery, the More Data object and envelope
  sequences are not implemented - documented in the help and the repo AGENTS.
- Tests: event form vectors (URI truncation, the restored tags, partial /
  Last Envelope, the size helper) and the server guard; the release
  reference and its PWA/code mirrors gain the three objects and the
  corrected IARI key.
- sw cache simple-v375.
This commit is contained in:
2026-10-02 14:34:47 +03:00
parent 7c2841ca06
commit c18b6cd0d4
9 changed files with 114 additions and 16 deletions
+4 -1
View File
@@ -73,10 +73,11 @@ CAT_RELEASE = {
'56/D6 CSG ID': 9,
'57/D7 HNB name': 9,
'31/B1 IMS URI': 10,
'77/F7 IARI': 10,
'76/F6 IARI': 10,
'77/F7 IMPU list': 11,
'78/F8 IMS status code': 11,
'7E/FE Media Type': 12,
'73/F3 URI truncated': 12,
'09/89 PLMN ID': 4,
'3F/BF Access technology': 4,
'B4 Supported Radio Access Technologies': 13,
@@ -96,6 +97,8 @@ CAT_RELEASE = {
'77/F7 Allowed slices with S-NSSAI mapping': 18,
'D7 Rejected slices with S-NSSAI mapping': 18,
'B1 Rejected slices information': 18,
'79/F9 Partial NSSAI': 18,
'70/F0 Last Envelope': 18,
},
'pli': {
'00': 4, '01': 4, '02': 4, '03': 4, '04': 4, '06': 4, '07': 4, '08': 6,
+18 -1
View File
@@ -32,7 +32,7 @@ from osmocom.tlv import BER_TLV_IE
from osmocom.utils import rpad
VERSION = '3.13.4'
VERSION = '3.14.0'
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
@@ -4595,11 +4595,24 @@ def _verify_adm(scc, app, adm_hex):
'error': 'Security status not satisfied' if sw == '6982' else 'Error'}
# The single-ENVELOPE budget for event data: the inner data (event list +
# device identities + the event objects) is wrapped as D6 81 <len> + inner,
# and the APDU Lc must stay within one byte (255), so the inner data is
# capped at 252 bytes (244 bytes of event data + the 8-byte header).
# Chained (multi-envelope) delivery is not implemented - the slice/S-NSSAI
# data must fit one envelope (see the help).
_EVENT_INNER_MAX = 252
_EVENT_DATA_MAX = _EVENT_INNER_MAX - 8
def _send_event_download(scc, event_type, event_data=None, drain=True, src=None):
"""Send ENVELOPE(Event Download) for the given event type.
Builds: CLA C2 0000 Lc D6 [len] (99 01 [type] 82 02 <src> 81 [extra]).
`src` is the source device identity (TS 102 223 8.7: '82' terminal,
'83' network); the default is the terminal."""
if event_data and len(event_data) > _EVENT_DATA_MAX:
raise ValueError('event data does not fit one ENVELOPE (max %d bytes; '
'chained delivery is not implemented)' % _EVENT_DATA_MAX)
src_byte = 0x82
if src:
try:
@@ -7205,6 +7218,10 @@ class PysimHandler(BaseHTTPRequestHandler):
resp['net_state'] = self.server.net_state
self._send_json(resp)
self._log_resp(resp)
except ValueError as e:
# the single-envelope budget (no chained delivery)
self._send_json({'error': str(e)}, 400)
self._log_resp({'error': str(e)})
except Exception as e:
sys.stderr.write('Event send error: %s\n' % e)
_handle_card_disconnect(stale=_is_transport_fatal(e))