def _recv_packet(self, allow_recovery_skip=False): buf_1 = self._link.recv(1 + protocol.LEN_FIELD_SIZE) start_marker = buf_1[0] packet_len = int.from_bytes(buf_1[1:], protocol.BO) if start_marker != protocol.START_MARKER: raise ClientError("got invalid frame (incorrect start marker)") buf_2 = self._link.recv(packet_len + 2) packet = buf_2[:-1] end_marker = buf_2[-1] if end_marker != protocol.END_MARKER: if not allow_recovery_skip: raise ClientError("got invalid frame (incorrect end marker)") log.debug( "got invalid frame (incorrect end marker), attempting recovery" ) buf_2.extend(self._link.recv(1 + protocol.LEN_FIELD_SIZE)) si = 0 ei = len(buf_2) expected_sub_len = protocol.LEN_FIELD_SIZE + packet_len + 3 while True: si = buf_2.find(buf_1, si, ei) if si < 0: raise ClientError( "got invalid frame and could not recover") sub_len_diff = expected_sub_len - (len(buf_2) - si) if sub_len_diff > 0: buf_2.extend(self._link.recv(sub_len_diff)) if buf_2[-1] != protocol.END_MARKER: log.debug("recovery attempt failed") continue packet = buf_2[si + 1 + protocol.LEN_FIELD_SIZE:-1] break log.warning("successfully recovered from corrupt frame") return protocol.unpack_packet(packet)
def test_unpack_packet(): unpacked = ptcl.unpack_packet(pkd_reg_read_res_packet) assert unpacked == unp_reg_read_res