blob: 0425e33be2ad15ef173d9ce6f62c957e293f2c3e [file] [log] [blame]
Philipp Maierc5b422e2019-08-30 11:41:02 +02001# -*- coding: utf-8 -*-
2
Harald Welte913e6162021-10-11 10:55:00 +02003""" pySim: card handler utilities. A 'card handler' is some method
4by which cards can be inserted/removed into the card reader. For
5normal smart card readers, this has to be done manually. However,
6there are also automatic card feeders.
Philipp Maierc5b422e2019-08-30 11:41:02 +02007"""
8
9#
10# (C) 2019 by Sysmocom s.f.m.c. GmbH
11# All Rights Reserved
12#
13# This program is free software: you can redistribute it and/or modify
14# it under the terms of the GNU General Public License as published by
15# the Free Software Foundation, either version 2 of the License, or
16# (at your option) any later version.
17#
18# This program is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21# GNU General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program. If not, see <http://www.gnu.org/licenses/>.
25#
26
Harald Welte913e6162021-10-11 10:55:00 +020027from pySim.transport import LinkBase
Philipp Maierc5b422e2019-08-30 11:41:02 +020028
29import subprocess
30import sys
31import yaml
32
Harald Welte913e6162021-10-11 10:55:00 +020033class CardHandlerBase:
34 """Abstract base class representing a mechanism for card insertion/removal."""
Philipp Maierc5b422e2019-08-30 11:41:02 +020035
Harald Welte913e6162021-10-11 10:55:00 +020036 def __init__(self, sl:LinkBase):
Philipp Maierc5b422e2019-08-30 11:41:02 +020037 self.sl = sl
38
Harald Welte913e6162021-10-11 10:55:00 +020039 def get(self, first:bool = False):
40 """Method called when pySim needs a new card to be inserted.
41
42 Args:
43 first : set to true when the get method is called the
44 first time. This is required to prevent blocking
45 when a card is already inserted into the reader.
46 The reader API would not recognize that card as
47 "new card" until it would be removed and re-inserted
48 again.
49 """
50 print("Ready for Programming: ", end='')
51 self._get(first)
Philipp Maierc5b422e2019-08-30 11:41:02 +020052
53 def error(self):
Harald Welte913e6162021-10-11 10:55:00 +020054 """Method called when pySim failed to program a card. Move card to 'bad' batch."""
55 print("Programming failed: ", end='')
56 self._error()
Philipp Maierc5b422e2019-08-30 11:41:02 +020057
58 def done(self):
Harald Welte913e6162021-10-11 10:55:00 +020059 """Method called when pySim failed to program a card. Move card to 'good' batch."""
60 print("Programming successful: ", end='')
61 self._done()
62
63 def _get(self, first:bool = False):
64 pass
65
66 def _error(self):
67 pass
68
69 def _done(self):
70 pass
71
72
73class CardHandler(CardHandlerBase):
74 """Manual card handler: User is prompted to insert/remove card from the reader."""
75
76 def _get(self, first:bool = False):
77 print("Insert card now (or CTRL-C to cancel)")
78 self.sl.wait_for_card(newcardonly=not first)
79
80 def _error(self):
81 print("Remove card from reader")
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +070082 print("")
Philipp Maierc5b422e2019-08-30 11:41:02 +020083
Harald Welte913e6162021-10-11 10:55:00 +020084 def _done(self):
85 print("Remove card from reader")
86 print("")
Philipp Maierc5b422e2019-08-30 11:41:02 +020087
Harald Welte913e6162021-10-11 10:55:00 +020088
89class CardHandlerAuto(CardHandlerBase):
90 """Automatic card handler: A machine is used to handle the cards."""
91
Philipp Maierc5b422e2019-08-30 11:41:02 +020092 verbose = True
93
Harald Welte913e6162021-10-11 10:55:00 +020094 def __init__(self, sl:LinkBase, config_file:str):
95 super().__init__(sl)
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +070096 print("Card handler Config-file: " + str(config_file))
Philipp Maierc5b422e2019-08-30 11:41:02 +020097 with open(config_file) as cfg:
98 self.cmds = yaml.load(cfg, Loader=yaml.FullLoader)
Philipp Maierc5b422e2019-08-30 11:41:02 +020099 self.verbose = (self.cmds.get('verbose') == True)
100
Harald Welte913e6162021-10-11 10:55:00 +0200101 def __print_outout(self, out):
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700102 print("")
103 print("Card handler output:")
104 print("---------------------8<---------------------")
Philipp Maierc5b422e2019-08-30 11:41:02 +0200105 stdout = out[0].strip()
106 if len(stdout) > 0:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700107 print("stdout:")
108 print(stdout)
Philipp Maierc5b422e2019-08-30 11:41:02 +0200109 stderr = out[1].strip()
110 if len(stderr) > 0:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700111 print("stderr:")
112 print(stderr)
113 print("---------------------8<---------------------")
114 print("")
Philipp Maierc5b422e2019-08-30 11:41:02 +0200115
116 def __exec_cmd(self, command):
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700117 print("Card handler Commandline: " + str(command))
Philipp Maierc5b422e2019-08-30 11:41:02 +0200118
119 proc = subprocess.Popen([command], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
120 out = proc.communicate()
121 rc = proc.returncode
122
123 if rc != 0 or self.verbose:
124 self.__print_outout(out)
125
126 if rc != 0:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700127 print("")
128 print("Error: Card handler failure! (rc=" + str(rc) + ")")
Philipp Maierc5b422e2019-08-30 11:41:02 +0200129 sys.exit(rc)
130
Harald Welte913e6162021-10-11 10:55:00 +0200131 def _get(self, first:bool = False):
132 print("Transporting card into the reader-bay...")
Philipp Maierc5b422e2019-08-30 11:41:02 +0200133 self.__exec_cmd(self.cmds['get'])
Philipp Maier48e1b902021-09-17 13:22:32 +0200134 if self.sl:
135 self.sl.connect()
Philipp Maierc5b422e2019-08-30 11:41:02 +0200136
Harald Welte913e6162021-10-11 10:55:00 +0200137 def _error(self):
138 print("Transporting card to the error-bin...")
Philipp Maierc5b422e2019-08-30 11:41:02 +0200139 self.__exec_cmd(self.cmds['error'])
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700140 print("")
Philipp Maierc5b422e2019-08-30 11:41:02 +0200141
Harald Welte913e6162021-10-11 10:55:00 +0200142 def _done(self):
143 print("Transporting card into the collector bin...")
Philipp Maierc5b422e2019-08-30 11:41:02 +0200144 self.__exec_cmd(self.cmds['done'])
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700145 print("")