2019-08-30 09:41:02 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2021-10-11 08:55:00 +00:00
|
|
|
""" pySim: card handler utilities. A 'card handler' is some method
|
|
|
|
by which cards can be inserted/removed into the card reader. For
|
|
|
|
normal smart card readers, this has to be done manually. However,
|
|
|
|
there are also automatic card feeders.
|
2019-08-30 09:41:02 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
#
|
|
|
|
# (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/>.
|
|
|
|
#
|
|
|
|
|
2021-10-11 08:55:00 +00:00
|
|
|
from pySim.transport import LinkBase
|
2019-08-30 09:41:02 +00:00
|
|
|
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import yaml
|
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
|
2021-10-11 08:55:00 +00:00
|
|
|
class CardHandlerBase:
|
2022-02-10 17:05:45 +00:00
|
|
|
"""Abstract base class representing a mechanism for card insertion/removal."""
|
2019-08-30 09:41:02 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def __init__(self, sl: LinkBase):
|
|
|
|
self.sl = sl
|
2019-08-30 09:41:02 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def get(self, first: bool = False):
|
|
|
|
"""Method called when pySim needs a new card to be inserted.
|
2021-10-11 08:55:00 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
Args:
|
|
|
|
first : set to true when the get method is called the
|
|
|
|
first time. This is required to prevent blocking
|
|
|
|
when a card is already inserted into the reader.
|
|
|
|
The reader API would not recognize that card as
|
|
|
|
"new card" until it would be removed and re-inserted
|
|
|
|
again.
|
|
|
|
"""
|
|
|
|
print("Ready for Programming: ", end='')
|
|
|
|
self._get(first)
|
2019-08-30 09:41:02 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def error(self):
|
|
|
|
"""Method called when pySim failed to program a card. Move card to 'bad' batch."""
|
|
|
|
print("Programming failed: ", end='')
|
|
|
|
self._error()
|
2019-08-30 09:41:02 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def done(self):
|
|
|
|
"""Method called when pySim failed to program a card. Move card to 'good' batch."""
|
|
|
|
print("Programming successful: ", end='')
|
|
|
|
self._done()
|
2021-10-11 08:55:00 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def _get(self, first: bool = False):
|
|
|
|
pass
|
2021-10-11 08:55:00 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def _error(self):
|
|
|
|
pass
|
2021-10-11 08:55:00 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def _done(self):
|
|
|
|
pass
|
2021-10-11 08:55:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
class CardHandler(CardHandlerBase):
|
2022-02-10 17:05:45 +00:00
|
|
|
"""Manual card handler: User is prompted to insert/remove card from the reader."""
|
2021-10-11 08:55:00 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def _get(self, first: bool = False):
|
|
|
|
print("Insert card now (or CTRL-C to cancel)")
|
|
|
|
self.sl.wait_for_card(newcardonly=not first)
|
2021-10-11 08:55:00 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def _error(self):
|
|
|
|
print("Remove card from reader")
|
|
|
|
print("")
|
2019-08-30 09:41:02 +00:00
|
|
|
|
2022-02-10 17:05:45 +00:00
|
|
|
def _done(self):
|
|
|
|
print("Remove card from reader")
|
|
|
|
print("")
|
2021-10-11 08:55:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
class CardHandlerAuto(CardHandlerBase):
|
2022-02-10 17:05:45 +00:00
|
|
|
"""Automatic card handler: A machine is used to handle the cards."""
|
|
|
|
|
|
|
|
verbose = True
|
|
|
|
|
|
|
|
def __init__(self, sl: LinkBase, config_file: str):
|
|
|
|
super().__init__(sl)
|
|
|
|
print("Card handler Config-file: " + str(config_file))
|
|
|
|
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: bool = False):
|
|
|
|
print("Transporting card into the reader-bay...")
|
|
|
|
self.__exec_cmd(self.cmds['get'])
|
|
|
|
if self.sl:
|
|
|
|
self.sl.connect()
|
|
|
|
|
|
|
|
def _error(self):
|
|
|
|
print("Transporting card to the error-bin...")
|
|
|
|
self.__exec_cmd(self.cmds['error'])
|
|
|
|
print("")
|
|
|
|
|
|
|
|
def _done(self):
|
|
|
|
print("Transporting card into the collector bin...")
|
|
|
|
self.__exec_cmd(self.cmds['done'])
|
|
|
|
print("")
|