1 """Smart card insertion/removal monitoring classes.
2
3 CardObserver is a base class for objects that are to be notified
4 upon smart card insertion/removal.
5
6 CardMonitor is a singleton object notifying registered CardObservers
7 upon reader insertion/removal.
8
9 __author__ = "http://www.gemalto.com"
10
11 Copyright 2001-2012 gemalto
12 Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
13
14 This file is part of pyscard.
15
16 pyscard is free software; you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License as published by
18 the Free Software Foundation; either version 2.1 of the License, or
19 (at your option) any later version.
20
21 pyscard is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU Lesser General Public License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with pyscard; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 """
30
31 from __future__ import print_function
32 from threading import Thread, Event
33 from time import sleep
34 import traceback
35
36 from smartcard.Observer import Observer
37 from smartcard.Observer import Observable
38
39 from smartcard.CardRequest import CardRequest
40
41 _START_ON_DEMAND_ = False
42
43
44
46 """
47 CardObserver is a base abstract class for objects that are to be notified
48 upon smart card insertion / removal.
49 """
50
53
54 - def update(self, observable, handlers):
55 """Called upon smart card insertion / removal.
56
57 @param observable:
58 @param handlers:
59 - addedcards: list of inserted smart cards causing notification
60 - removedcards: list of removed smart cards causing notification
61 """
62 pass
63
64
66 """Class that monitors smart card insertion / removals.
67 and notify observers
68
69 note: a card monitoring thread will be running
70 as long as the card monitor has observers, or CardMonitor.stop()
71 is called. Do not forget to delete all your observers by
72 calling deleteObserver, or your program will run forever...
73
74 Uses the singleton pattern from Thinking in Python
75 Bruce Eckel, http://mindview.net/Books/TIPython to make sure
76 there is only one CardMonitor.
77 """
78
80 """The real smart card monitor class.
81
82 A single instance of this class is created
83 by the public CardMonitor class.
84 """
85
92
105
107 """Remove an observer.
108
109 We delete the CardMonitoringThread reference when there
110 are no more observers.
111 """
112 Observable.deleteObserver(self, observer)
113 if _START_ON_DEMAND_:
114 if self.countObservers() == 0:
115 if self.rmthread != None:
116 self.rmthread = None
117
120
121
122 instance = None
123
127
130
131
133 """Card insertion thread.
134 This thread waits for card insertion.
135 """
136
138 """The real card monitoring thread class.
139
140 A single instance of this class is created
141 by the public CardMonitoringThread class.
142 """
143
145 Thread.__init__(self)
146 self.observable = observable
147 self.stopEvent = Event()
148 self.stopEvent.clear()
149 self.cards = []
150 self.setDaemon(True)
151
152
154 """Runs until stopEvent is notified, and notify
155 observers of all card insertion/removal.
156 """
157 self.cardrequest = CardRequest(timeout=0.1)
158 while self.stopEvent.isSet() != 1:
159 try:
160 currentcards = self.cardrequest.waitforcardevent()
161
162 addedcards = []
163 for card in currentcards:
164 if not self.cards.__contains__(card):
165 addedcards.append(card)
166
167 removedcards = []
168 for card in self.cards:
169 if not currentcards.__contains__(card):
170 removedcards.append(card)
171
172 if addedcards != [] or removedcards != []:
173 self.cards = currentcards
174 self.observable.setChanged()
175 self.observable.notifyObservers(
176 (addedcards, removedcards))
177
178
179
180
181
182
183
184 except TypeError:
185 pass
186 except AttributeError:
187 pass
188
189 except:
190
191 traceback.print_exc()
192
193
194
195
196 self.stopEvent.set()
197
198
201
202
203 instance = None
204
210
214
215
216
217
218
219
220
221
222
223 if __name__ == "__main__":
224 print('insert or remove cards in the next 10 seconds')
225
226
228
230 self.obsindex = obsindex
231
232 - def update(self, observable, handlers):
233 addedcards, removedcards = handlers
234 print("%d - added: %s" % (self.obsindex, str(addedcards)))
235 print("%d - removed: %s" % (self.obsindex, str(removedcards)))
236
238
240 Thread.__init__(self)
241 self.readermonitor = CardMonitor()
242 self.obsindex = obsindex
243 self.observer = None
244
246
247 self.observer = printobserver(self.obsindex)
248 self.readermonitor.addObserver(self.observer)
249 sleep(10)
250 self.readermonitor.deleteObserver(self.observer)
251
252 t1 = testthread(1)
253 t2 = testthread(2)
254 t1.start()
255 t2.start()
256