def request(self, cmd, *data): self.logger.debug(cmd.name) self.parent._setService(cmd) cmdlen = cmd.bit_length() // 8 # calculate bytes needed for cmd header = self.HEADER.pack(cmdlen + len(data), self.counterSend) self.counterSend = (self.counterSend + 1) & 0xffff frame = header + bytes(flatten(cmd.to_bytes(cmdlen, 'big'), data)) self.logger.debug("-> {}".format(hexDump(frame))) self.timing.start() self.send(frame) try: xcpPDU = self.resQueue.get(timeout=2.0) except queue.Empty: if PYTHON_VERSION >= (3, 3): raise types.XcpTimeoutError("Response timed out.") from None else: raise types.XcpTimeoutError("Response timed out.") self.resQueue.task_done() # TODO: move up!? self.timing.stop() pid = types.Response.parse(xcpPDU).type if pid == 'ERR' and cmd.name != 'SYNCH': err = types.XcpError.parse(xcpPDU[1:]) raise types.XcpResponseError(err) else: pass # Und nu?? return xcpPDU[1:]
def request(self, cmd, *data): self.logger.debug(cmd.name) header = struct.pack("<HH", len(data) + 1, self.counterSend) self.counterSend += 1 self.counterSend &= 0xffff frame = header + bytearray([cmd, *data]) self.logger.debug("-> {}".format(hexDump(frame))) self.timing.start() self.send(frame) try: xcpPDU = self.resQueue.get(timeout=2.0) except queue.Empty: if PYTHON_VERSION >= (3, 3): raise types.XcpTimeoutError("Response timed out.") from None else: raise types.XcpTimeoutError("Response timed out.") self.resQueue.task_done() # TODO: move up!? self.timing.stop() pid = types.Response.parse(xcpPDU).type if pid == 'ERR' and cmd.name != 'SYNCH': err = types.XcpError.parse(xcpPDU[1:]) raise types.XcpResponseError(err) else: pass # Und nu?? return xcpPDU[1:]
def block_receive(self, length_required: int) -> bytes: """ Implements packet reception for block communication model (e.g. for XCP on CAN) Parameters ---------- length_required: int number of bytes to be expected in block response packets Returns ------- bytes all payload bytes received in block response packets Raises ------ :class:`pyxcp.types.XcpTimeoutError` """ TIMEOUT = 1.0 # TODO: parameter. block_response = b'' start = time() while len(block_response) < length_required: if len(self.resQueue): partial_response = self.resQueue.popleft() block_response += partial_response[1:] else: if time() - start > TIMEOUT: raise types.XcpTimeoutError("Response timed out [block_receive].") from None sleep(0.001) return block_response
def _request_internal(self, cmd, ignore_timeout=False, *data): frame = self._prepare_request(cmd, *data) self.timing.start() self.send(frame) try: xcpPDU = get( self.resQueue, timeout=self.timeout, restart_event=self.timer_restart_event, ) except Empty: if not ignore_timeout: raise types.XcpTimeoutError( "Response timed out (timeout={}s)".format( self.timeout)) from None else: self.timing.stop() return self.timing.stop() pid = types.Response.parse(xcpPDU).type if pid == "ERR" and cmd.name != "SYNCH": err = types.XcpError.parse(xcpPDU[1:]) raise types.XcpResponseError(err) else: pass # Und nu?? return xcpPDU[1:]
def block_receive(self, length_required: int) -> bytes: """ Implements packet reception for block communication model (e.g. for XCP on CAN) :param length_required: number of bytes to be expected in block response packets :return: all payload bytes received in block response packets """ block_response = b'' while len(block_response) < length_required: try: partial_response = self.resQueue.get(timeout=2.0) block_response += partial_response[1:] except queue.Empty: raise types.XcpTimeoutError("Response timed out.") from None return block_response
def request(self, cmd, *data): frame = self._prepare_request(cmd, *data) self.timing.start() self.send(frame) try: xcpPDU = get(self.resQueue, timeout=2.0) except Empty: raise types.XcpTimeoutError("Response timed out.") from None self.timing.stop() pid = types.Response.parse(xcpPDU).type if pid == 'ERR' and cmd.name != 'SYNCH': err = types.XcpError.parse(xcpPDU[1:]) raise types.XcpResponseError(err) else: pass # Und nu?? return xcpPDU[1:]
def listen(self): HEADER_UNPACK = self.HEADER.unpack HEADER_SIZE = self.HEADER_SIZE use_tcp = self.use_tcp processResponse = self.processResponse EVENT_READ = selectors.EVENT_READ close_event_set = self.closeEvent.isSet socket_fileno = self.sock.fileno select = self.selector.select high_resolution_time = self.perf_counter_origin > 0 timestamp_origin = self.timestamp_origin perf_counter_origin = self.perf_counter_origin if use_tcp: sock_recv = self.sock.recv else: sock_recv = self.sock.recvfrom while True: try: if close_event_set() or socket_fileno() == -1: return sel = select(0.1) for _, events in sel: if events & EVENT_READ: if high_resolution_time: recv_timestamp = time() else: recv_timestamp = timestamp_origin + perf_counter() - perf_counter_origin if use_tcp: # first try to get the header in one go # if we are lucky this will avoid creating a # bytearray and extending it header = sock_recv(HEADER_SIZE) size = len(header) if size != HEADER_SIZE: start = perf_counter() header = bytearray(header) while len(header) != HEADER_SIZE: header.extend( sock_recv(HEADER_SIZE - len(header)) ) if perf_counter() - start > 2: raise types.XcpTimeoutError("Eth frame header read timed out.") from None length, counter = HEADER_UNPACK(header) try: # first try to get the response in one go # similar to the header response = sock_recv(length) size = len(response) if size != length: start = perf_counter() response = bytearray(response) while len(response) != length: response.extend( sock_recv(length - len(response)) ) if perf_counter() - start > 2: raise types.XcpTimeoutError("Eth frame payload read timed out.") from None except Exception as e: self.logger.error(str(e)) continue else: try: response, _ = sock_recv( Eth.MAX_DATAGRAM_SIZE ) length, counter = HEADER_UNPACK( response[:HEADER_SIZE] ) response = response[HEADER_SIZE:] if len(response) != length: raise types.FrameSizeError("Size mismatch.") except Exception as e: self.logger.error(str(e)) continue processResponse(response, length, counter, recv_timestamp) except Exception: self.status = 0 # disconnected break