class smartcardBridge(): cardmonitor = None cardobserver = None """ MainClass for the smartcardBride """ def __init__(self, args): # feedbackHandler.setup() self.cardmonitor = CardMonitor() self.cardobserver = cardReader(args) self.addCardObserver(self.cardobserver) def shutdown(self): print "Shutdown" self.removeCardObserver(self.cardobserver) # feedbackHandler.shutdown() def addCardObserver(self, observer): self.cardmonitor.addObserver(observer) def removeCardObserver(self, observer): self.cardmonitor.deleteObserver(observer)
def main(): global logger global consumer setup_logging() logger = logging.getLogger(__name__) logger.info( "Insert MIFARE Desfire card to any reader to get its applications.") available_reader = readers() logger.info("Available readers: %s", available_reader) if not available_reader: sys.exit("No smartcard readers detected") consumer = ConsumerThread() consumer.start() cardmonitor = CardMonitor() cardobserver = MyObserver() cardmonitor.addObserver(cardobserver) try: while True: time.sleep(1) finally: consumer.alive = False # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(cardobserver)
class SmartCardMonitor(CardObserver): def __init__ (self, dispatcher): self.cards = 0 self.dispatcher = dispatcher self.dispatcher.update_inserted(self.get_status(), initial=True) def get_status(self): cards = 0 for reader in readers(): try: connection = reader.createConnection() connection.connect() cards = cards + 1 except NoCardException: pass self.cards = cards return (self.cards > 0) def monitor (self): self.cardmonitor = CardMonitor() self.cardmonitor.addObserver(self) def shutdown (self): self.cardmonitor.deleteObserver(self) def update (self, observable, (addedcards, removedcards)): #update the number of cards currently inserted in the system self.cards = self.cards + len(addedcards) - len(removedcards) if self.cards > 0: self.dispatcher.update_inserted(True) else: self.dispatcher.update_inserted(False)
def setStudentPresent(self): self.start() # Creation client com avec Serveur NFC print('thread start') client = Client(config.URI) try: lastID = "" while self.run: cardmonitor = CardMonitor() cardobserver = ComUsb() cardmonitor.addObserver(cardobserver) time.sleep(1) tmp = cardobserver.repUid print(tmp) if tmp != "" and tmp != lastID: lastID = tmp data = client.get('/1.0/user/byTag/' + tmp) self.cours[self.idCour].setPresent(self.reseau, data["login"], "present") self.gui.setStatus(data["login"], "present") cardmonitor.deleteObserver(cardobserver) except Exception as e: print(str(e)) self.finished.emit()
def main(): try: # initial screen LOGGER_MAIN.info("System ready....") global GPIO_CONTROL_MAIN GPIO_CONTROL_MAIN = GPIOControl() # card monitor cardmonitor = CardMonitor() cardobserver = BrizziCardObserver() cardmonitor.addObserver(cardobserver) # eternal loop try: while True: time.sleep(1) except Exception as err: pass # delete observer cardmonitor.deleteObserver(cardobserver) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) except Exception as err: pass GPIO_CONTROL_MAIN.gpio_cleanup()
class NfcReader(threading.Thread): def _disable_buz(self): hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) assert hresult == SCARD_S_SUCCESS hresult, readers = SCardListReaders(hcontext, []) assert len(readers) > 0 reader = readers[READER] hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, reader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) print('Connected with active protocol', dwActiveProtocol) hresult, response = SCardControl(hcard, SCARD_CTL_CODE(1), [0xFF, 0x00, 0x52, 0x00, 0x00]) if hresult != SCARD_S_SUCCESS: print('Failed to disable sound output : ' + SCardGetErrorMessage(hresult)) def __init__(self, callback): threading.Thread.__init__(self) #self._disable_buz() self.cardmonitor = CardMonitor() self.cardobserver = NfcReaderObserver(callback) self.cardmonitor.addObserver(self.cardobserver) self.run_event = threading.Event() self.run_event.set() def run(self): while self.run_event.is_set(): sleep(1) def close(self): self.run_event.clear() self.cardmonitor.deleteObserver(self.cardobserver)
def run(): cardmonitor = CardMonitor() cardobserver = PhoneObserver() cardmonitor.addObserver(cardobserver) sleep(10) cardmonitor.deleteObserver(cardobserver)
def main(): monitor = CardMonitor() observer = TapObserver(handle_card) monitor.addObserver(observer) try: while True: time.sleep(5) finally: monitor.deleteObserver(observer)
def wait_for_device(): cardmonitor = CardMonitor() cardobserver = PhoneObserver() cardmonitor.addObserver(cardobserver) print('Waiting for device...') sleep(10) cardmonitor.deleteObserver(cardobserver) os._exit(1)
def main(): print('Insert or remove a smartcard in the system.') print('') cardmonitor = CardMonitor() cardobserver = PrintObserver() cardmonitor.addObserver(cardobserver) while True: sleep(1) cardmonitor.deleteObserver(cardobserver)
def daemon_body(): # The main loop try: cardmonitor = CardMonitor() cardobserver = printobserver() cardmonitor.addObserver(cardobserver) while True: sleep(1000000) # sleep forever except: cardmonitor.deleteObserver(cardobserver)
class testthread(Thread): def __init__(self, obsindex): Thread.__init__(self) self.readermonitor = CardMonitor() self.obsindex = obsindex self.observer = None def run(self): # create and register observer self.observer = printobserver(self.obsindex) self.readermonitor.addObserver(self.observer) sleep(10) self.readermonitor.deleteObserver(self.observer)
def startLoop(): now = datetime.datetime.today() directory = "%04u-%02u-%02u_%02uh%02um%02us" % (now.year, now.month, now.day, now.hour, now.minute, now.second) os.makedirs(directory) cardmonitor = CardMonitor() cardobserver = observer(directory) cardmonitor.addObserver(cardobserver) while True: try: time.sleep(60) except: break cardmonitor.deleteObserver(cardobserver)
class testthread(threading.Thread): def __init__(self, obsindex, testcase): threading.Thread.__init__(self) self.obsindex = obsindex self.testcase = testcase self.cardmonitor = CardMonitor() self.observer = None def run(self): # create and register observer self.observer = printobserver(self.obsindex, self.testcase) self.cardmonitor.addObserver(self.observer) time.sleep(1) self.cardmonitor.deleteObserver(self.observer)
def daemon_body(): # The main loop logging.info("INFO waiting for card... (hit CTRL+C to stop)") try: cardmonitor = CardMonitor() cardobserver = printobserver() cardmonitor.addObserver(cardobserver) while True: sleep(1000000) # sleep forever except: cardmonitor.deleteObserver(cardobserver)
class ACR122(): def __init__(self, obs_impl=uid.ReadUidObserver): # Declaration self.__monitor = None self.__observer = None # Initialization self.__monitor = CardMonitor() self.__observer = obs_impl() # XXX: Extend to mutiple observer def attachObserver(self): self.__monitor.addObserver(self.__observer) def detachObserver(self): self.__monitor.deleteObserver(self.__observer)
def startLoop(): now = datetime.datetime.today() directory = "%04u-%02u-%02u_%02uh%02um%02us" % \ (now.year, now.month, now.day, now.hour, now.minute, now.second) os.makedirs(directory) cardmonitor = CardMonitor() cardobserver = observer(directory) cardmonitor.addObserver(cardobserver) while True: try: time.sleep(60) except: break cardmonitor.deleteObserver(cardobserver)
def display_atr(self, reader="usb", verbose=False): print_info("Scanning present readers...") cardmonitor = CardMonitor() selectobserver = ATRObserver(verbose) cardmonitor.addObserver(selectobserver) while True: try: sleep(0.1) except KeyboardInterrupt: print() print_error("Module Interrupted") cardmonitor.deleteObserver(selectobserver) return True
class LecteurCarteTest(unittest.TestCase): def setUp(self): self.q = Queue() self.cardmonitor = CardMonitor() self.lecteur = Lecteur(self.q) self.cardmonitor.addObserver(self.lecteur) def test_lecturecarte(self): print( '\nVous avez 10 secondes pour présenter une ou plusieurs cartes au lecteur.' ) time.sleep(10) self.assertNotEqual(self.q.qsize(), 0, 'Le lecteur n\'a lu aucune carte.') self.cardmonitor.deleteObserver(self.lecteur)
def entry_point(): print u"Smartcard monitor applet by Lauri Võsandi <*****@*****.**>" if not os.path.exists(PCSCD): print "Unable to find", PCSCD, "are you sure it is installed" applet = SmartcardApplet() reader_monitor = ReaderMonitor() reader_monitor.addObserver(applet.reader_observer) card_monitor = CardMonitor() card_monitor.addObserver(applet.card_observer) try: gtk.main() except KeyboardInterrupt: pass card_monitor.deleteObserver(applet.card_observer) reader_monitor.deleteObserver(applet.reader_observer)
class CardWatcher: def __init__(self, on_card): self.monitor = CardMonitor() self.observer = MyObserver(on_card) def start(self): available_reader = readers() if not available_reader: raise Exception('No smartcard readers detected') self.monitor.addObserver(self.observer) while True: time.sleep(1) self.monitor.deleteObserver(self.observer)
def TapN(): print("Insert or remove a smartcard in the system.") print("This program will exit in 10 seconds") print("") cardmonitor = CardMonitor() cardobserver = PrintObserver() cardmonitor.addObserver(cardobserver) sleep(1) # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(cardobserver) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1) return cardobserver.Tap
class NfcReader(): def __init__(self, o2m=None): print("NFCReader initializing...") print("Insert or remove a smartcard in the system.") print("") self.log = logging.getLogger(__name__) self.o2m = o2m self.cardmonitor = CardMonitor() self.cardobserver = PrintObserver() self.cardmonitor.addObserver(self.cardobserver) self.cardobserver.events.on_change += self.update_change ''' Callback function called when the card observer triggers the event on_change. this function just pass the parameters to the parent NfcToMopidy object ''' def update_change(self, addedCards, removedCards, activeCards): self.o2m.get_new_cards(addedCards, removedCards, activeCards) ''' Start an infinite loop to keep the readers polling ''' def loop(self): try: while True: sleep(10) except KeyboardInterrupt: self.remove_observer() self.log.info('Keyboard Interrupt : Removing observer') ''' If killed properly we remove the observer to prevent forever polling on the readers ''' def remove_observer(self): # don't forget to remove observer, or the # monitor will poll forever... self.cardmonitor.deleteObserver(self.cardobserver) self.log.info('Observer removed : Connection closed')
class Webconnector(): cardmonitor = None cardobserver = None """ MainClass for the Webconnector """ def __init__(self, args): feedbackHandler.setup() self.cardmonitor = CardMonitor() self.cardobserver = cardWebconnector(args) self.addCardObserver(self.cardobserver) def shutdown(self): print "Shutdown" self.removeCardObserver(self.cardobserver) feedbackHandler.shutdown() def addCardObserver(self, observer): self.cardmonitor.addObserver(observer) def removeCardObserver(self, observer): self.cardmonitor.deleteObserver(observer) def checkConnection(self, url): try: # Try connection response = urllib2.urlopen(url, timeout=1) # Connection successful, activate Connection-LED feedbackHandler.setFeedback(feedbackHandler.CONNECTION, feedbackHandler.ACTIVE) return True except urllib2.URLError as e: # No Connection to Server feedbackHandler.setFeedback(feedbackHandler.CONNECTION, feedbackHandler.INACTIVE) finally: return False
def main(): global logger logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) logger.info("Insert MIFARE Desfire card to any reader to get its applications.") available_reader = readers() logger.info("Available readers: %s", available_reader) if not available_reader: sys.exit("No smartcard readers detected") cardmonitor = CardMonitor() cardobserver = MyObserver() cardmonitor.addObserver(cardobserver) while True: time.sleep(1) # don't forget to remove§ observer, or the # monitor will poll forever... cardmonitor.deleteObserver(cardobserver)
def ResultMifar1k(): cardmonitor = CardMonitor() cardobserver = PrintObserver() cardmonitor.addObserver(cardobserver) sleep(1) # if cardobserver.getbaca!="": # print("Tes baca", cardobserver.getbaca) # cardobserver.getbaca = "" # while True: # sleep(1) # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(cardobserver) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(6000) return cardobserver.getbaca
def run(self, loop=True): self.debug("Starting DNIe System", color='blue') # Monitor for new cards # cardtype = AnyCardType() if CardMonitor: try: # cardrequest = CardRequest( timeout=1.5, cardType=cardtype ) cardmonitor = CardMonitor() cardobserver = DNIeObserver(self.DNIeHandler) self.debug("DNIe connecting observer", color='yellow') cardmonitor.addObserver(cardobserver) except Exception as e: self.error( "No smartcard reader detected... (ERROR: {})".format(e)) cardobserver = None cardmonitor = None else: self.error("No smartcard library detected... (ERROR: {})".format( CardMonitorError)) cardobserver = None cardmonitor = None # Sleep as usually if loop: super(POSDNIe, self).run() # Finish self.debug("Shutting down DNIe System", color='blue') # Remove the observer, or the monitor will poll forever if cardmonitor and cardobserver: cardmonitor.deleteObserver(cardobserver) # We are done self.debug("DNIe System is down", color='blue')
def main(): output_pins, input_pins, relay_number, ldap_match_attr, ldap_owner_attr, ldap_server, ldap_port, ldap_base_dn, ldap_use_ssl, ldap_user, ldap_user_secret = read_config( "config.yml") pifacedigital = pifacedigitalio.PiFaceDigital() door = Door(pifacedigital, output_pins, input_pins, relay_number) # To fix startup problems we toggle the lock door.close() sleep(0.5) door.open() sleep(0.5) door.close() listener = pifacedigitalio.InputEventListener(chip=pifacedigital) listener.register(1, pifacedigitalio.IODIR_ON, door.event_on_door_switch) logger.info("Activating listener") listener.activate() cardmonitor = CardMonitor() cardobserver = PrintObserver(door, ldap_base_dn, ldap_server, ldap_port, ldap_use_ssl, ldap_user, ldap_user_secret, ldap_match_attr, ldap_owner_attr) cardmonitor.addObserver(cardobserver) while True: sleep(60) cardmonitor.deleteObserver(cardobserver)
apdu = SELECT + DF_TELECOM response, sw1, sw2 = card.connection.transmit(apdu) if sw1 == 0x9F: apdu = GET_RESPONSE + [sw2] response, sw1, sw2 = card.connection.transmit(apdu) for card in removedcards: print "-Removed: ", toHexString(card.atr) try: print "Insert or remove a SIM card in the system." print "This program will exit in 60 seconds" print "" cardmonitor = CardMonitor() selectobserver = selectDFTELECOMObserver() cardmonitor.addObserver(selectobserver) sleep(60) # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(selectobserver) import sys if 'win32' == sys.platform: print 'press Enter to continue' sys.stdin.read(1) except: print exc_info()[0], ':', exc_info()[1]
class PrintObserver(CardObserver): """A simple card observer that is notified when cards are inserted/removed from the system and prints the list of cards """ def update(self, observable, actions): (addedcards, removedcards) = actions for card in addedcards: print("+Inserted: ", toHexString(card.atr)) for card in removedcards: print("-Removed: ", toHexString(card.atr)) if __name__ == '__main__': print("Insert or remove a smartcard in the system.") print("This program will exit in 10 seconds") print("") cardmonitor = CardMonitor() cardobserver = PrintObserver() cardmonitor.addObserver(cardobserver) sleep(10) # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(cardobserver) import sys if 'win32' == sys.platform: print('press Enter to continue') sys.stdin.read(1)
class ThaiIDCard: status = None smart_card_reader_monitor = None smart_card_reader_observer = None smart_card_monitor = None smart_card_observer = None # # Thailand National ID Card Address # # Select & Thai MOI SELECT = [0x00, 0xA4, 0x04, 0x00, 0x08] AID_MOI = [0xA0, 0x00, 0x00, 0x00, 0x54, 0x48, 0x00, 0x01] # APDU Type APDU_THAILAND_IDCARD_TYPE_01 = [0x00, 0xc0, 0x00, 0x01] APDU_THAILAND_IDCARD_TYPE_02 = [0x00, 0xc0, 0x00, 0x00] # TH Citizen ID CMD_CITIZEN = [0x80, 0xb0, 0x00, 0x04, 0x02, 0x00, 0x0d] # TH Full Name CMD_THFULLNAME = [0x80, 0xb0, 0x00, 0x11, 0x02, 0x00, 0x64] # EN Full Name CMD_ENFULLNAME = [0x80, 0xb0, 0x00, 0x75, 0x02, 0x00, 0x64] # Date of birth CMD_BIRTH = [0x80, 0xb0, 0x00, 0xD9, 0x02, 0x00, 0x08] # Gender CMD_GENDER = [0x80, 0xb0, 0x00, 0xE1, 0x02, 0x00, 0x01] # Card Issuer CMD_ISSUER = [0x80, 0xb0, 0x00, 0xF6, 0x02, 0x00, 0x64] # Issue Date CMD_ISSUE = [0x80, 0xb0, 0x01, 0x67, 0x02, 0x00, 0x08] # Expire Date CMD_EXPIRE = [0x80, 0xb0, 0x01, 0x6F, 0x02, 0x00, 0x08] # Address CMD_ADDRESS = [0x80, 0xb0, 0x15, 0x79, 0x02, 0x00, 0x64] # Photo_Part1/20 CMD_PHOTO01 = [0x80, 0xb0, 0x01, 0x7B, 0x02, 0x00, 0xFF] # Photo_Part2/20 CMD_PHOTO02 = [0x80, 0xb0, 0x02, 0x7A, 0x02, 0x00, 0xFF] # Photo_Part3/20 CMD_PHOTO03 = [0x80, 0xb0, 0x03, 0x79, 0x02, 0x00, 0xFF] # Photo_Part4/20 CMD_PHOTO04 = [0x80, 0xb0, 0x04, 0x78, 0x02, 0x00, 0xFF] # Photo_Part5/20 CMD_PHOTO05 = [0x80, 0xb0, 0x05, 0x77, 0x02, 0x00, 0xFF] # Photo_Part6/20 CMD_PHOTO06 = [0x80, 0xb0, 0x06, 0x76, 0x02, 0x00, 0xFF] # Photo_Part7/20 CMD_PHOTO07 = [0x80, 0xb0, 0x07, 0x75, 0x02, 0x00, 0xFF] # Photo_Part8/20 CMD_PHOTO08 = [0x80, 0xb0, 0x08, 0x74, 0x02, 0x00, 0xFF] # Photo_Part9/20 CMD_PHOTO09 = [0x80, 0xb0, 0x09, 0x73, 0x02, 0x00, 0xFF] # Photo_Part10/20 CMD_PHOTO10 = [0x80, 0xb0, 0x0A, 0x72, 0x02, 0x00, 0xFF] # Photo_Part11/20 CMD_PHOTO11 = [0x80, 0xb0, 0x0B, 0x71, 0x02, 0x00, 0xFF] # Photo_Part12/20 CMD_PHOTO12 = [0x80, 0xb0, 0x0C, 0x70, 0x02, 0x00, 0xFF] # Photo_Part13/20 CMD_PHOTO13 = [0x80, 0xb0, 0x0D, 0x6F, 0x02, 0x00, 0xFF] # Photo_Part14/20 CMD_PHOTO14 = [0x80, 0xb0, 0x0E, 0x6E, 0x02, 0x00, 0xFF] # Photo_Part15/20 CMD_PHOTO15 = [0x80, 0xb0, 0x0F, 0x6D, 0x02, 0x00, 0xFF] # Photo_Part16/20 CMD_PHOTO16 = [0x80, 0xb0, 0x10, 0x6C, 0x02, 0x00, 0xFF] # Photo_Part17/20 CMD_PHOTO17 = [0x80, 0xb0, 0x11, 0x6B, 0x02, 0x00, 0xFF] # Photo_Part18/20 CMD_PHOTO18 = [0x80, 0xb0, 0x12, 0x6A, 0x02, 0x00, 0xFF] # Photo_Part19/20 CMD_PHOTO19 = [0x80, 0xb0, 0x13, 0x69, 0x02, 0x00, 0xFF] # Photo_Part20/20 CMD_PHOTO20 = [0x80, 0xb0, 0x14, 0x68, 0x02, 0x00, 0xFF] # Expire time of data -- seconds _read_expire_time = 5 # # Thai Citizen ID _citizen = None _citizen_t = 0 # Thai Full Name _full_name_th = None _full_name_th_t = 0 # English Full Name _full_name_en = None _full_name_en_th = 0 # Date of birth _birth = None _birth_t = 0 # Gender _gender = None _gender_t = 0 # Card Issuer _issuer = None _issuer_t = 0 # Issue Date _issue = None _issue_t = 0 # Expire Date _expire = None _expire_t = 0 # Address _address = None _address_t = 0 # Photo _photo = None _photo_t = 0 def __init__(self): self.readerList = [] if (len(self.getReaders()) > 0): self.connect(0) def readerMonitor(self, reader_added_cb, reader_removed_cb): self.reader_added_cb = reader_added_cb self.reader_removed_cb = reader_removed_cb if THAI_ID_CARD_DEBUG: print("ThaiIDCard: Add SmartCard reader observer") self.smart_card_reader_monitor = ReaderMonitor() self.smart_card_reader_observer = SmartCardReaderObserver( reader_added_callback=self.reader_removed_cb, reader_removed_callback=self.reader_removed_cb) self.smart_card_reader_monitor.addObserver( self.smart_card_reader_observer) def readerUnmonitor(self): try: if THAI_ID_CARD_DEBUG: print("ThaiIDCard: Remove SmartCard reader observer") self.smart_card_reader_monitor.deleteObserver( self.smart_card_reader_observer) except: pass def cardMonitor(self, smart_card_insert_cb, smart_card_remove_cb): self.smart_card_insert_cb = smart_card_insert_cb self.smart_card_remove_cb = smart_card_remove_cb if THAI_ID_CARD_DEBUG: print("ThaiIDCard: Add SmartCard observer") self.smart_card_monitor = CardMonitor() self.smart_card_observer = SmartCardObserver( card_insert_callback=self.smart_card_insert_cb, card_remove_callback=self.smart_card_remove_cb) self.smart_card_monitor.addObserver(self.smart_card_observer) def cardUnmonitor(self): try: if THAI_ID_CARD_DEBUG: print("ThaiIDCard: Remove SmartCard observer") self.smart_card_monitor.deleteObserver(self.smart_card_observer) except: pass # Get SmartCard reader list def getReaders(self): # Get all the available readers self.readerList = smartcard.System.readers() #if len(self.readerList) > 0: # print ("Found SmartCard readers:") # for readerIndex,readerItem in enumerate(self.readerList): # print(" - %d, '%s'"%(readerIndex, readerItem)) #else: # print ("No SmartCard reader") self.readerIndex = 0 return self.readerList # Connect to SmartCard reader def connect(self, index=0): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: Connecting to SmartCard") if len(self.readerList) == 0: if len(self.getReaders()) == 0: return None if index < 0 or index >= len(self.readerList): return None # Select reader self.readerIndex = index self.reader = self.readerList[self.readerIndex] if THAI_ID_CARD_DEBUG: print("Using SmartCard reader:", self.reader) try: self.connection = self.reader.createConnection() self.connection.connect() atr = self.connection.getATR() if THAI_ID_CARD_DEBUG: print(" - Card type: " + toHexString(atr)) if (atr[0] == 0x3B & atr[1] == 0x67): # Corruption Card self._apdu = self.APDU_THAILAND_IDCARD_TYPE_01 else: self._apdu = self.APDU_THAILAND_IDCARD_TYPE_02 if THAI_ID_CARD_DEBUG: print(" - Connect to SmartCard success") self.status = True response, sw1, sw2 = self.selectApplet() # [], 61, 0A time.sleep(0.1) if sw1 == 0x61 and sw2 == 0x0A: return True self.status = None return None except: if THAI_ID_CARD_DEBUG: print(" - Failed to connect to SmartCard") self.status = None return None def disconnect(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: Closing connection from SmartCard") try: self.connection.disconnect() except: pass # Select MOI Applet def selectApplet(self): if self.status == None: if self.connect(self.readerIndex) == None: return [None, None, None] response, sw1, sw2 = self.connection.transmit(self.SELECT + self.AID_MOI) #print ("Select Applet: %02X %02X" % (sw1, sw2)) return [response, sw1, sw2] # Read data from SmartCard def read(self, cmd, apdu=None): if self.status == None: if self.connect(self.readerIndex) == None: return [None, None, None] if apdu == None: apdu = self._apdu try: response, sw1, sw2 = self.connection.transmit(cmd) response, sw1, sw2 = self.connection.transmit(apdu + [cmd[-1]]) return [response, sw1, sw2] except Exception as w: return [None, None, None] # Read photo from SmartCard def readPhoto(self): if self.status == None: if self.connect(self.readerIndex) == None: return None photo = self.read(self.CMD_PHOTO01)[0] photo += self.read(self.CMD_PHOTO02)[0] photo += self.read(self.CMD_PHOTO03)[0] photo += self.read(self.CMD_PHOTO04)[0] photo += self.read(self.CMD_PHOTO05)[0] photo += self.read(self.CMD_PHOTO06)[0] photo += self.read(self.CMD_PHOTO07)[0] photo += self.read(self.CMD_PHOTO08)[0] photo += self.read(self.CMD_PHOTO09)[0] photo += self.read(self.CMD_PHOTO10)[0] photo += self.read(self.CMD_PHOTO11)[0] photo += self.read(self.CMD_PHOTO12)[0] photo += self.read(self.CMD_PHOTO13)[0] photo += self.read(self.CMD_PHOTO14)[0] photo += self.read(self.CMD_PHOTO15)[0] photo += self.read(self.CMD_PHOTO16)[0] photo += self.read(self.CMD_PHOTO17)[0] photo += self.read(self.CMD_PHOTO18)[0] photo += self.read(self.CMD_PHOTO19)[0] photo += self.read(self.CMD_PHOTO20)[0] response = HexListToBinString(photo) return response def thai2unicode(self, data): result = '' result = bytes(data).decode('tis-620') return result.strip() # Citizen ID @property def citizen(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: citizen=", end=' ') if (self._citizen != None): if ((time.time() - self._citizen_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._citizen) return self._citizen response, sw1, sw2 = self.read(self.CMD_CITIZEN) if (response != None): self._citizen = self.thai2unicode(response) self._citizen_t = time.time() else: self._citizen = None if THAI_ID_CARD_DEBUG: print(self._citizen) return self._citizen # Thai Name @property def full_name_th(self): #if THAI_ID_CARD_DEBUG: # print("ThaiIDCard: full_name_th") if (self._full_name_th != None): if ((time.time() - self._full_name_th_t) < self._read_expire_time): return self._full_name_th response, sw1, sw2 = self.read(self.CMD_THFULLNAME) if (response != None): self._full_name_th = self.thai2unicode(response) self._full_name_th_t = time.time() self._first_name_th, self._last_name_th = self._full_name_th.split( '##') self._prefix_th, self._first_name_th = self._first_name_th.split( '#') else: self._full_name_th = None return self._full_name_th @property def prefix_th(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: prefix_th=", end=' ') if (self._full_name_th != None): if ((time.time() - self._full_name_th_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._prefix_th) return self._prefix_th if (self.full_name_th != None): if THAI_ID_CARD_DEBUG: print(self._prefix_th) return self._prefix_th return None @property def first_name_th(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: first_name_th=", end=' ') if (self._full_name_th != None): if ((time.time() - self._full_name_th_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._first_name_th) return self._first_name_th if (self.full_name_th != None): if THAI_ID_CARD_DEBUG: print(self._first_name_th) return self._first_name_th return None @property def last_name_th(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: last_name_th=", end=' ') if (self._full_name_th != None): if ((time.time() - self._full_name_th_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._last_name_th) return self._last_name_th if (self.full_name_th != None): if THAI_ID_CARD_DEBUG: print(self._last_name_th) return self._last_name_th return None # English Name @property def full_name_en(self): #if THAI_ID_CARD_DEBUG: # print("ThaiIDCard: full_name_en") if (self._full_name_en != None): if ((time.time() - self._full_name_en_t) < self._read_expire_time): return self._full_name_en response, sw1, sw2 = self.read(self.CMD_ENFULLNAME) if (response != None): self._full_name_en = self.thai2unicode(response) self._full_name_en_t = time.time() self._first_name_en, self._last_name_en = self._full_name_en.split( '##') self._prefix_en, self._first_name_en = self._first_name_en.split( '#') else: self._full_name_en = None return self._full_name_en @property def prefix_en(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: prefix_en=", end=' ') if (self._full_name_en != None): if ((time.time() - self._full_name_en_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._prefix_en) return self._prefix_en if (self.full_name_en != None): if THAI_ID_CARD_DEBUG: print(self._prefix_en) return self._prefix_en return None @property def first_name_en(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: first_name_en=", end=' ') if (self._full_name_en != None): if ((time.time() - self._full_name_en_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._first_name_en) return self._first_name_en if (self.full_name_en != None): if THAI_ID_CARD_DEBUG: print(self._first_name_en) return self._first_name_en return None @property def last_name_en(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: last_name_en=", end=' ') if (self._full_name_en != None): if ((time.time() - self._full_name_en_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._last_name_en) return self._last_name_en if (self.full_name_en != None): if THAI_ID_CARD_DEBUG: print(self._last_name_en) return self._last_name_en return None # Date of birth @property def birth(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: birth=", end=' ') if (self._birth != None): if ((time.time() - self._birth_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._birth) return self._birth response, sw1, sw2 = self.read(self.CMD_BIRTH) if (response != None): self._birth = self.thai2unicode(response) self._birth_t = time.time() self._birth = self._birth[0:4] + '-' + self._birth[ 4:6] + '-' + self._birth[6:8] else: self._birth = None if THAI_ID_CARD_DEBUG: print(self._birth) return self._birth # Gender @property def gender(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: gender=", end=' ') if (self._gender != None): if ((time.time() - self._gender_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._gender) return self._gender response, sw1, sw2 = self.read(self.CMD_GENDER) if (response != None): self._gender = self.thai2unicode(response) self._gender_t = time.time() else: self._gender = None if THAI_ID_CARD_DEBUG: print(self._gender) return self._gender # Issue date @property def issue(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: issue=", end=' ') if (self._issue != None): if ((time.time() - self._issue_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._issue) return self._issue response, sw1, sw2 = self.read(self.CMD_ISSUE) if (response != None): self._issue = self.thai2unicode(response) self._issue_t = time.time() self._issue = self._issue[0:4] + '-' + self._issue[ 4:6] + '-' + self._issue[6:8] else: self._issue = None if THAI_ID_CARD_DEBUG: print(self._issue) return self._issue # Expire date @property def expire(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: expire=", end=' ') if (self._expire != None): if ((time.time() - self._expire_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._expire) return self._expire response, sw1, sw2 = self.read(self.CMD_EXPIRE) if (response != None): self._expire = self.thai2unicode(response) self._expire_t = time.time() self._expire = self._expire[0:4] + '-' + self._expire[ 4:6] + '-' + self._expire[6:8] else: self._expire = None if THAI_ID_CARD_DEBUG: print(self._expire) return self._expire # Address @property def address(self): #if THAI_ID_CARD_DEBUG: # print("ThaiIDCard: address") if (self._address != None): if ((time.time() - self._address_t) < self._read_expire_time): return self._address response, sw1, sw2 = self.read(self.CMD_ADDRESS) if (response != None): self._address = self.thai2unicode(response) self._address_t = time.time() #self._address = self._address[0:4]+'-'+self._address[4:6]+'-'+self._address[6:8] self._address = re.sub(r'#', ' ', self._address) self._address = re.sub(r' ', ' ', self._address) self._address = re.sub(r' ', ' ', self._address) x = self._address.rsplit() self._city = x[len(x) - 2] self._province = x[len(x) - 1] else: self._address = None return self._address @property def city(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: city=", end=' ') if (self._address != None): if ((time.time() - self._address_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._city) return self._city if (self.address != None): if THAI_ID_CARD_DEBUG: print(self._city) return self._city return None @property def province(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: province=", end=' ') if (self._address != None): if ((time.time() - self._address_t) < self._read_expire_time): if THAI_ID_CARD_DEBUG: print(self._province) return self._province if (self.address != None): if THAI_ID_CARD_DEBUG: print(self._province) return self._province return None # Photo @property def photo(self): if THAI_ID_CARD_DEBUG: print("ThaiIDCard: photo") if (self._photo != None): if ((time.time() - self._photo_t) < self._read_expire_time): return self._photo self._photo = self.readPhoto() return self._photo # Example code, read all attributes def example(self): if (len(self.readerList) < 0): return None # Reader list print(self.getReaders()) print(f'Citizen ID:', self.citizen) print(f'Thai Full Name: ' + self.full_name_th) print(f'Thai Prefix: ' + self.prefix_th) print(f'Thai First Name: ' + self.first_name_th) print(f'Thai Last Name: ' + self.last_name_th) print(f'English Full Name: ' + self.full_name_en) print(f'English Prefix: ' + self.prefix_en) print(f'English First Name: ' + self.first_name_en) print(f'English Last Name: ' + self.last_name_en) print(f'Date of birth: ' + self.birth) print(f'Gender: ' + self.gender) print(f'Issue date: ' + self.issue) print(f'Expire date: ' + self.expire) print(f'Address: ' + self.address) print(f'City: ' + self.city) print(f'Province: ' + self.province) #print(f'Photo file size: ' + self.photo) return
class CardAndReaderTreePanel(wx.Panel): """Panel containing the smart card and reader tree controls.""" class _CardObserver(CardObserver): """Inner CardObserver. Gets notified of card insertion removal by the CardMonitor.""" def __init__(self, cardtreectrl): self.cardtreectrl = cardtreectrl def update(self, observable, handlers): """CardObserver callback that is notified when cards are added or removed.""" addedcards, removedcards = handlers self.cardtreectrl.OnRemoveCards(removedcards) self.cardtreectrl.OnAddCards(addedcards) class _ReaderObserver(ReaderObserver): """Inner ReaderObserver. Gets notified of reader insertion/removal by the ReaderMonitor.""" def __init__(self, readertreectrl): self.readertreectrl = readertreectrl def update(self, observable, handlers): """ReaderObserver callback that is notified when readers are added or removed.""" addedcards, removedcards = handlers self.readertreectrl.OnRemoveReaders(removedreaders) self.readertreectrl.OnAddReaders(addedreaders) def __init__(self, parent, appstyle, clientpanel): """Constructor. Create a smartcard and reader tree control on the left-hand side of the application main frame. @param parent: the tree panel parent @param appstyle: a combination of the following styles (bitwise or |) - TR_SMARTCARD: display a smartcard tree panel - TR_READER: display a reader tree panel - default is TR_DEFAULT = TR_SMARTCARD @param clientpanel: the client panel to notify of smartcard and reader events """ wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS) sizer = wx.BoxSizer(wx.VERTICAL) # create the smartcard tree if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD: self.cardtreectrl = CardTreeCtrl(self, clientpanel=clientpanel) # create the smartcard insertion observer self.cardtreecardobserver = self._CardObserver(self.cardtreectrl) # register as a CardObserver; we will ge # notified of added/removed cards self.cardmonitor = CardMonitor() self.cardmonitor.addObserver(self.cardtreecardobserver) sizer.Add( self.cardtreectrl, flag=wx.EXPAND | wx.ALL, proportion=1) # create the reader tree if appstyle & smartcard.wx.SimpleSCardApp.TR_READER: self.readertreectrl = ReaderTreeCtrl( self, clientpanel=clientpanel) # create the reader insertion observer self.readertreereaderobserver = self._ReaderObserver( self.readertreectrl) # register as a ReaderObserver; we will ge # notified of added/removed readers self.readermonitor = ReaderMonitor() self.readermonitor.addObserver(self.readertreereaderobserver) # create the smartcard insertion observer self.readertreecardobserver = self._CardObserver( self.readertreectrl) # register as a CardObserver; we will get # notified of added/removed cards self.cardmonitor = CardMonitor() self.cardmonitor.addObserver(self.readertreecardobserver) sizer.Add( self.readertreectrl, flag=wx.EXPAND | wx.ALL, proportion=1) self.SetSizer(sizer) self.SetAutoLayout(True) def OnDestroy(self, event): """Called on panel destruction.""" # deregister observers if hasattr(self, 'cardmonitor'): self.cardmonitor.deleteObserver(self.cardtreecardobserver) if hasattr(self, 'readermonitor'): self.readermonitor.deleteObserver(self.readertreereaderobserver) self.cardmonitor.deleteObserver(self.readertreecardobserver) event.Skip()
class Command(BaseCommand): args = '' help = 'This program puts a default order (one coffee or tea) when a card is read.' def _enter_state(self, state): states = { STATE_NONE: { 'name': 'STATE_NONE', # no call }, STATE_INITIAL: { 'name': 'STATE_INITIAL', 'call': self._enter_initial, }, STATE_WAITING_FOR_READER: { 'name': 'STATE_WAITING_FOR_READER', 'call': self._enter_waiting_for_reader, }, STATE_READING_CARDS: { 'name': 'STATE_READING_CARDS', 'call': self._enter_reading_cards, }, STATE_EXIT: { 'name': 'STATE_EXIT', 'call': self._enter_exit, }, } if states.has_key(state): state_msg = 'state change: %s -> %s' % ( states[self.state]['name'], states[state]['name'], ) log.info(state_msg) else: err_msg = 'bad state: %r' % state log.error(err_msg) raise StateChangeError(err_msg) self.state = state states[state]['call']() def _setup_card_monitor_and_observer(self): self.card_monitor = CardMonitor() self.card_observer = OrderObserver() self.card_observer.initialize() self.card_monitor.addObserver(self.card_observer) def _tear_down_card_monitor_and_observer(self): if self.card_observer is not None and self.card_monitor is not None: self.card_monitor.deleteObserver(self.card_observer) self.card_monitor = None self.card_observer = None def _enter_waiting_for_reader(self): tasks.blipper_waiting.delay() while len(scsystem.readers()) == 0: sleep(1) self._enter_state(STATE_READING_CARDS) def _enter_reading_cards(self): self._setup_card_monitor_and_observer() tasks.blipper_reading_cards.delay() while len(scsystem.readers()) != 0: sleep(1) self._tear_down_card_monitor_and_observer() self._enter_state(STATE_WAITING_FOR_READER) def _enter_exit(self): self._tear_down_card_monitor_and_observer() log.info('finished program, normal exit') def _enter_initial(self): initial_readers = scsystem.readers() log.info('connected readers: %r' % initial_readers) tasks.blipper_ready.delay() try: if len(initial_readers) == 0: initial_state = STATE_WAITING_FOR_READER elif len(initial_readers) == 1: initial_state = STATE_READING_CARDS else: err_msg = '%d readers connected' % len(initial_readers) raise CardReaderError(err_msg) self._enter_state(initial_state) except KeyboardInterrupt: log.info('user exit') self._enter_state(STATE_EXIT) def handle(self, *args, **options): valid = True if not valid: raise CommandError('invalid config') if settings.CARDREADER_PREFETCH: log.info('prefetch enabled') tasks.blipper_prefetch_users.delay() else: log.info('prefetch disabled') self.card_monitor = None self.card_observer = None self.state = STATE_NONE self._enter_state(STATE_INITIAL)
class AuthD: """ Smart Card Authentication daemon wrapper Supports start/restart/stop and communication through socket """ SOCK_FILE = "/var/run/sc-authd.socket" PID_FILE = "/var/run/sc-authd.pid" def __init__(self): self._pan_monitor = None self._card_monitor = None self._latest_info = None self._watcher = None self._sock = None def start(self) -> None: """ Do daemonization and then init all requirements - sockets, card service, etc. """ self._turn_daemon() self._pan_monitor = CardHolder() if os.path.exists(AuthD.SOCK_FILE): os.unlink(AuthD.SOCK_FILE) self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self._sock.bind(AuthD.SOCK_FILE) #os.chmod(AuthD.SOCK_FILE, 0o777) self._card_monitor = CardMonitor() self._watcher = CardWatcher(self._pan_monitor) self._card_monitor.addObserver(self._watcher) # Pretty normal signal hooks set to shutdown this daemon signal.signal(signal.SIGABRT, self._shutdown) signal.signal(signal.SIGTERM, self._shutdown) signal.signal(signal.SIGQUIT, self._shutdown) signal.signal(signal.SIGINT, self._shutdown) self.run() def restart(self) -> None: """ Simply calls AuthD#stop and AuthD#start then """ self.stop() self.start() def stop(self) -> None: """ Tries to read daemon's PID file and kill it with SIGQUIT """ try: with open(AuthD.PID_FILE, "rt") as pid_file: pid_s = pid_file.readline().strip() os.kill(int(pid_s), signal.SIGQUIT) except FileNotFoundError: syslog.syslog(syslog.LOG_WARNING, "Can't stop. Daemon is not running") except IOError as error: syslog.syslog(syslog.LOG_ERR, "Can't stop. {}".format(error)) def run(self) -> None: """ Main loop method. Listens to the socket and execute commands passed through it """ while True: self._sock.listen(1) conn, _ = self._sock.accept() command = conn.recv(128).decode("utf-8") if command == "get_pan": if self._pan_monitor.read() is None: pan = "" else: pan = self._pan_monitor.read( )[0] or "" # cause ...[0] can be None sha = hashlib.sha3_512() sha.update(pan.encode("utf-8")) conn.send(sha.hexdigest().encode("utf-8")) @noreturn def _shutdown(self, signum: int, _: None): """ Close all handles, stops card monitor """ self._card_monitor.deleteObserver(self._watcher) self._sock.close() if os.path.isfile(AuthD.PID_FILE): os.unlink(AuthD.PID_FILE) if os.path.exists(AuthD.SOCK_FILE): os.unlink(AuthD.SOCK_FILE) syslog.syslog(syslog.LOG_INFO, "Stopped by sig #{}".format(signum)) sys.exit(0) def _turn_daemon(self) -> None: """ Awakens Cthulhu """ self._fork() os.chdir("/") os.setsid() os.umask(0) self._fork() sys.stdout.flush() sys.stderr.flush() stdin = open(os.devnull, "rt") stdout = open(os.devnull, "wt") stderr = open(os.devnull, "wt") os.dup2(stdin.fileno(), sys.stdin.fileno()) os.dup2(stdout.fileno(), sys.stdout.fileno()) os.dup2(stderr.fileno(), sys.stderr.fileno()) pid = os.getpid() if os.path.isfile(AuthD.PID_FILE): os.unlink(AuthD.PID_FILE) with open(AuthD.PID_FILE, "wt") as pidfile: pidfile.write(str(pid)) def _fork(self) -> None: """ Just forks """ try: pid = os.fork() if pid != 0: sys.exit(0) except OSError as error: syslog.syslog(syslog.LOG_CRIT, "Can't daemonize", error) sys.exit(1)
""" def __init__(self): self.observer = ConsoleCardConnectionObserver() def update(self, observable, actions): (addedcards, removedcards) = actions for card in addedcards: card.connection = card.createConnection() card.connection.connect() card.connection.addObserver(self.observer) apdu = [0xFF, 0xCA, 0x00, 0x00, 0x00] response, sw1, sw2 = card.connection.transmit(apdu) print(response) for card in removedcards: print("-Removed: ") if __name__ == '__main__': print("Insert or remove a SIM card in the system.") print("This program will exit in 60 seconds") print("") cardmonitor = CardMonitor() selectobserver = selectDFTELECOMObserver() cardmonitor.addObserver(selectobserver) sleep(60) # don't forget to remove observer, or the # monitor will poll forever... cardmonitor.deleteObserver(selectobserver)
pinLen = len(pin_code)//2 sCmd = ('802100%02x%02x' % (pinLen << 5, pinLen + 32)) + pin_code + h res, status = transmit(sCmd) print('status:', status) if(status == '9000'): t = ''.join(chr(ch) for ch in res).encode('latin-1') t = hexlify(t).decode() t = {'msg': '', 'sign': t, 'status': SUCCESS} print('t:', t, len(t)) else: t = {'msg': 'TEE sign transaction failed', 'sign': '', 'status': FAILED} return json.dumps(t) @app.route('/info', methods=['GET']) def info(): if not checkPseudoWallet(): print('TEE wallet not ready yet!') uockBefore = 0 uockAfter = 0 if __name__ == "__main__": app.after_request(after_request) app.run(host='127.0.0.1', port=3000, debug=True) monitor.deleteObserver(observer)
class NFCreader(): def __init__(self, callback, cb2): self.reader = red.getReader() #make it beep! #answ = self.reader.control(SCARD_CTL_CODE(3500), [0xFF, 0x00, 0x40, 0xC3, 0x04, 0x04, 0x06, 0x01, 0x01]) #turn off default beep is card is scanned #answ = self.reader.control(SCARD_CTL_CODE(3500), [0xFF, 0x00, 0x52, 0x00, 0x00]) #turn off autopolling #answ = self.reader.control(SCARD_CTL_CODE(3500), [0xFF, 0x00, 0x51, 0x43, 0x00]) #workaround to turn it back on #answ = self.reader.control(SCARD_CTL_CODE(3500), [0xFF, 0x00, 0x51, 0xC3, 0x00]) #send direct command to tun on internal polling #answ = self.reader.control(SCARD_CTL_CODE(3500), [0xFF, 0x00, 0x00, 0x00, 0x05, 0xD4, 0x60, 0xFF, 0x02, 0x00]) #print(answ) #answ = self.reader.control(SCARD_CTL_CODE(3500), [0xE0, 0x00, 0x00, 0x20, 0x01, 0x1F]) self.cardmonitor = CardMonitor() self.cardobserver = self.PrintObserver(callback, cb2) self.cardmonitor.addObserver(self.cardobserver) def killObserver(self): self.cardmonitor.deleteObserver(self.cardobserver) class PrintObserver(CardObserver): """A simple card observer that is notified when cards are inserted/removed from the system and prints the list of cards """ def __init__(self, incallback, outcallback): CardObserver.__init__(self) self.InCallback = incallback self.outCallback = outcallback self.observer = ConsoleCardConnectionObserver() def update(self, observable, actions): (addedcards, removedcards) = actions #for card in removedcards: #print(card) for card in addedcards: card.connection = card.createConnection() try: card.connection.connect() except NoCardException as e: continue except CardConnectionException as e: print(e) #todo implement error show continue ncard = NFCCard(card) ncard.getUID() #card.connection.addObserver(self.observer) self.InCallback(ncard) #print(toHexString(card.connection.getATR())) #card.connection.disconnect() for card in removedcards: self.outCallback(card)