JPM has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/38992?usp=email )
Change subject: Handling Long APDU response ......................................................................
Handling Long APDU response
Change-Id: I3c09d4dd1ed68bb982e23c90a6762fd9c2dfdd7f --- M pySim/transport/modem_atcmd.py 1 file changed, 22 insertions(+), 13 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/92/38992/1
diff --git a/pySim/transport/modem_atcmd.py b/pySim/transport/modem_atcmd.py index e7614c0..340ed92 100644 --- a/pySim/transport/modem_atcmd.py +++ b/pySim/transport/modem_atcmd.py @@ -86,6 +86,8 @@ if res == b'ERROR' or res.startswith(b'+CME ERROR:'): log.error('Command failed with result: %s', res) break + if lines[-1].startswith(b'+CSIM:'): # Sequans Monarch GM02S Long APDU response is OK and then all multiple +CSIM + t_start = time.time() # Reset the timer on each additional +CSIM received
if time.time() - t_start >= timeout: log.info('Command finished with timeout >= %ss', timeout) @@ -155,22 +157,29 @@
# Send AT+CSIM command to the modem rsp = self.send_at_cmd(cmd) - if rsp[-1].startswith(b'+CME ERROR:'): - raise ProtocolError('AT+CSIM failed with: %s' % str(rsp)) - if len(rsp) != 2 or rsp[-1] != b'OK': - raise ReaderError('APDU transfer failed: %s' % str(rsp)) - rsp = rsp[0] # Get rid of b'OK'
- # Make sure that the response has format: b'+CSIM: %d,"%s"' - try: - result = re.match(b'+CSIM: (\d+),"([0-9A-F]+)"', rsp) - (_rsp_tpdu_len, rsp_tpdu) = result.groups() - except Exception as exc: - raise ReaderError('Failed to parse response from modem: %s' % rsp) from exc + # AT+CSIM works with APDU, but returns the TPDU in multiple +CSIM answers (at least Sequans does it) + # In that case, the answer starts with OK, and then multiple +CSIM answers + rsp_apdu = b'' + for r in rsp: + if r.startswith(b'+CSIM:'): + try: + result = re.match(b'+CSIM: (\d+),"([0-9A-F]+)"', r) + (_rsp_tpdu_len, _rsp_tpdu) = result.groups() + rsp_apdu = rsp_apdu + _rsp_tpdu + except Exception as exc: + raise ReaderError('Failed to parse response from modem: %s' % rsp) from exc + elif r.startswith(b'CME ERROR:'): + raise ProtocolError('AT+CSIM failed with: %s' % str(rsp)) + elif r == b'OK': + continue + else: + raise ReaderError('APDU transfer failed: %s' % str(rsp)) +
# TODO: make sure we have at least SW - data = rsp_tpdu[:-4].decode().lower() - sw = rsp_tpdu[-4:].decode().lower() + data = rsp_apdu[:-4].decode().lower() + sw = rsp_apdu[-4:].decode().lower() log.debug('Command response: %s, %s', data, sw) return data, sw