def _tx_string(self, s): """This is only safe if it's guaranteed the card won't send any data during the time of tx of the string !!!""" self._sl.write(s) r = self._sl.read(len(s)) if r != s: # TX and RX are tied, so we must clear the echo raise ProtocolError("Bad echo value (Expected: %s, got %s)" % (b2h(s), b2h(r)))
def connect(self): try: # Explicitly select T=0 communication protocol self._con.connect(CardConnection.T0_protocol) except CardConnectionException: raise ProtocolError() except NoCardException: raise NoCardError()
def send_apdu_raw(self, pdu): """see LinkBase.send_apdu_raw""" pdu = h2b(pdu) data_len = ord(pdu[4]) # P3 # Send first CLASS,INS,P1,P2,P3 self._tx_string(pdu[0:5]) # Wait ack which can be # - INS: Command acked -> go ahead # - 0x60: NULL, just wait some more # - SW1: The card can apparently proceed ... while True: b = self._rx_byte() if b == pdu[1]: break elif b != '\x60': # Ok, it 'could' be SW1 sw1 = b sw2 = self._rx_byte() nil = self._rx_byte() if (sw2 and not nil): return '', b2h(sw1 + sw2) raise ProtocolError() # Send data (if any) if len(pdu) > 5: self._tx_string(pdu[5:]) # Receive data (including SW !) # length = [P3 - tx_data (=len(pdu)-len(hdr)) + 2 (SW1/2) ] to_recv = data_len - len(pdu) + 5 + 2 data = '' while (len(data) < to_recv): b = self._rx_byte() if (to_recv == 2) and ( b == '\x60'): # Ignore NIL if we have no RX data (hack ?) continue if not b: break data += b # Split datafield from SW if len(data) < 2: return None, None sw = data[-2:] data = data[0:-2] # Return value return b2h(data), b2h(sw)
def connect(self): try: # To avoid leakage of resources, make sure the reader # is disconnected self.disconnect() # Explicitly select T=0 communication protocol self._con.connect(CardConnection.T0_protocol) except CardConnectionException: raise ProtocolError() except NoCardException: raise NoCardError()
def _tx_byte(self, b): self._sl.write(b) r = self._sl.read() if r != b: # TX and RX are tied, so we must clear the echo raise ProtocolError("Bad echo value. Expected %02x, got %s)" % (ord(b), '%02x' % ord(r) if r else '(nil)'))
def reset_card(self): rv = self._reset_card() if rv == 0: raise NoCardError() elif rv < 0: raise ProtocolError()