def _wait_recv(self, error_count, retry, timeout): ''' Waits for a <NAK> or <CRC> before starting the transmission. Return <NAK> or <CRC> on success, ``False`` in case of failure ''' # Initialize protocol cancel = 0 # Loop until the first character is a control character (NAK, CRC) or # we reach the retry limit while True: char = self.getc(1) print char ; if char: if char in [NAK, CRC]: print "char is NAK or CRC" return char elif char == CAN: # Cancel at two consecutive cancels if cancel: log.error(error.ABORT_RECV_CAN_CAN) self.abort(timeout=timeout) return False else: log.debug(error.DEBUG_RECV_CAN) cancel = 1 else: # Ignore the rest pass error_count += 1 if error_count >= retry: self.abort(timeout=timeout) return False
def _recv_bin32_header(self, timeout): ''' Receive a header with 32 bit CRC. ''' header = [] mine = 0 for x in xrange(0, 5): char = self._recv(timeout) if char is TIMEOUT: return 0, False else: mine = self.calc_crc32(chr(char), mine) header.append(char) # Read their crc rcrc = self._recv(timeout) rcrc |= self._recv(timeout) << 0x08 rcrc |= self._recv(timeout) << 0x10 rcrc |= self._recv(timeout) << 0x18 log.debug('My CRC = %08x, theirs = %08x' % (mine, rcrc)) if mine != rcrc: log.error('Invalid CRC32 in header') return 0, False else: return 5, header
def _recv_hex_header(self, timeout): ''' Receive a header with HEX encoding. ''' header = [] mine = 0 for x in xrange(0, 5): char = self._recv_hex(timeout) if char is TIMEOUT: return TIMEOUT mine = self.calc_crc16(chr(char), mine) header.append(char) # Read their crc char = self._recv_hex(timeout) if char is TIMEOUT: return TIMEOUT rcrc = char << 0x08 char = self._recv_hex(timeout) if char is TIMEOUT: return TIMEOUT rcrc |= char log.debug('My CRC = %04x, theirs = %04x' % (mine, rcrc)) if mine != rcrc: log.error('Invalid CRC16 in receiving HEX header') return 0, False # Read to see if we receive a carriage return char = self.getc(1, timeout) if char == '\r': # Expect a second one (which we discard) self.getc(1, timeout) return 5, header
def _recv_32_data(self, timeout): char = 0 data = [] mine = 0 while char < 0x100: char = self._recv(timeout) if char is TIMEOUT: return TIMEOUT, '' elif char < 0x100: mine = self.calc_crc32(chr(char & 0xff), mine) data.append(chr(char)) # Calculate our crc, unescape the sub_frame_kind sub_frame_kind = char ^ ZDLEESC mine = self.calc_crc32(chr(sub_frame_kind), mine) # Read their crc rcrc = self._recv(timeout) rcrc |= self._recv(timeout) << 0x08 rcrc |= self._recv(timeout) << 0x10 rcrc |= self._recv(timeout) << 0x18 log.debug('My CRC = %08x, theirs = %08x' % (mine, rcrc)) if mine != rcrc: log.error('Invalid CRC32') return timeout, '' else: return sub_frame_kind, ''.join(data)
def _wait_recv(self, error_count, timeout): ''' Waits for a <NAK> or <CRC> before starting the transmission. Return <NAK> or <CRC> on success, ``False`` in case of failure ''' # Initialize protocol cancel = 0 # Loop until the first character is a control character (NAK, CRC) or # we reach the retry limit while True: char = self.getc(1) if char: if char in [NAK, CRC]: return char elif char == CAN: # Cancel at two consecutive cancels if cancel: log.error(error.ABORT_RECV_CAN_CAN) self.abort(timeout=timeout) return False else: log.debug(error.DEBUG_RECV_CAN) cancel = 1 else: # Ignore the rest pass error_count += 1 if error_count >= retry: self.abort(timeout=timeout) return False
def _send_stream(self, stream, crc_mode, retry=16, timeout=0): ''' Sends a stream according to the given protocol dialect: >>> stream = file('/etc/issue', 'rb') >>> print modem.send(stream) True Return ``True`` on success, ``False`` in case of failure. ''' # Get packet size for current protocol packet_size = PACKET_SIZE.get(self.protocol, 128) # ASSUME THAT I'VE ALREADY RECEIVED THE INITIAL <CRC> OR <NAK> # SO START DIRECTLY WITH STREAM TRANSMISSION sequence = 1 error_count = 0 while True: data = stream.read(packet_size) # Check if we're done sending if not data: break # Select optimal packet size when using YMODEM if self.protocol == PROTOCOL_YMODEM: packet_size = (len(data) <= 128) and 128 or 1024 # Align the packet data = data.ljust(packet_size, '\x00') # Calculate CRC or checksum crc = crc_mode and self.calc_crc16(data) or \ self.calc_checksum(data) # SENDS PACKET WITH CRC if not self._send_packet(sequence, data, packet_size, crc_mode, crc, error_count, retry, timeout): log.error(error.ERROR_SEND_PACKET) return False # Next sequence sequence = (sequence + 1) % 0x100 # STREAM FINISHED, SEND EOT log.debug(error.DEBUG_SEND_EOT) if self._send_eot(error_count, retry, timeout): return True else: log.error(error.ERROR_SEND_EOT) return False
def _send_stream(self, stream, crc_mode, retry=16, timeout=0): ''' Sends a stream according to the given protocol dialect: >>> stream = file('/etc/issue', 'rb') >>> print modem.send(stream) True Return ``True`` on success, ``False`` in case of failure. ''' # Get packet size for current protocol packet_size = PACKET_SIZE.get(self.protocol, 128) # ASSUME THAT I'VE ALREADY RECEIVED THE INITIAL <CRC> OR <NAK> # SO START DIRECTLY WITH STREAM TRANSMISSION sequence = 1 error_count = 0 while True: data = stream.read(packet_size) # Check if we're done sending if not data: break # Select optimal packet size when using YMODEM if self.protocol == PROTOCOL_YMODEM: packet_size = (len(data) <= 128) and 128 or 1024 # Align the packet data = data.ljust(packet_size, b'\x00') # Calculate CRC or checksum crc = crc_mode and self.calc_crc16(data) or \ self.calc_checksum(data) # SENDS PACKET WITH CRC if not self._send_packet(sequence, data, packet_size, crc_mode, crc, error_count, retry, timeout): log.error(error.ERROR_SEND_PACKET) return False # Next sequence sequence = (sequence + 1) % 0x100 # STREAM FINISHED, SEND EOT log.debug(error.DEBUG_SEND_EOT) if self._send_eot(error_count, retry, timeout): return True else: log.error(error.ERROR_SEND_EOT) return False
def send(self, stream, retry=16, timeout=60): ''' Send a stream via the XMODEM1K protocol. >>> stream = file('/etc/issue', 'rb') >>> print modem.send(stream) True Returns ``True`` upon succesful transmission or ``False`` in case of failure. ''' # initialize protocol error_count = 0 crc_mode = 0 cancel = 0 while True: char = self.getc(1) if char: if char == NAK: crc_mode = 0 break elif char == CRC: crc_mode = 1 break elif char == CAN: if cancel: log.debug(error.DEBUG_RECV_CAN) return False else: log.error(error.ABORT_RECV_CAN_CAN) cancel = 1 else: log.error(error.ERROR_EXPECT_NAK_CRC % ord(char)) error_count += 1 if error_count >= retry: self.abort(timeout=timeout) return False if self._send_stream(stream, crc_mode, retry, timeout): return True else: log.error(error.ABORT_SEND_STREAM) return False
def recv(self, stream, crc_mode=1, retry=16, timeout=60, delay=1): ''' Receive a stream via the XMODEM1K protocol. >>> stream = file('/etc/issue', 'wb') >>> print modem.recv(stream) 2342 Returns the number of bytes received on success or ``None`` in case of failure. ''' # initiate protocol error_count = 0 char = 0 cancel = 0 while True: # first try CRC mode, if this fails, # fall back to checksum mode if error_count >= retry: self.abort(timeout=timeout) return None elif crc_mode and error_count < (retry / 2): if not self.putc(CRC): time.sleep(delay) error_count += 1 else: crc_mode = 0 if not self.putc(NAK): time.sleep(delay) error_count += 1 char = self.getc(1, timeout) if char is None: error_count += 1 continue elif char == SOH: #crc_mode = 0 break elif char in [STX, CAN]: break elif char == CAN: if cancel: return None else: cancel = 1 else: error_count += 1 # read data error_count = 0 income_size = 0 packet_size = 128 sequence = 1 cancel = 0 while True: while True: if char == SOH: packet_size = 128 break elif char == STX: packet_size = 1024 break elif char == EOT: # SEND LAST <ACK> self.putc(ACK) return income_size elif char == CAN: # cancel at two consecutive cancels if cancel: log.error(error.ABORT_RECV_CAN_CAN) return None else: log.debug(error.DEBUG_RECV_CAN) cancel = 1 else: log.error(error.ERROR_EXPECT_SOH_EOT % ord(char)) error_count += 1 if error_count >= retry: self.abort() return None # read sequence error_count = 0 cancel = 0 seq1 = ord(self.getc(1)) seq2 = 0xff - ord(self.getc(1)) if seq1 == sequence and seq2 == sequence: # sequence is ok, read packet # packet_size + checksum data = self.getc(packet_size + 1 + crc_mode) data = self._check_crc(data, crc_mode) # valid data, append chunk if data: income_size += len(data) stream.write(data) self.putc(ACK) sequence = (sequence + 1) % 0x100 char = self.getc(1, timeout) continue else: # consume data self.getc(packet_size + 1 + crc_mode) log.debug(error.ERROR_INVALID_SEQ) # something went wrong, request retransmission self.putc(NAK)
def recv(self, stream, crc_mode=1, retry=16, timeout=60, delay=1, quiet=0): ''' Receive a stream via the XMODEM protocol. >>> stream = file('/etc/issue', 'wb') >>> print modem.recv(stream) 2342 Returns the number of bytes received on success or ``None`` in case of failure. ''' # initiate protocol error_count = 0 char = 0 cancel = 0 while True: # first try CRC mode, if this fails, # fall back to checksum mode if error_count >= retry: log.error(error.ABORT_ERROR_LIMIT) self.abort(timeout=timeout) return None elif crc_mode and error_count < (retry / 2): log.debug(error.DEBUG_TRY_CRC) if not self.putc(CRC): time.sleep(delay) error_count += 1 else: log.debug(error.DEBUG_TRY_CHECKSUM) crc_mode = 0 if not self.putc(NAK): time.sleep(delay) error_count += 1 char = self.getc(1, timeout) if char is None: error_count += 1 continue elif char in [SOH, STX]: break elif char == CAN: if cancel: log.error(error.ABORT_RECV_CAN_CAN) return None else: log.debug(error.DEBUG_RECV_CAN) cancel = 1 else: error_count += 1 # read data error_count = 0 income_size = 0 packet_size = 128 sequence = 1 cancel = 0 while True: while True: if char == SOH: packet_size = 128 break elif char == EOT: # Acknowledge end of transmission self.putc(ACK) return income_size elif char == CAN: # We abort if we receive two consecutive <CAN> bytes if cancel: return None else: cancel = 1 else: log.debug(error.DEBUG_EXPECT_SOH_EOT % repr(char)) error_count += 1 if error_count >= retry: self.abort() return None # read sequence error_count = 0 cancel = 0 # FIXME check error seq1 = self.getc(1)[0] seq2 = 0xff - self.getc(1)[0] if seq1 == sequence and seq2 == sequence: # sequence is ok, read packet # packet_size + checksum data = self._check_crc(self.getc(packet_size + 1 + crc_mode), crc_mode) # valid data, append chunk if data: income_size += len(data) stream.write(data) self.putc(ACK) sequence = (sequence + 1) % 0x100 char = self.getc(1, timeout) continue else: # consume data self.getc(packet_size + 1 + crc_mode) log.warning(error.WARNS_SEQUENCE % (sequence, seq1, seq2)) # something went wrong, request retransmission self.putc(NAK)
def _recv_stream(self, stream, crc_mode, retry, timeout, delay): ''' Receives data and write it on a stream. It assumes the protocol has already been initialized (<CRC> or <NAK> sent and optional packet 0 received). On success it exits after an <EOT> and returns the number of bytes received. In case of failure returns ``False``. ''' # IN CASE OF YMODEM THE FILE IS ALREADY OPEN AND THE PACKET 0 RECEIVED error_count = 0 cancel = 0 sequence = 1 income_size = 0 self.putc(CRC) char = self.getc(1, timeout) while True: if char is None: error_count += 1 if error_count >= retry: log.error(error.ABORT_ERROR_LIMIT) self.abort(timeout=timeout) return None else: continue elif char == CAN: if cancel: return None else: cancel = 1 elif char in [SOH, STX]: packet_size = 128 if char == SOH else 1024 # Check the requested packet size, only YMODEM has a variable # size if self.protocol != PROTOCOL_YMODEM and \ PACKET_SIZE.get(self.protocol) != packet_size: log.error(error.ABORT_PACKET_SIZE) self.abort(timeout=timeout) return False # FIXME check error seq1 = self.getc(1)[0] seq2 = 0xff - self.getc(1)[0] if seq1 == sequence and seq2 == sequence: data = self.getc(packet_size + 1 + crc_mode) data = self._check_crc(data, crc_mode) if data: # Append data to the stream income_size += len(data) stream.write(data) self.putc(ACK) sequence = (sequence + 1) % 0x100 # Waiting for new packet char = self.getc(1, timeout) continue # Sequence numbering is off or CRC is incorrect, request new # packet self.getc(packet_size + 1 + crc_mode) self.putc(NAK) elif char == EOT: # We are done, acknowledge <EOT> self.putc(ACK) return income_size elif char == CAN: # Cancel at two consecutive cancels if cancel: return False else: cancel = 1 self.putc(ACK) char = self.getc(1, timeout) continue else: log.debug(error.DEBUG_EXPECT_SOH_EOT % repr(char)) error_count += 1 if error_count >= retry: log.error(error.ABORT_ERROR_LIMIT) self.abort() return False
def recv(self, basedir, crc_mode=1, retry=16, timeout=60, delay=1): ''' Receive some files via the YMODEM protocol and place them under ``basedir``:: >>> print modem.recv(basedir) 3 Returns the number of files received on success or ``None`` in case of failure. N.B.: currently there are no control on the existence of files, so they will be silently overwritten. ''' # Initiate protocol error_count = 0 char = 0 cancel = 0 sequence = 0 num_files = 0 while True: # First try CRC mode, if this fails, fall back to checksum mode if error_count >= retry: self.abort(timeout=timeout) return None elif crc_mode and error_count < (retry / 2): if not self.putc(CRC): time.sleep(delay) error_count += 1 else: crc_mode = 0 if not self.putc(NAK): time.sleep(delay) error_count += 1 # <CRC> or <NAK> sent, waiting answer char = self.getc(1, timeout) if char is None: error_count += 1 continue elif char == CAN: if cancel: log.error(error.ABORT_RECV_CAN_CAN) return None else: log.debug(error.DEBUG_RECV_CAN) cancel = 1 continue elif char in [SOH, STX]: break else: error_count += 1 continue # Receiver loop fileout = None while True: # Read next file in batch mode while True: if char is None: error_count += 1 elif char == CAN: if cancel: log.error(error.ABORT_RECV_CAN_CAN) return None else: log.debug(debug.DEBUG_RECV_CAN) cancel = 1 continue elif char in [SOH, STX]: seq1 = ord(self.getc(1)) seq2 = 0xff - ord(self.getc(1)) if seq1 == sequence and seq2 == sequence: packet_size = 128 if char == SOH else 1024 data = self.getc(packet_size + 1 + crc_mode) data = self._check_crc(data, crc_mode) if data: filename = data.split('\x00')[0] if not filename: # No filename, end of batch reception self.putc(ACK) return num_files log.info('Receiving %s to %s' % (filename, basedir)) fileout = open( os.path.join(basedir, os.path.basename(filename)), 'wb') if not fileout: log.error(error.ABORT_OPEN_FILE) self.putc(NAK) self.abort(timeout=timeout) return False else: self.putc(ACK) break # Request retransmission if something went wrong self.getc(packet_size + 1 + crc_mode) self.putc(NAK) self.getc(1, timeout) continue else: error_count += 1 self.getc(packet_size + 1 + crc_mode) self.putc(NAK) self.getc(1, timeout) stream_size = self._recv_stream(fileout, crc_mode, retry, timeout, delay) if not stream_size: log.error(error.ABORT_RECV_STREAM) return False log.debug('File transfer done, requesting next') fileout.close() num_files += 1 sequence = 0 # Ask for the next sequence and receive the reply self.putc(CRC) char = self.getc(1, timeout)
def recv(self, stream, crc_mode=1, retry=16, timeout=60, delay=1, quiet=0): ''' Receive a stream via the XMODEM protocol. >>> stream = file('/etc/issue', 'wb') >>> print modem.recv(stream) 2342 Returns the number of bytes received on success or ``None`` in case of failure. ''' # initiate protocol error_count = 0 char = 0 cancel = 0 while True: # first try CRC mode, if this fails, # fall back to checksum mode if error_count >= retry: log.error(error.ABORT_ERROR_LIMIT) self.abort(timeout=timeout) return None elif crc_mode and error_count < (retry / 2): log.debug(error.DEBUG_TRY_CRC) if not self.putc(CRC): time.sleep(delay) error_count += 1 else: log.debug(error.DEBUG_TRY_CHECKSUM) crc_mode = 0 if not self.putc(NAK): time.sleep(delay) error_count += 1 char = self.getc(1, timeout) if char is None: error_count += 1 continue elif char in [SOH, STX]: break elif char == CAN: if cancel: log.error(error.ABORT_RECV_CAN_CAN) return None else: log.debug(error.DEBUG_RECV_CAN) cancel = 1 else: error_count += 1 # read data error_count = 0 income_size = 0 packet_size = 128 sequence = 1 cancel = 0 while True: while True: if char == SOH: packet_size = 128 break elif char == EOT: # Acknowledge end of transmission self.putc(ACK) return income_size elif char == CAN: # We abort if we receive two consecutive <CAN> bytes if cancel: return None else: cancel = 1 else: log.debug(error.DEBUG_EXPECT_SOH_EOT % ord(char)) error_count += 1 if error_count >= retry: self.abort() return None # read sequence error_count = 0 cancel = 0 seq1 = ord(self.getc(1)) seq2 = 0xff - ord(self.getc(1)) if seq1 == sequence and seq2 == sequence: # sequence is ok, read packet # packet_size + checksum data = self._check_crc(self.getc(packet_size + 1 + crc_mode), crc_mode) # valid data, append chunk if data: income_size += len(data) stream.write(data) self.putc(ACK) sequence = (sequence + 1) % 0x100 char = self.getc(1, timeout) continue else: # consume data self.getc(packet_size + 1 + crc_mode) log.warning(error.WARNS_SEQUENCE % (sequence, seq1, seq2)) # something went wrong, request retransmission self.putc(NAK)
def _recv_stream(self, stream, crc_mode, retry, timeout, delay): ''' Receives data and write it on a stream. It assumes the protocol has already been initialized (<CRC> or <NAK> sent and optional packet 0 received). On success it exits after an <EOT> and returns the number of bytes received. In case of failure returns ``False``. ''' # IN CASE OF YMODEM THE FILE IS ALREADY OPEN AND THE PACKET 0 RECEIVED error_count = 0 cancel = 0 sequence = 1 income_size = 0 self.putc(CRC) char = self.getc(1, timeout) while True: if char is None: error_count += 1 if error_count >= retry: log.error(error.ABORT_ERROR_LIMIT) self.abort(timeout=timeout) return None else: continue elif char == CAN: if cancel: return None else: cancel = 1 elif char in [SOH, STX]: packet_size = 128 if char == SOH else 1024 # Check the requested packet size, only YMODEM has a variable # size if self.protocol != PROTOCOL_YMODEM and \ PACKET_SIZE.get(self.protocol) != packet_size: log.error(error.ABORT_PACKET_SIZE) self.abort(timeout=timeout) return False seq1 = ord(self.getc(1)) seq2 = 0xff - ord(self.getc(1)) if seq1 == sequence and seq2 == sequence: data = self.getc(packet_size + 1 + crc_mode) data = self._check_crc(data, crc_mode) if data: # Append data to the stream income_size += len(data) stream.write(data) self.putc(ACK) sequence = (sequence + 1) % 0x100 # Waiting for new packet char = self.getc(1, timeout) continue # Sequence numbering is off or CRC is incorrect, request new # packet self.getc(packet_size + 1 + crc_mode) self.putc(NAK) elif char == EOT: # We are done, acknowledge <EOT> self.putc(ACK) return income_size elif char == CAN: # Cancel at two consecutive cancels if cancel: return False else: cancel = 1 self.putc(ACK) char = self.getc(1, timeout) continue else: log.debug(error.DEBUG_EXPECT_SOH_EOT % ord(char)) error_count += 1 if error_count >= retry: log.error(error.ABORT_ERROR_LIMIT) self.abort() return False
def _send_zrinit(self, timeout): log.debug('Sending ZRINIT header') header = [ZRINIT, 0, 0, 0, 4 | ZF0_CANFDX | ZF0_CANOVIO | ZF0_CANFC32] self._send_hex_header(header, timeout)
def send(self, pattern, retry=10, timeout=60): ''' Send one or more files via the YMODEM protocol. >>> print modem.send('*.txt') True Returns ``True`` upon succesful transmission or ``False`` in case of failure. ''' # Get a list of files to send filenames = glob.glob(pattern) # filenames = 'mixer.bin' if not filenames: return True # initialize protocol error_count = 0 crc_mode = 0 start_char = self._wait_recv(error_count, timeout, retry) if start_char: crc_mode = 1 if (start_char == CRC) else 0 else: log.error(error.ABORT_PROTOCOL) # Already aborted return False for filename in filenames: # Send meta data packet sequence = 0 error_count = 0 # Add filesize filesize = os.path.getsize(filename) data = ''.join( [os.path.basename(filename), '\x00', str(filesize), '\x00']) log.debug(error.DEBUG_START_FILENAME % (filename, )) # Pick a suitable packet length for the filename packet_size = 128 if (len(data) < 128) else 1024 # Packet padding data = data.ljust(packet_size, '\0') # Calculate checksum crc = crc32_byte(list(bytearray(data.encode()))) # Emit packet if not self._send_packet(sequence, data, packet_size, crc_mode, crc, error_count, retry, timeout): self.abort(timeout=timeout) return False # Wait for <CRC> before transmitting the file contents error_count = 0 if not self._wait_recv(error_count, timeout, retry): self.abort(timeout) return False filedesc = open(filename, 'rb') # AT THIS POINT # - PACKET 0 WITH METADATA TRANSMITTED # - INITIAL <CRC> OR <NAK> ALREADY RECEIVED if not self._send_stream(filedesc, crc_mode, retry, timeout): log.error(error.ABORT_SEND_STREAM) return False # AT THIS POINT # - FILE CONTENTS TRANSMITTED # - <EOT> TRANSMITTED # - <ACK> RECEIVED filedesc.close() # WAIT A <CRC> BEFORE NEXT FILE error_count = 0 if not self._wait_recv(error_count, timeout, retry): log.error(error.ABORT_INIT_NEXT) # Already aborted return False # End of batch transmission, send NULL file name sequence = 0 error_count = 0 packet_size = 128 data = '\x00' * packet_size crc = crc32_byte(list(bytearray(data.encode()))) # Emit packet if not self._send_packet(sequence, data, packet_size, crc_mode, crc, error_count, retry, timeout): log.error(error.ABORT_SEND_PACKET) # Already aborted return False # All went fine return True
def recv(self, basedir, crc_mode=1, retry=16, timeout=60, delay=1): ''' Receive some files via the YMODEM protocol and place them under ``basedir``:: >>> print modem.recv(basedir) 3 Returns the number of files received on success or ``None`` in case of failure. N.B.: currently there are no control on the existence of files, so they will be silently overwritten. ''' # Initiate protocol error_count = 0 char = 0 cancel = 0 sequence = 0 num_files = 0 while True: # First try CRC mode, if this fails, fall back to checksum mode if error_count >= retry: self.abort(timeout=timeout) return None elif crc_mode and error_count < (retry / 2): if not self.putc(CRC): time.sleep(delay) error_count += 1 else: crc_mode = 0 if not self.putc(NAK): time.sleep(delay) error_count += 1 # <CRC> or <NAK> sent, waiting answer char = self.getc(1, timeout) if char is None: error_count += 1 continue elif char == CAN: if cancel: log.error(error.ABORT_RECV_CAN_CAN) return None else: log.debug(error.DEBUG_RECV_CAN) cancel = 1 continue elif char in [SOH, STX]: break else: error_count += 1 continue # Receiver loop fileout = None while True: # Read next file in batch mode while True: if char is None: error_count += 1 elif char == CAN: if cancel: log.error(error.ABORT_RECV_CAN_CAN) return None else: log.debug(debug.DEBUG_RECV_CAN) cancel = 1 continue elif char in [SOH, STX]: seq1 = ord(self.getc(1)) seq2 = 0xff - ord(self.getc(1)) if seq1 == sequence and seq2 == sequence: packet_size = 128 if char == SOH else 1024 data = self.getc(packet_size + 1 + crc_mode) data = self._check_crc(data, crc_mode) if data: filename = data.split('\x00')[0] if not filename: # No filename, end of batch reception self.putc(ACK) return num_files log.info('Receiving %s to %s' % (filename, basedir)) fileout = open(os.path.join(basedir, os.path.basename(filename)), 'wb') if not fileout: log.error(error.ABORT_OPEN_FILE) self.putc(NAK) self.abort(timeout=timeout) return False else: self.putc(ACK) break # Request retransmission if something went wrong self.getc(packet_size + 1 + crc_mode) self.putc(NAK) self.getc(1, timeout) continue else: error_count += 1 self.getc(packet_size + 1 + crc_mode) self.putc(NAK) self.getc(1, timeout) stream_size = self._recv_stream(fileout, crc_mode, retry, timeout, delay) if not stream_size: log.error(error.ABORT_RECV_STREAM) return False log.debug('File transfer done, requesting next') fileout.close() num_files += 1 sequence = 0 # Ask for the next sequence and receive the reply self.putc(CRC) char = self.getc(1, timeout)