v3.28.6: keep the PoR delivered with a 91xx ENVELOPE answer
A card may deliver the response packet (the PoR) in the GET RESPONSE of an ENVELOPE that answered 61xx and signal a proactive command pending in the same answer (91xx - the CAT success state, not an error). _send_envelope ran the chain and then cleared the response data (`data, sw = '', '9000'`), so the operation reported no PoR although the card had returned one (live 2026-10-14: a GP DELETE answered 6113, the GET RESPONSE delivered the PoR with 9130, and the delete verdict showed "ok (no PoR)"). The delivered bytes are kept now; the chain still runs and the exchange reports 9000. Test: the delivered PoR survives the chain (verified to fail on the old code). 917 frontend + 928 Python; sw cache simple-v444.
This commit is contained in:
+1
-1
@@ -1910,7 +1910,7 @@
|
|||||||
// ===== Version =====
|
// ===== Version =====
|
||||||
// Single source of truth for the PWA version: shown in the header and used
|
// Single source of truth for the PWA version: shown in the header and used
|
||||||
// by the server version check in pysimConnect().
|
// by the server version check in pysimConnect().
|
||||||
const SIMPLE_VERSION = '3.28.5';
|
const SIMPLE_VERSION = '3.28.6';
|
||||||
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
||||||
|
|
||||||
// ===== view history (the browser Back/Forward buttons) =====
|
// ===== view history (the browser Back/Forward buttons) =====
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const CACHE = 'simple-v443';
|
const CACHE = 'simple-v444';
|
||||||
const URLS = [
|
const URLS = [
|
||||||
'index.html',
|
'index.html',
|
||||||
'help.html',
|
'help.html',
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "pysim-simple-server"
|
name = "pysim-simple-server"
|
||||||
version = "3.28.5"
|
version = "3.28.6"
|
||||||
description = "HTTP REST server wrapping pysim for the SIMple PWA"
|
description = "HTTP REST server wrapping pysim for the SIMple PWA"
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.8"
|
||||||
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
|
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ from osmocom.tlv import BER_TLV_IE
|
|||||||
from osmocom.utils import rpad
|
from osmocom.utils import rpad
|
||||||
|
|
||||||
|
|
||||||
VERSION = '3.28.5'
|
VERSION = '3.28.6'
|
||||||
|
|
||||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||||
|
|
||||||
@@ -1350,8 +1350,16 @@ def _send_envelope(tpdu_hex, scc, sm_sc='12345678912', submit_handler=None,
|
|||||||
# retrieved from this exchange (TS 31.115 4.2/4.4, v3.25.7).
|
# retrieved from this exchange (TS 31.115 4.2/4.4, v3.25.7).
|
||||||
data, sw = _envelope_get_response(scc, data, sw)
|
data, sw = _envelope_get_response(scc, data, sw)
|
||||||
if handle_proactive and sw.startswith('91'):
|
if handle_proactive and sw.startswith('91'):
|
||||||
|
# 91xx is the CAT success state (a proactive command is pending), not
|
||||||
|
# an error: run the chain, then report the exchange as successful.
|
||||||
|
# The GET RESPONSE above may have delivered the response packet (the
|
||||||
|
# PoR) in the very same answer - keep those bytes. The old
|
||||||
|
# `data, sw = '', '9000'` dropped a delivered PoR whenever the card
|
||||||
|
# signalled a proactive command at the same time (live 2026-10-14: a
|
||||||
|
# DELETE answered 6113, the GET RESPONSE delivered the PoR with 9130
|
||||||
|
# and the operation reported 'no PoR' although the card returned one).
|
||||||
_handle_proactive_chain(scc, sw, _capture_sms_tpdu)
|
_handle_proactive_chain(scc, sw, _capture_sms_tpdu)
|
||||||
data, sw = '', '9000'
|
sw = '9000'
|
||||||
# Late-PoR fallback: only after the last segment of a packet (a
|
# Late-PoR fallback: only after the last segment of a packet (a
|
||||||
# concatenated download cannot have produced its PoR before the card got
|
# concatenated download cannot have produced its PoR before the card got
|
||||||
# every part, and polling mid-packet made spurious STATUS exchanges).
|
# every part, and polling mid-packet made spurious STATUS exchanges).
|
||||||
|
|||||||
@@ -512,6 +512,23 @@ class TestEnvelopeGetResponse(unittest.TestCase):
|
|||||||
self.assertEqual(scc._tp.sent[1], '00c0000000')
|
self.assertEqual(scc._tp.sent[1], '00c0000000')
|
||||||
self.assertEqual((data, sw), ('AABB', '9000'))
|
self.assertEqual((data, sw), ('AABB', '9000'))
|
||||||
|
|
||||||
|
def test_a_por_delivered_with_a_91xx_answer_survives_the_chain(self):
|
||||||
|
# v3.28.6: 91xx is the CAT success state (a proactive command is
|
||||||
|
# pending), not an error - and the GET RESPONSE may deliver the
|
||||||
|
# response packet (the PoR) in the very same answer. The chain runs;
|
||||||
|
# the delivered bytes must reach the caller (the old branch cleared
|
||||||
|
# them: live 2026-10-14, a DELETE answered 6113, the GET RESPONSE
|
||||||
|
# delivered the PoR with 9130 and the operation reported no PoR).
|
||||||
|
import pysim_simple_server.server as srv
|
||||||
|
por = '027100000e0a00000000000000140000016101'
|
||||||
|
scc = self._scc([('', '6113'), (por, '9130')])
|
||||||
|
with mock.patch.object(srv, '_handle_proactive_chain') as chain:
|
||||||
|
data, sw = srv._send_envelope('00', scc, handle_proactive=True)
|
||||||
|
self.assertEqual(scc._tp.sent[1], '00c0000013')
|
||||||
|
self.assertEqual((data, sw), (por, '9000'))
|
||||||
|
self.assertTrue(chain.called)
|
||||||
|
self.assertEqual(chain.call_args[0][1], '9130')
|
||||||
|
|
||||||
|
|
||||||
class TestDecodePor(unittest.TestCase):
|
class TestDecodePor(unittest.TestCase):
|
||||||
def test_plaintext_no_cc_synthetic(self):
|
def test_plaintext_no_cc_synthetic(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user