Change in ...pysim[master]: Add support for automatic card handling

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/.

dexter gerrit-no-reply at lists.osmocom.org
Fri Sep 13 08:13:57 UTC 2019


dexter has submitted this change and it was merged. ( https://gerrit.osmocom.org/c/pysim/+/15432 )

Change subject: Add support for automatic card handling
......................................................................

Add support for automatic card handling

When using the batch mode of pySim-prog, the user has to insert/remove
the cards from the cardreader manually. This is fine for small batches,
but for high volume batches this method is not applicable.

This patch adds support for the integration of an automatic card handler
machine. The user can freely configure a custom commandline that is
executed when a card should be inserted or moved to a good/bad
collection bin.

Change-Id: Icfed3cad7927b92816723d75603b78e1a4b87ef1
Related: SYS#4654
---
M contrib/jenkins.sh
M pySim-prog.py
A pySim/card_handler.py
3 files changed, 213 insertions(+), 77 deletions(-)

Approvals:
  Jenkins Builder: Verified
  daniel: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved



diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh
index fdcd0cb..a70f139 100755
--- a/contrib/jenkins.sh
+++ b/contrib/jenkins.sh
@@ -12,6 +12,7 @@
 virtualenv -p python2 venv --system-site-packages
 . venv/bin/activate
 pip install pytlv
+pip install pyyaml
 
 cd pysim-testdata
 ../tests/pysim-test.sh
diff --git a/pySim-prog.py b/pySim-prog.py
index 13e8bb5..55634a5 100755
--- a/pySim-prog.py
+++ b/pySim-prog.py
@@ -30,6 +30,7 @@
 import random
 import re
 import sys
+import traceback
 
 try:
 	import json
@@ -41,6 +42,7 @@
 from pySim.cards import _cards_classes
 from pySim.utils import h2b, swap_nibbles, rpad, derive_milenage_opc, calculate_luhn, dec_iccid
 from pySim.ts_51_011 import EF
+from pySim.card_handler import *
 
 def parse_options():
 
@@ -163,6 +165,9 @@
 			help="Perform a 'dry run', don't actually program the card",
 			default=False, action="store_true")
 
+	parser.add_option("--card_handler", dest="card_handler", metavar="FILE",
+			help="Use automatic card handling machine")
+
 	(options, args) = parser.parse_args()
 
 	if options.type == 'list':
@@ -610,6 +615,74 @@
 	return card
 
 
+def process_card(opts, first, card_handler):
+
+	if opts.dry_run is False:
+		# Connect transport
+		card_handler.get(first)
+
+	if opts.dry_run is False:
+		# Get card
+		card = card_detect(opts, scc)
+		if card is None:
+			print "No card detected!"
+			return -1
+
+		# Probe only
+		if opts.probe:
+			return 0
+
+		# Erase if requested
+		if opts.erase:
+			print "Formatting ..."
+			card.erase()
+			card.reset()
+
+	# Generate parameters
+	if opts.source == 'cmdline':
+		cp = gen_parameters(opts)
+	elif opts.source == 'csv':
+		imsi = None
+		iccid = None
+		if opts.read_iccid:
+			if opts.dry_run:
+				# Connect transport
+				card_handler.get(false)
+			(res,_) = scc.read_binary(['3f00', '2fe2'], length=10)
+			iccid = dec_iccid(res)
+		elif opts.read_imsi:
+			if opts.dry_run:
+				# Connect transport
+				card_handler.get(false)
+			(res,_) = scc.read_binary(EF['IMSI'])
+			imsi = swap_nibbles(res)[3:]
+		else:
+			imsi = opts.imsi
+		cp = read_params_csv(opts, imsi=imsi, iccid=iccid)
+	if cp is None:
+		print "Error reading parameters\n"
+		return 2
+	print_parameters(cp)
+
+	if opts.dry_run is False:
+		# Program the card
+		print "Programming ..."
+		card.program(cp)
+	else:
+		print "Dry Run: NOT PROGRAMMING!"
+
+	# Write parameters permanently
+	write_parameters(opts, cp)
+
+	# Batch mode state update and save
+	if opts.num is not None:
+		opts.num += 1
+	save_batch(opts)
+
+	card_handler.done()
+	return 0
+
+
 if __name__ == '__main__':
 
 	# Parse options
@@ -638,88 +711,42 @@
 	# Batch mode init
 	init_batch(opts)
 
+	if opts.card_handler:
+		card_handler = card_handler_auto(sl, opts.card_handler)
+        else:
+		card_handler = card_handler(sl)
+
 	# Iterate
-	done = False
 	first = True
 	card = None
 
-	while not done:
+	while 1:
+		try:
+			rc = process_card(opts, first, card_handler)
+		except (KeyboardInterrupt):
+			print ""
+			print "Terminated by user!"
+			sys.exit(0)
+		except (SystemExit):
+			raise
+		except:
+			print ""
+			print "Card programming failed with an execption:"
+			print "---------------------8<---------------------"
+			traceback.print_exc()
+			print "---------------------8<---------------------"
+			print ""
+			rc = -1
 
-		if opts.dry_run is False:
-			# Connect transport
-			print "Insert card now (or CTRL-C to cancel)"
-			sl.wait_for_card(newcardonly=not first)
+		# Something did not work as well as expected, however, lets
+		# make sure the card is pulled from the reader.
+		if rc != 0:
+			card_handler.error()
 
