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