def send_message(self, message, tries=0, no_wait=False): """ sends input with write returns output with read. if skip_read is True, it only returns true, you have to read yourself. """ if message: self.write(message.as_bin()) # time.sleep(0.1) acknowledge = self.connection.read(1) self.slog(acknowledge, True) # if nak, we retry, if ack, we read, if other, we raise. if acknowledge == ensure_bytes(chr(ACK)): # everything alright. if not no_wait: return self.receive() return True elif acknowledge == ensure_bytes(chr(NAK)): # not everything allright. #if tries < 3: # return self.send_message(message, tries + 1, no_answer) #else: raise common.TransportLayerException("Could not send message") elif not acknowledge: # this happens quite a lot with the ingenico devices. # possibly a workaround would be nice. raise common.TransportTimeoutException( "No Answer, Possible Timeout") else: raise common.TransportLayerException( "Unknown Acknowledgment Byte %s" % conv.bs2hl(acknowledge))
def read(self, timeout=TIMEOUT_T2): """ reads a message packet. any errors are raised directly. """ # if in 5 seconds no message appears, we respond with a nak and raise an error. self.connection.timeout = timeout apdu = [] crc = None header = self.connection.read(2) header = conv.bs2hl(header) # test if there was a transmission: if header == []: raise common.TransportLayerException('Reading Header Timeout') # test our header to be valid if header != [DLE, STX]: self.slog(header, True) raise common.TransportLayerException("Header Error: %s" % header) # read until DLE, ETX is reached. dle = False # timeout to T1 after header. self.connection.timeout = TIMEOUT_T1 while not crc: b = ord(self.connection.read(1)) # read a byte. if b is None: # timeout raise common.TransportLayerException( "Timeout T1 reading stream.") if b == ETX and dle: # dle was set, and this is ETX, so we are at the end. # we read the CRC now. crc = self.connection.read(2) if not crc: raise common.TransportLayerException( "Timeout T1 reading CRC") else: crc = conv.bs2hl(crc) # and break continue elif b == DLE: if not dle: # this is a dle dle = True continue else: # this is the second dle. we take it. dle = False elif dle: # dle was set, but we got no etx here. # this seems to be an error. raise common.TransportLayerException( "DLE without sense detected.") # we add this byte to our apdu. apdu += [b] self.slog(header + apdu + [DLE, ETX] + crc, True) return crc, apdu
def dismantle_serial_packet(data): apdu = [] crc = None i = 2 header = data[:i] #header = conv.bs2hl(header) # test if there was a transmission: if header == []: raise common.TransportLayerException('No Header') # test our header to be valid if header != [DLE, STX]: raise common.TransportLayerException("Header Error: %s" % header) # read until DLE, ETX is reached. dle = False while not crc and i < len(data): b = data[i] # read a byte. if b == ETX and dle: # dle was set, and this is ETX, so we are at the end. # we read the CRC now. crc = [data[i + 1], data[i + 2]] # and break continue elif b == DLE: if not dle: # this is a dle dle = True continue else: # this is the second dle. we take it. dle = False elif dle: # dle was set, but we got no etx here. # this seems to be an error. raise Exception("DLE without sense detected.") # we add this byte to our apdu. apdu += [b] i += 1 return crc, apdu