feat: the remaining six event types get their parameter forms

MT call, Call connected, Call disconnected, Browser termination, (I-)WLAN
access status and CSG cell selection no longer fall back to the generic
"send a bare notification" prompt:

- MT call (TS 31.111 7.5.1A.2): transaction identifier, calling party number
  + TON -> Address (EFADN BCD coding, encBcdDigits/eventAddressTlv),
  subaddress, IMS URI, media type; source network.
- Call connected (7.5.2A.2) / Call disconnected (7.5.3A.2): transaction
  identifier, near/far-end source select, media type, and a cause - absent,
  the zero-length radio-link-timeout form or custom bytes (the hex field shows
  only for "custom").
- Browser termination (TS 102 223 7.5.9.2): user / error cause.
- (I-)WLAN access status (TS 31.111 7.5.1.2): no coverage / coverage /
  connection on-going.
- CSG cell selection (TS 31.111 7.5.3.2): status + selection mechanism,
  optional access technology, CSG ID, HNB name and PLMN ID; source network.

The device-identities source (TS 102 223 8.7: 82 terminal / 83 network) is now
selectable: EVENT_FORMS carries a fixed `src` or a `srcField`, and
_send_event_download()/`/api/event-send` take an `event_src` override (an
invalid value falls back to the terminal).

Tests: the BCD/Address builders, each event's build vectors, the "no not_yet
left" guard and the server source override.  Help EN/RU, both AGENTS files;
sw cache simple-v348.
This commit is contained in:
2026-10-01 22:19:55 +03:00
parent 994ee6d2a3
commit a26a2b6648
7 changed files with 219 additions and 14 deletions
+13 -4
View File
@@ -4276,12 +4276,20 @@ def _verify_adm(scc, app, adm_hex):
'error': 'Security status not satisfied' if sw == '6982' else 'Error'}
def _send_event_download(scc, event_type, event_data=None, drain=True):
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 82 81 [extra])"""
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."""
src_byte = 0x82
if src:
try:
src_byte = int(str(src), 16) & 0xFF
except (TypeError, ValueError):
src_byte = 0x82
inner = bytearray()
inner.extend([0x99, 0x01, event_type])
inner.extend([0x82, 0x02, 0x82, 0x81])
inner.extend([0x82, 0x02, src_byte, 0x81])
if event_data:
inner.extend(event_data)
if len(inner) < 0x80:
@@ -6849,8 +6857,9 @@ class PysimHandler(BaseHTTPRequestHandler):
self._send_json({'error': 'event_type is required'}, 400)
return
event_data = bytes.fromhex(event_data_hex) if event_data_hex else None
event_src = body.get('event_src')
try:
data, sw = _send_event_download(scc, event_type, event_data)
data, sw = _send_event_download(scc, event_type, event_data, src=event_src)
try:
ev_type = int(event_type)
except (TypeError, ValueError):