-		# Not the first anymore !
+		# If we are not in batch mode we are done in any case, so lets
+		# exit here.
+		if not opts.batch_mode:
+			sys.exit(rc)
+
 		first = False
 
-		if opts.dry_run is False:
-			# Get card
-			card = card_detect(opts, scc)
-			if card is None:
-				if opts.batch_mode:
-					first = False
-					continue
-				else:
-					sys.exit(-1)
-
-                        # Probe only
-                        if opts.probe:
-                                break;
-
-			# Erase if requested
-			if opts.erase:
-				print "Formatting ..."
-				card.erase()
-				card.reset()
-
-		# Generate parameters
-		if opts.source == 'cmdline':
-			cp = gen_parameters(opts)
-		elif opts.source == 'csv':
-                        imsi = None
-                        iccid = None
-			if opts.read_iccid:
-				if opts.dry_run:
-					# Connect transport
-					print "Insert card now (or CTRL-C to cancel)"
-					sl.wait_for_card(newcardonly=not first)
-				(res,_) = scc.read_binary(['3f00', '2fe2'], length=10)
-				iccid = dec_iccid(res)
-                                print iccid
-                        elif opts.read_imsi:
-				if opts.dry_run:
-					# Connect transport
-					print "Insert card now (or CTRL-C to cancel)"
-					sl.wait_for_card(newcardonly=not first)
-				(res,_) = scc.read_binary(EF['IMSI'])
-				imsi = swap_nibbles(res)[3:]
-			else:
-				imsi = opts.imsi
-			cp = read_params_csv(opts, imsi=imsi, iccid=iccid)
-		if cp is None:
-			print "Error reading parameters\n"
-			sys.exit(2)
-		print_parameters(cp)
-
-		if opts.dry_run is False:
-			# Program the card
-			print "Programming ..."
-			if opts.dry_run is not True:
-				card.program(cp)
-		else:
-			print "Dry Run: NOT PROGRAMMING!"
-
-		# Write parameters permanently
-		write_parameters(opts, cp)
-
-		# Batch mode state update and save
-		if opts.num is not None:
-			opts.num += 1
-		save_batch(opts)
-
-		# Done for this card and maybe for everything ?
-		print "Done !\n"
-
-		if not opts.batch_mode:
-			done = True
diff --git a/pySim/card_handler.py b/pySim/card_handler.py
new file mode 100644
index 0000000..46ec93e
--- /dev/null
+++ b/pySim/card_handler.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+
+""" pySim: card handler utilities
+"""
+
+#
+# (C) 2019 by Sysmocom s.f.m.c. GmbH
+# All Rights Reserved
+#
+# 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/>.
+#
+
+
+import subprocess
+import sys
+import yaml
+
+# Manual card handler: User is prompted to insert/remove card from the reader.
+class card_handler:
+
+	sl = None
+
+	def __init__(self, sl):
+		self.sl = sl
+
+	def get(self, first = False):
+		print "Ready for Programming: Insert card now (or CTRL-C to cancel)"
+		self.sl.wait_for_card(newcardonly=not first)
+
+	def error(self):
+		print "Programming failed: Remove card from reader"
+		print ""
+
+	def done(self):
+		print "Programming successful: Remove card from reader"
+		print ""
+
+# Automatic card handler: A machine is used to handle the cards.
+class card_handler_auto:
+
+	sl = None
+	cmds = None
+	verbose = True
+
+	def __init__(self, sl, config_file):
+		print "Card handler Config-file: " + str(config_file)
+		self.sl = sl
+		with open(config_file) as cfg:
+			self.cmds = yaml.load(cfg, Loader=yaml.FullLoader)
+
+		self.verbose = (self.cmds.get('verbose') == True)
+
+	def __print_outout(self,out):
+		print ""
+		print "Card handler output:"
+		print "---------------------8<---------------------"
+		stdout = out[0].strip()
+		if len(stdout) > 0:
+			print "stdout:"
+			print stdout
+		stderr = out[1].strip()
+		if len(stderr) > 0:
+			print "stderr:"
+			print stderr
+		print "---------------------8<---------------------"
+		print ""
+
+	def __exec_cmd(self, command):
+		print "Card handler Commandline: " + str(command)
+
+		proc = subprocess.Popen([command], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+		out = proc.communicate()
+		rc = proc.returncode
+
+		if rc != 0 or self.verbose:
+			self.__print_outout(out)
+
+		if rc != 0:
+			print ""
+			print "Error: Card handler failure! (rc=" + str(rc) + ")"
+			sys.exit(rc)
+
+	def get(self, first = False):
+		print "Ready for Programming: Transporting card into the reader-bay..."
+		self.__exec_cmd(self.cmds['get'])
+		self.sl.connect()
+
+	def error(self):
+		print "Programming failed: Transporting card to the error-bin..."
+		self.__exec_cmd(self.cmds['error'])
+		print ""
+
+	def done(self):
+		print "Programming successful: Transporting card into the collector bin..."
+		self.__exec_cmd(self.cmds['done'])
+		print ""

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

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Icfed3cad7927b92816723d75603b78e1a4b87ef1
Gerrit-Change-Number: 15432
Gerrit-PatchSet: 4
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at gnumonks.org>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190913/943dcc6c/attachment.htm>


More information about the gerrit-log mailing list