Пример #1
0
    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:]
Пример #2
0
    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:]
Пример #3
0
    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
Пример #4
0
    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:]
Пример #5
0
 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
Пример #6
0
    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:]
Пример #7
0
    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