pysim/pySim/card_handler.py

147 lines
4.5 KiB
Python
Raw Permalink Normal View History

# -*- coding: utf-8 -*-
""" 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.
"""
#
# (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
pylint: card_key_provider.py, card_handler.py, iso7816_4.py, jsonpath.py pySim/card_key_provider.py:57:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/card_key_provider.py:61:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/card_handler.py:100:0: C0325: Unnecessary parens after '=' keyword (superfluous-parens) pySim/card_handler.py:100:24: C0121: Comparison 'self.cmds.get('verbose') == True' should be 'self.cmds.get('verbose') is True' if checking for the singleton value True, or 'bool(self.cmds.get('verbose'))' if testing for truthiness (singleton-comparison) pySim/card_handler.py:29:0: C0411: standard import "import subprocess" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/card_handler.py:30:0: C0411: standard import "import sys" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/card_handler.py:31:0: C0411: third party import "import yaml" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/iso7816_4.py:20:0: W0401: Wildcard import construct (wildcard-import) pySim/jsonpath.py:1:0: C0114: Missing module docstring (missing-module-docstring) pySim/jsonpath.py:6:0: W0105: String statement has no effect (pointless-string-statement) pySim/jsonpath.py:2:0: W0611: Unused import json (unused-import) pySim/jsonpath.py:3:0: W0611: Unused import pprint (unused-import) Change-Id: I780595d69000f727ad0fbaff4b89918b91b3122e
2024-02-04 20:40:32 +00:00
from pySim.transport import LinkBase
class CardHandlerBase:
"""Abstract base class representing a mechanism for card insertion/removal."""
def __init__(self, sl: LinkBase):
self.sl = sl
def get(self, first: bool = False):
"""Method called when pySim needs a new card to be inserted.
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)
def error(self):
"""Method called when pySim failed to program a card. Move card to 'bad' batch."""
print("Programming failed: ", end='')
self._error()
def done(self):
"""Method called when pySim failed to program a card. Move card to 'good' batch."""
print("Programming successful: ", end='')
self._done()
def _get(self, first: bool = False):
pass
def _error(self):
pass
def _done(self):
pass
class CardHandler(CardHandlerBase):
"""Manual card handler: User is prompted to insert/remove card from the reader."""
def _get(self, first: bool = False):
print("Insert card now (or CTRL-C to cancel)")
self.sl.wait_for_card(newcardonly=not first)
def _error(self):
print("Remove card from reader")
print("")
def _done(self):
print("Remove card from reader")
print("")
class CardHandlerAuto(CardHandlerBase):
"""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)
pylint: card_key_provider.py, card_handler.py, iso7816_4.py, jsonpath.py pySim/card_key_provider.py:57:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/card_key_provider.py:61:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/card_handler.py:100:0: C0325: Unnecessary parens after '=' keyword (superfluous-parens) pySim/card_handler.py:100:24: C0121: Comparison 'self.cmds.get('verbose') == True' should be 'self.cmds.get('verbose') is True' if checking for the singleton value True, or 'bool(self.cmds.get('verbose'))' if testing for truthiness (singleton-comparison) pySim/card_handler.py:29:0: C0411: standard import "import subprocess" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/card_handler.py:30:0: C0411: standard import "import sys" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/card_handler.py:31:0: C0411: third party import "import yaml" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/iso7816_4.py:20:0: W0401: Wildcard import construct (wildcard-import) pySim/jsonpath.py:1:0: C0114: Missing module docstring (missing-module-docstring) pySim/jsonpath.py:6:0: W0105: String statement has no effect (pointless-string-statement) pySim/jsonpath.py:2:0: W0611: Unused import json (unused-import) pySim/jsonpath.py:3:0: W0611: Unused import pprint (unused-import) Change-Id: I780595d69000f727ad0fbaff4b89918b91b3122e
2024-02-04 20:40:32 +00:00
self.verbose = self.cmds.get('verbose') is 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("")