Change in pysim[master]: Implement Generic SIM Access interface as per 3GPP TS 27.007

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Wed Jun 3 06:25:44 UTC 2020


Vadim Yanitskiy has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/18159 )

Change subject: Implement Generic SIM Access interface as per 3GPP TS 27.007
......................................................................

Implement Generic SIM Access interface as per 3GPP TS 27.007

According to 3GPP TS 27.007, sections 8.17 and 8.18, the modem
may *optionally* provide Generic and/or Restricted SIM Access
to the TE (Terminal Equipment) by means of the AT commands.
This basically means that a modem can act as a card reader.

Generic SIM Access allows the TE to send raw PDUs in the format
as described in 3GPP TS 51.011 directly to the SIM card, while
Restricted SIM Access is more limited, and thus is not really
interesting to us.

This change implements a new transport called ModemATCommandLink,
so using it a SIM card can be read and/or programmed without the
need to remove it from the modem's socket. A downside of this
approach is relatively slow I/O speed compared to PC/SC readers.

Tested with Quectel EC20:

  $ ./pySim-read.py --modem-dev /dev/ttyUSB2

Change-Id: I20bc00315e2c7c298f46283852865c1416047bc6
Signed-off-by: Vadim Yanitskiy <axilirator at gmail.com>
---
M pySim-prog.py
M pySim-read.py
A pySim/transport/modem_atcmd.py
M pySim/utils.py
4 files changed, 146 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Vadim Yanitskiy: Verified
  herlesupreeth: Looks good to me, approved



diff --git a/pySim-prog.py b/pySim-prog.py
index f707c57..601f980 100755
--- a/pySim-prog.py
+++ b/pySim-prog.py
@@ -61,6 +61,14 @@
 			help="Which PC/SC reader number for SIM access",
 			default=None,
 		)
+	parser.add_option("--modem-device", dest="modem_dev", metavar="DEV",
+			help="Serial port of modem for Generic SIM Access (3GPP TS 27.007)",
+			default=None,
+		)
+	parser.add_option("--modem-baud", dest="modem_baud", type="int", metavar="BAUD",
+			help="Baudrate used for modem's port [default: %default]",
+			default=115200,
+		)
 	parser.add_option("--osmocon", dest="osmocon_sock", metavar="PATH",
 			help="Socket path for Calypso (e.g. Motorola C1XX) based reader (via OsmocomBB)",
 			default=None,
diff --git a/pySim-read.py b/pySim-read.py
index df21531..e49a907 100755
--- a/pySim-read.py
+++ b/pySim-read.py
@@ -53,6 +53,14 @@
 			help="Which PC/SC reader number for SIM access",
 			default=None,
 		)
