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-2011 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 sys import exc_info
32 from threading import Thread, Event
33 from time import sleep
34
35 from smartcard.System import readers
36 from smartcard.Exceptions import CardRequestTimeoutException
37 from smartcard.Observer import Observer
38 from smartcard.Observer import Observable
39
40 from smartcard.CardType import AnyCardType
41 from smartcard.CardRequest import CardRequest
42
43 _START_ON_DEMAND_ = False
44
45
46
48 """
49 CardObserver is a base abstract class for objects that are to be notified
50 upon smartcard reader insertion/removal.
51 """
52
55
56 - def update(self, observable, (addedcards, removedcards)):
57 """Called upon reader insertion/removal.
58
59 observable:
60 addedcards: list of added readers causing notification
61 removedcards: list of removed readers causing notification
62 """
63 pass
64
65
67 """Class that monitors smart card insertion/removal.
68 and notify observers
69
70 note: a card monitoring thread will be running
71 as long as the card monitor has observers, or CardMonitor.stop()
72 is called. Do not forget to delete all your observers by
73 calling deleteObserver, or your program will run forever...
74
75 Uses the singleton pattern from Thinking in Python
76 Bruce Eckel, http://mindview.net/Books/TIPython to make sure
77 there is only one CardMonitor.
78 """
79
81 """The real smartcard monitor class.
82
83 A single instance of this class is created
84 by the public CardMonitor class.
85 """
86
93
106
108 """Remove an observer.
109
110 We delete the CardMonitoringThread reference when there
111 are no more observers.
112 """
113 Observable.deleteObserver(self, observer)
114 if _START_ON_DEMAND_:
115 if self.countObservers() == 0:
116 if self.rmthread != None:
117 self.rmthread = None
118
121
122
123 instance = None
124
128
131
132
134 """Card insertion thread.
135 This thread waits for card insertion.
136 """
137
139 """The real card monitoring thread class.
140
141 A single instance of this class is created
142 by the public CardMonitoringThread class.
143 """
144
146 Thread.__init__(self)
147 self.observable = observable
148 self.stopEvent = Event()
149 self.stopEvent.clear()
150 self.cards = []
151 self.setDaemon(True)
152
153
155 """Runs until stopEvent is notified, and notify
156 observers of all card insertion/removal.
157 """
158 self.cardrequest = CardRequest(timeout=0.1)
159 while self.stopEvent.isSet() != 1:
160 try:
161 currentcards = self.cardrequest.waitforcardevent()
162
163 addedcards = []
164 for card in currentcards:
165 if not self.cards.__contains__(card):
166 addedcards.append(card)
167
168 removedcards = []
169 for card in self.cards:
170 if not currentcards.__contains__(card):
171 removedcards.append(card)
172
173 if addedcards != [] or removedcards != []:
174 self.cards = currentcards
175 self.observable.setChanged()
176 self.observable.notifyObservers((addedcards, removedcards))
177
178
179
180
181
182
183
184 except TypeError:
185 pass
186 except AttributeError:
187 pass
188
189 except:
190 try:
191 import sys
192 print sys.exc_info()[1]
193 print sys.exc_info()[2]
194 print sys.exc_info()[0]
195 except:
196 pass
197
198
201
202
203 instance = None
204
209
213
214
215
216
217
218
219
220
221
222 if __name__ == "__main__":
223 from smartcard.CardMonitoring import CardMonitor
224 print 'insert or remove cards in the next 10 seconds'
225
226
228
230 self.obsindex = obsindex
231
232 - def update(self, observable, (addedcards, removedcards)):
233 print "%d - added: " % self.obsindex, addedcards
234 print "%d - removed: " % self.obsindex, removedcards
235
237
239 Thread.__init__(self)
240 self.readermonitor = CardMonitor()
241 self.obsindex = obsindex
242 self.observer = None
243
245
246 self.observer = printobserver(self.obsindex)
247 self.readermonitor.addObserver(self.observer)
248 sleep(10)
249 self.readermonitor.deleteObserver(self.observer)
250
251 t1 = testthread(1)
252 t2 = testthread(2)
253 t1.start()
254 t2.start()
255