<p>dexter <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/pysim/+/15432">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
daniel: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add support for automatic card handling<br><br>When using the batch mode of pySim-prog, the user has to insert/remove<br>the cards from the cardreader manually. This is fine for small batches,<br>but for high volume batches this method is not applicable.<br><br>This patch adds support for the integration of an automatic card handler<br>machine. The user can freely configure a custom commandline that is<br>executed when a card should be inserted or moved to a good/bad<br>collection bin.<br><br>Change-Id: Icfed3cad7927b92816723d75603b78e1a4b87ef1<br>Related: SYS#4654<br>---<br>M contrib/jenkins.sh<br>M pySim-prog.py<br>A pySim/card_handler.py<br>3 files changed, 213 insertions(+), 77 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh</span><br><span>index fdcd0cb..a70f139 100755</span><br><span>--- a/contrib/jenkins.sh</span><br><span>+++ b/contrib/jenkins.sh</span><br><span>@@ -12,6 +12,7 @@</span><br><span> virtualenv -p python2 venv --system-site-packages</span><br><span> . venv/bin/activate</span><br><span> pip install pytlv</span><br><span style="color: hsl(120, 100%, 40%);">+pip install pyyaml</span><br><span> </span><br><span> cd pysim-testdata</span><br><span> ../tests/pysim-test.sh</span><br><span>diff --git a/pySim-prog.py b/pySim-prog.py</span><br><span>index 13e8bb5..55634a5 100755</span><br><span>--- a/pySim-prog.py</span><br><span>+++ b/pySim-prog.py</span><br><span>@@ -30,6 +30,7 @@</span><br><span> import random</span><br><span> import re</span><br><span> import sys</span><br><span style="color: hsl(120, 100%, 40%);">+import traceback</span><br><span> </span><br><span> try:</span><br><span> import json</span><br><span>@@ -41,6 +42,7 @@</span><br><span> from pySim.cards import _cards_classes</span><br><span> from pySim.utils import h2b, swap_nibbles, rpad, derive_milenage_opc, calculate_luhn, dec_iccid</span><br><span> from pySim.ts_51_011 import EF</span><br><span style="color: hsl(120, 100%, 40%);">+from pySim.card_handler import *</span><br><span> </span><br><span> def parse_options():</span><br><span> </span><br><span>@@ -163,6 +165,9 @@</span><br><span> help="Perform a 'dry run', don't actually program the card",</span><br><span> default=False, action="store_true")</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ parser.add_option("--card_handler", dest="card_handler", metavar="FILE",</span><br><span style="color: hsl(120, 100%, 40%);">+ help="Use automatic card handling machine")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> (options, args) = parser.parse_args()</span><br><span> </span><br><span> if options.type == 'list':</span><br><span>@@ -610,6 +615,74 @@</span><br><span> return card</span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+def process_card(opts, first, card_handler):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.dry_run is False:</span><br><span style="color: hsl(120, 100%, 40%);">+ # Connect transport</span><br><span style="color: hsl(120, 100%, 40%);">+ card_handler.get(first)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.dry_run is False:</span><br><span style="color: hsl(120, 100%, 40%);">+ # Get card</span><br><span style="color: hsl(120, 100%, 40%);">+ card = card_detect(opts, scc)</span><br><span style="color: hsl(120, 100%, 40%);">+ if card is None:</span><br><span style="color: hsl(120, 100%, 40%);">+ print "No card detected!"</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ # Probe only</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.probe:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ # Erase if requested</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.erase:</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Formatting ..."</span><br><span style="color: hsl(120, 100%, 40%);">+ card.erase()</span><br><span style="color: hsl(120, 100%, 40%);">+ card.reset()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ # Generate parameters</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.source == 'cmdline':</span><br><span style="color: hsl(120, 100%, 40%);">+ cp = gen_parameters(opts)</span><br><span style="color: hsl(120, 100%, 40%);">+ elif opts.source == 'csv':</span><br><span style="color: hsl(120, 100%, 40%);">+ imsi = None</span><br><span style="color: hsl(120, 100%, 40%);">+ iccid = None</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.read_iccid:</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.dry_run:</span><br><span style="color: hsl(120, 100%, 40%);">+ # Connect transport</span><br><span style="color: hsl(120, 100%, 40%);">+ card_handler.get(false)</span><br><span style="color: hsl(120, 100%, 40%);">+ (res,_) = scc.read_binary(['3f00', '2fe2'], length=10)</span><br><span style="color: hsl(120, 100%, 40%);">+ iccid = dec_iccid(res)</span><br><span style="color: hsl(120, 100%, 40%);">+ elif opts.read_imsi:</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.dry_run:</span><br><span style="color: hsl(120, 100%, 40%);">+ # Connect transport</span><br><span style="color: hsl(120, 100%, 40%);">+ card_handler.get(false)</span><br><span style="color: hsl(120, 100%, 40%);">+ (res,_) = scc.read_binary(EF['IMSI'])</span><br><span style="color: hsl(120, 100%, 40%);">+ imsi = swap_nibbles(res)[3:]</span><br><span style="color: hsl(120, 100%, 40%);">+ else:</span><br><span style="color: hsl(120, 100%, 40%);">+ imsi = opts.imsi</span><br><span style="color: hsl(120, 100%, 40%);">+ cp = read_params_csv(opts, imsi=imsi, iccid=iccid)</span><br><span style="color: hsl(120, 100%, 40%);">+ if cp is None:</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Error reading parameters\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ return 2</span><br><span style="color: hsl(120, 100%, 40%);">+ print_parameters(cp)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.dry_run is False:</span><br><span style="color: hsl(120, 100%, 40%);">+ # Program the card</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Programming ..."</span><br><span style="color: hsl(120, 100%, 40%);">+ card.program(cp)</span><br><span style="color: hsl(120, 100%, 40%);">+ else:</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Dry Run: NOT PROGRAMMING!"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ # Write parameters permanently</span><br><span style="color: hsl(120, 100%, 40%);">+ write_parameters(opts, cp)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ # Batch mode state update and save</span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.num is not None:</span><br><span style="color: hsl(120, 100%, 40%);">+ opts.num += 1</span><br><span style="color: hsl(120, 100%, 40%);">+ save_batch(opts)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ card_handler.done()</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if __name__ == '__main__':</span><br><span> </span><br><span> # Parse options</span><br><span>@@ -638,88 +711,42 @@</span><br><span> # Batch mode init</span><br><span> init_batch(opts)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if opts.card_handler:</span><br><span style="color: hsl(120, 100%, 40%);">+ card_handler = card_handler_auto(sl, opts.card_handler)</span><br><span style="color: hsl(120, 100%, 40%);">+ else:</span><br><span style="color: hsl(120, 100%, 40%);">+ card_handler = card_handler(sl)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> # Iterate</span><br><span style="color: hsl(0, 100%, 40%);">- done = False</span><br><span> first = True</span><br><span> card = None</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- while not done:</span><br><span style="color: hsl(120, 100%, 40%);">+ while 1:</span><br><span style="color: hsl(120, 100%, 40%);">+ try:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = process_card(opts, first, card_handler)</span><br><span style="color: hsl(120, 100%, 40%);">+ except (KeyboardInterrupt):</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Terminated by user!"</span><br><span style="color: hsl(120, 100%, 40%);">+ sys.exit(0)</span><br><span style="color: hsl(120, 100%, 40%);">+ except (SystemExit):</span><br><span style="color: hsl(120, 100%, 40%);">+ raise</span><br><span style="color: hsl(120, 100%, 40%);">+ except:</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Card programming failed with an execption:"</span><br><span style="color: hsl(120, 100%, 40%);">+ print "---------------------8<---------------------"</span><br><span style="color: hsl(120, 100%, 40%);">+ traceback.print_exc()</span><br><span style="color: hsl(120, 100%, 40%);">+ print "---------------------8<---------------------"</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = -1</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if opts.dry_run is False:</span><br><span style="color: hsl(0, 100%, 40%);">- # Connect transport</span><br><span style="color: hsl(0, 100%, 40%);">- print "Insert card now (or CTRL-C to cancel)"</span><br><span style="color: hsl(0, 100%, 40%);">- sl.wait_for_card(newcardonly=not first)</span><br><span style="color: hsl(120, 100%, 40%);">+ # Something did not work as well as expected, however, lets</span><br><span style="color: hsl(120, 100%, 40%);">+ # make sure the card is pulled from the reader.</span><br><span style="color: hsl(120, 100%, 40%);">+ if rc != 0:</span><br><span style="color: hsl(120, 100%, 40%);">+ card_handler.error()</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- # Not the first anymore !</span><br><span style="color: hsl(120, 100%, 40%);">+ # If we are not in batch mode we are done in any case, so lets</span><br><span style="color: hsl(120, 100%, 40%);">+ # exit here.</span><br><span style="color: hsl(120, 100%, 40%);">+ if not opts.batch_mode:</span><br><span style="color: hsl(120, 100%, 40%);">+ sys.exit(rc)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> first = False</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if opts.dry_run is False:</span><br><span style="color: hsl(0, 100%, 40%);">- # Get card</span><br><span style="color: hsl(0, 100%, 40%);">- card = card_detect(opts, scc)</span><br><span style="color: hsl(0, 100%, 40%);">- if card is None:</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.batch_mode:</span><br><span style="color: hsl(0, 100%, 40%);">- first = False</span><br><span style="color: hsl(0, 100%, 40%);">- continue</span><br><span style="color: hsl(0, 100%, 40%);">- else:</span><br><span style="color: hsl(0, 100%, 40%);">- sys.exit(-1)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- # Probe only</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.probe:</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- # Erase if requested</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.erase:</span><br><span style="color: hsl(0, 100%, 40%);">- print "Formatting ..."</span><br><span style="color: hsl(0, 100%, 40%);">- card.erase()</span><br><span style="color: hsl(0, 100%, 40%);">- card.reset()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- # Generate parameters</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.source == 'cmdline':</span><br><span style="color: hsl(0, 100%, 40%);">- cp = gen_parameters(opts)</span><br><span style="color: hsl(0, 100%, 40%);">- elif opts.source == 'csv':</span><br><span style="color: hsl(0, 100%, 40%);">- imsi = None</span><br><span style="color: hsl(0, 100%, 40%);">- iccid = None</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.read_iccid:</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.dry_run:</span><br><span style="color: hsl(0, 100%, 40%);">- # Connect transport</span><br><span style="color: hsl(0, 100%, 40%);">- print "Insert card now (or CTRL-C to cancel)"</span><br><span style="color: hsl(0, 100%, 40%);">- sl.wait_for_card(newcardonly=not first)</span><br><span style="color: hsl(0, 100%, 40%);">- (res,_) = scc.read_binary(['3f00', '2fe2'], length=10)</span><br><span style="color: hsl(0, 100%, 40%);">- iccid = dec_iccid(res)</span><br><span style="color: hsl(0, 100%, 40%);">- print iccid</span><br><span style="color: hsl(0, 100%, 40%);">- elif opts.read_imsi:</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.dry_run:</span><br><span style="color: hsl(0, 100%, 40%);">- # Connect transport</span><br><span style="color: hsl(0, 100%, 40%);">- print "Insert card now (or CTRL-C to cancel)"</span><br><span style="color: hsl(0, 100%, 40%);">- sl.wait_for_card(newcardonly=not first)</span><br><span style="color: hsl(0, 100%, 40%);">- (res,_) = scc.read_binary(EF['IMSI'])</span><br><span style="color: hsl(0, 100%, 40%);">- imsi = swap_nibbles(res)[3:]</span><br><span style="color: hsl(0, 100%, 40%);">- else:</span><br><span style="color: hsl(0, 100%, 40%);">- imsi = opts.imsi</span><br><span style="color: hsl(0, 100%, 40%);">- cp = read_params_csv(opts, imsi=imsi, iccid=iccid)</span><br><span style="color: hsl(0, 100%, 40%);">- if cp is None:</span><br><span style="color: hsl(0, 100%, 40%);">- print "Error reading parameters\n"</span><br><span style="color: hsl(0, 100%, 40%);">- sys.exit(2)</span><br><span style="color: hsl(0, 100%, 40%);">- print_parameters(cp)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.dry_run is False:</span><br><span style="color: hsl(0, 100%, 40%);">- # Program the card</span><br><span style="color: hsl(0, 100%, 40%);">- print "Programming ..."</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.dry_run is not True:</span><br><span style="color: hsl(0, 100%, 40%);">- card.program(cp)</span><br><span style="color: hsl(0, 100%, 40%);">- else:</span><br><span style="color: hsl(0, 100%, 40%);">- print "Dry Run: NOT PROGRAMMING!"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- # Write parameters permanently</span><br><span style="color: hsl(0, 100%, 40%);">- write_parameters(opts, cp)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- # Batch mode state update and save</span><br><span style="color: hsl(0, 100%, 40%);">- if opts.num is not None:</span><br><span style="color: hsl(0, 100%, 40%);">- opts.num += 1</span><br><span style="color: hsl(0, 100%, 40%);">- save_batch(opts)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- # Done for this card and maybe for everything ?</span><br><span style="color: hsl(0, 100%, 40%);">- print "Done !\n"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if not opts.batch_mode:</span><br><span style="color: hsl(0, 100%, 40%);">- done = True</span><br><span>diff --git a/pySim/card_handler.py b/pySim/card_handler.py</span><br><span>new file mode 100644</span><br><span>index 0000000..46ec93e</span><br><span>--- /dev/null</span><br><span>+++ b/pySim/card_handler.py</span><br><span>@@ -0,0 +1,108 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#!/usr/bin/env python2</span><br><span style="color: hsl(120, 100%, 40%);">+# -*- coding: utf-8 -*-</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+""" pySim: card handler utilities</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# (C) 2019 by Sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+# All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# This program is free software: you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+# it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+# the Free Software Foundation, either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+# (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+# but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+# GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+# along with this program. If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import subprocess</span><br><span style="color: hsl(120, 100%, 40%);">+import sys</span><br><span style="color: hsl(120, 100%, 40%);">+import yaml</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# Manual card handler: User is prompted to insert/remove card from the reader.</span><br><span style="color: hsl(120, 100%, 40%);">+class card_handler:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sl = None</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def __init__(self, sl):</span><br><span style="color: hsl(120, 100%, 40%);">+ self.sl = sl</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def get(self, first = False):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Ready for Programming: Insert card now (or CTRL-C to cancel)"</span><br><span style="color: hsl(120, 100%, 40%);">+ self.sl.wait_for_card(newcardonly=not first)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def error(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Programming failed: Remove card from reader"</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def done(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Programming successful: Remove card from reader"</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# Automatic card handler: A machine is used to handle the cards.</span><br><span style="color: hsl(120, 100%, 40%);">+class card_handler_auto:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sl = None</span><br><span style="color: hsl(120, 100%, 40%);">+ cmds = None</span><br><span style="color: hsl(120, 100%, 40%);">+ verbose = True</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def __init__(self, sl, config_file):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Card handler Config-file: " + str(config_file)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.sl = sl</span><br><span style="color: hsl(120, 100%, 40%);">+ with open(config_file) as cfg:</span><br><span style="color: hsl(120, 100%, 40%);">+ self.cmds = yaml.load(cfg, Loader=yaml.FullLoader)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ self.verbose = (self.cmds.get('verbose') == True)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def __print_outout(self,out):</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Card handler output:"</span><br><span style="color: hsl(120, 100%, 40%);">+ print "---------------------8<---------------------"</span><br><span style="color: hsl(120, 100%, 40%);">+ stdout = out[0].strip()</span><br><span style="color: hsl(120, 100%, 40%);">+ if len(stdout) > 0:</span><br><span style="color: hsl(120, 100%, 40%);">+ print "stdout:"</span><br><span style="color: hsl(120, 100%, 40%);">+ print stdout</span><br><span style="color: hsl(120, 100%, 40%);">+ stderr = out[1].strip()</span><br><span style="color: hsl(120, 100%, 40%);">+ if len(stderr) > 0:</span><br><span style="color: hsl(120, 100%, 40%);">+ print "stderr:"</span><br><span style="color: hsl(120, 100%, 40%);">+ print stderr</span><br><span style="color: hsl(120, 100%, 40%);">+ print "---------------------8<---------------------"</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def __exec_cmd(self, command):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Card handler Commandline: " + str(command)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ proc = subprocess.Popen([command], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)</span><br><span style="color: hsl(120, 100%, 40%);">+ out = proc.communicate()</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = proc.returncode</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if rc != 0 or self.verbose:</span><br><span style="color: hsl(120, 100%, 40%);">+ self.__print_outout(out)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if rc != 0:</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Error: Card handler failure! (rc=" + str(rc) + ")"</span><br><span style="color: hsl(120, 100%, 40%);">+ sys.exit(rc)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def get(self, first = False):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Ready for Programming: Transporting card into the reader-bay..."</span><br><span style="color: hsl(120, 100%, 40%);">+ self.__exec_cmd(self.cmds['get'])</span><br><span style="color: hsl(120, 100%, 40%);">+ self.sl.connect()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def error(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Programming failed: Transporting card to the error-bin..."</span><br><span style="color: hsl(120, 100%, 40%);">+ self.__exec_cmd(self.cmds['error'])</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def done(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ print "Programming successful: Transporting card into the collector bin..."</span><br><span style="color: hsl(120, 100%, 40%);">+ self.__exec_cmd(self.cmds['done'])</span><br><span style="color: hsl(120, 100%, 40%);">+ print ""</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/pysim/+/15432">change 15432</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/pysim/+/15432"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: pysim </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Icfed3cad7927b92816723d75603b78e1a4b87ef1 </div>
<div style="display:none"> Gerrit-Change-Number: 15432 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>