+	parser.add_option("--modem-device", dest="modem_dev", metavar="DEV",
+			help="Serial port of modem for Generic SIM Access (3GPP TS 27.007)",
+			default=None,
+		)
+	parser.add_option("--modem-baud", dest="modem_baud", type="int", metavar="BAUD",
+			help="Baudrate used for modem's port [default: %default]",
+			default=115200,
+		)
 	parser.add_option("--osmocon", dest="osmocon_sock", metavar="PATH",
 			help="Socket path for Calypso (e.g. Motorola C1XX) based reader (via OsmocomBB)",
 			default=None,
diff --git a/pySim/transport/modem_atcmd.py b/pySim/transport/modem_atcmd.py
new file mode 100644
index 0000000..742ae8d
--- /dev/null
+++ b/pySim/transport/modem_atcmd.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+""" pySim: Transport Link for 3GPP TS 27.007 compliant modems
+"""
+
+# Copyright (C) 2020 Vadim Yanitskiy <axilirator at gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from __future__ import absolute_import
+
+import logging as log
+import serial
+import time
+import re
+
+from pySim.transport import LinkBase
+from pySim.exceptions import *
+
+# HACK: if somebody needs to debug this thing
+# log.root.setLevel(log.DEBUG)
+
+class ModemATCommandLink(LinkBase):
+	def __init__(self, device='/dev/ttyUSB0', baudrate=115200):
+		self._sl = serial.Serial(device, baudrate, timeout=5)
+		self._device = device
+		self._atr = None
+
+		# Trigger initial reset
+		self.reset_card()
+
+	def __del__(self):
+		self._sl.close()
+
+	def send_at_cmd(self, cmd):
+		# Convert from string to bytes, if needed
+		bcmd = cmd if type(cmd) is bytes else cmd.encode()
+		bcmd += b'\r'
+
+		# Send command to the modem
+		log.debug('Sending AT command: %s' % cmd)
+		try:
+			wlen = self._sl.write(bcmd)
+			assert(wlen == len(bcmd))
+		except:
+			raise ReaderError('Failed to send AT command: %s' % cmd)
+
+		# Give the modem some time...
+		time.sleep(0.3)
+
+		# Read the response
+		try:
+			# Skip characters sent back
+			self._sl.read(wlen)
+			# Read the rest
+			rsp = self._sl.read_all()
+
+			# Strip '\r\n'
+			rsp = rsp.strip()
+			# Split into a list
+			rsp = rsp.split(b'\r\n\r\n')
+		except:
+			raise ReaderError('Failed parse response to AT command: %s' % cmd)
+
+		log.debug('Got response from modem: %s' % rsp)
+		return rsp
+
+	def reset_card(self):
+		# Make sure that we can talk to the modem
+		if self.send_at_cmd('AT') != [b'OK']:
+			raise ReaderError('Failed to connect to modem')
+
+		# Reset the modem, just to be sure
+		if self.send_at_cmd('ATZ') != [b'OK']:
+			raise ReaderError('Failed to reset the modem')
+
+		# Make sure that generic SIM access is supported
+		if self.send_at_cmd('AT+CSIM=?') != [b'OK']:
+			raise ReaderError('The modem does not seem to support SIM access')
+
+		log.info('Modem at \'%s\' is ready!' % self._device)
+
+	def connect(self):
+		pass # Nothing to do really ...
+
+	def disconnect(self):
+		pass # Nothing to do really ...
+
+	def wait_for_card(self, timeout=None, newcardonly=False):
+		pass # Nothing to do really ...
+
+	def send_apdu_raw(self, pdu):
+		# Prepare the command as described in 8.17
+		cmd = 'AT+CSIM=%d,\"%s\"' % (len(pdu), pdu)
+
+		# Send AT+CSIM command to the modem
+		# TODO: also handle +CME ERROR: <err>
+		rsp = self.send_at_cmd(cmd)
+		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_pdu_len, rsp_pdu) = result.groups()
+		except:
+			raise ReaderError('Failed to parse response from modem: %s' % rsp)
+
+		# TODO: make sure we have at least SW
+		data = rsp_pdu[:-4].decode()
+		sw   = rsp_pdu[-4:].decode()
+		return data, sw
diff --git a/pySim/utils.py b/pySim/utils.py
index 20eb5a8..496b918 100644
--- a/pySim/utils.py
+++ b/pySim/utils.py
@@ -485,6 +485,10 @@
 		print("Using Calypso-based (OsmocomBB) reader interface")
 		from pySim.transport.calypso import CalypsoSimLink
 		sl = CalypsoSimLink(sock_path=opts.osmocon_sock)
+	elif opts.modem_dev is not None:
+		print("Using modem for Generic SIM Access (3GPP TS 27.007)")
+		from pySim.transport.modem_atcmd import ModemATCommandLink
+		sl = ModemATCommandLink(device=opts.modem_dev, baudrate=opts.modem_baud)
 	else: # Serial reader is default
 		print("Using serial reader interface")
 		from pySim.transport.serial import SerialSimLink

-- 
To view, visit https://gerrit.osmocom.org/c/pysim/+/18159
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I20bc00315e2c7c298f46283852865c1416047bc6
Gerrit-Change-Number: 18159
Gerrit-PatchSet: 6
Gerrit-Owner: Vadim Yanitskiy <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Vadim Yanitskiy <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: herlesupreeth <herlesupreeth at gmail.com>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-CC: guilly at gmail.com <guilly at gmail.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200603/72ba688d/attachment.htm>


More information about the gerrit-log mailing list