def send(self, msg, timeout=None):
        if not ics.validate_hobject(self.dev):
            raise CanError("bus not open")
        message = ics.SpyMessage()

        flag0 = 0
        if msg.is_extended_id:
            flag0 |= ics.SPY_STATUS_XTD_FRAME
        if msg.is_remote_frame:
            flag0 |= ics.SPY_STATUS_REMOTE_FRAME

        flag3 = 0
        if msg.is_fd:
            message.Protocol = ics.SPY_PROTOCOL_CANFD
            if msg.bitrate_switch:
                flag3 |= ics.SPY_STATUS3_CANFD_BRS
            if msg.error_state_indicator:
                flag3 |= ics.SPY_STATUS3_CANFD_ESI

        message.ArbIDOrHeader = msg.arbitration_id
        msg_data = msg.data
        message.NumberBytesData = len(msg_data)
        message.Data = tuple(msg_data[:8])
        if msg.is_fd and len(msg_data) > 8:
            message.ExtraDataPtrEnabled = 1
            message.ExtraDataPtr = tuple(msg_data)
        message.StatusBitField = flag0
        message.StatusBitField2 = 0
        message.StatusBitField3 = flag3
        if msg.channel is not None:
            message.NetworkID = msg.channel
        elif len(self.channels) == 1:
            message.NetworkID = self.channels[0]
        else:
            raise ValueError(
                "msg.channel must be set when using multiple channels.")

        try:
            ics.transmit_messages(self.dev, message)
        except ics.RuntimeError:
            raise ICSApiError(*ics.get_last_api_error(self.dev))
Beispiel #2
0
    def send(self, msg, timeout=0):
        """Transmit a message to the CAN bus.

        :param Message msg: A message object.

        :param float timeout:
            If > 0, wait up to this many seconds for message to be ACK'ed.
            If timeout is exceeded, an exception will be raised.
            None blocks indefinitely.

        :raises can.CanError:
            if the message could not be sent
        """
        if not ics.validate_hobject(self.dev):
            raise CanError("bus not open")
        message = ics.SpyMessage()

        flag0 = 0
        if msg.is_extended_id:
            flag0 |= ics.SPY_STATUS_XTD_FRAME
        if msg.is_remote_frame:
            flag0 |= ics.SPY_STATUS_REMOTE_FRAME

        flag3 = 0
        if msg.is_fd:
            message.Protocol = ics.SPY_PROTOCOL_CANFD
            if msg.bitrate_switch:
                flag3 |= ics.SPY_STATUS3_CANFD_BRS
            if msg.error_state_indicator:
                flag3 |= ics.SPY_STATUS3_CANFD_ESI

        message.ArbIDOrHeader = msg.arbitration_id
        msg_data = msg.data
        message.NumberBytesData = len(msg_data)
        message.Data = tuple(msg_data[:8])
        if msg.is_fd and len(msg_data) > 8:
            message.ExtraDataPtrEnabled = 1
            message.ExtraDataPtr = tuple(msg_data)
        message.StatusBitField = flag0
        message.StatusBitField2 = 0
        message.StatusBitField3 = flag3
        if msg.channel is not None:
            message.NetworkID = msg.channel
        elif len(self.channels) == 1:
            message.NetworkID = self.channels[0]
        else:
            raise ValueError(
                "msg.channel must be set when using multiple channels.")

        msg_desc_id = next(description_id)
        message.DescriptionID = msg_desc_id
        receipt_key = (msg.arbitration_id, msg_desc_id)

        if timeout != 0:
            self.message_receipts[receipt_key].clear()

        try:
            ics.transmit_messages(self.dev, message)
        except ics.RuntimeError:
            raise ICSApiError(*ics.get_last_api_error(self.dev))

        # If timeout is set, wait for ACK
        # This requires a notifier for the bus or
        # some other thread calling recv periodically
        if timeout != 0 and not self.message_receipts[receipt_key].wait(
                timeout):
            raise CanError("Transmit timeout")