예제 #1
0
    def _data_transfer_handler(self, msg):
        msg_source = msg.arbitration_id.source_address
        pdu_specific = msg.arbitration_id.pgn.pdu_specific

        if msg_source in self._incomplete_received_pdus:

            if pdu_specific in self._incomplete_received_pdus[msg_source]:
                self._incomplete_received_pdus[msg_source][pdu_specific].data.extend(msg.data[1:])
                total = self._incomplete_received_pdu_lengths[msg_source][pdu_specific]["total"]
                if len(self._incomplete_received_pdus[msg_source][pdu_specific].data) >= total:
                    if pdu_specific == DESTINATION_ADDRESS_GLOBAL:
                        # Looks strange but makes sense - in the absence of explicit flow control,
                        # the last CAN packet in a long message *is* the end of message acknowledgement
                        return self._process_eom_ack(msg)

                    # Find a Node object so we can search its list of known node addresses for this node
                    # so we can find if we are responsible for sending the EOM ACK message
					# TODO: Was self.j1939_notifier.listeners
                    send_ack = any(True for l in self.can_notifier.listeners
                                   if isinstance(l, Node) and (l.address == pdu_specific or
                                                               pdu_specific in l.address_list))
                    if send_ack:
                        arbitration_id = ArbitrationID()
                        arbitration_id.pgn.value = PGN_TP_CONNECTION_MANAGEMENT
                        arbitration_id.pgn.pdu_specific = msg_source
                        arbitration_id.source_address = pdu_specific
                        total_length = self._incomplete_received_pdu_lengths[msg_source][pdu_specific]["total"]
                        _num_packages = self._incomplete_received_pdu_lengths[msg_source][pdu_specific]["num_packages"]
                        pgn = self._incomplete_received_pdus[msg_source][pdu_specific].arbitration_id.pgn
                        pgn_msb = ((pgn.value & 0xFF0000) >> 16)
                        _pgn_middle = ((pgn.value & 0x00FF00) >> 8)
                        _pgn_lsb = 0

                        div, mod = divmod(total_length, 256)
                        can_message = Message(arbitration_id=arbitration_id.can_id,
                                              extended_id=True,
                                              dlc=8,
                                              data=[CM_MSG_TYPE_EOM_ACK,
                                                    mod,  # total_length % 256,
                                                    div,  # total_length / 256,
                                                    _num_packages,
                                                    0xFF,
                                                    _pgn_lsb,
                                                    _pgn_middle,
                                                    pgn_msb])
                        self.can_bus.send(can_message)

                    return self._process_eom_ack(msg)
예제 #2
0
    def _data_transfer_handler(self, msg):
        logger.debug("_data_transfer_handler:")
        msg_source = msg.arbitration_id.source_address
        pdu_specific = msg.arbitration_id.pgn.pdu_specific

        if msg_source in self._incomplete_received_pdus:

            logger.debug("in self._incomplete_received_pdus:")
            if pdu_specific in self._incomplete_received_pdus[msg_source]:
                logger.debug("in self._incomplete_received_pdus[msg_source]:")
                self._incomplete_received_pdus[msg_source][
                    pdu_specific].data.extend(msg.data[1:])
                total = self._incomplete_received_pdu_lengths[msg_source][
                    pdu_specific]["total"]
                if len(self._incomplete_received_pdus[msg_source]
                       [pdu_specific].data) >= total:
                    logger.debug(
                        "allReceived: %s" %
                        type(self._incomplete_received_pdus[msg_source]))
                    logger.debug("allReceived: %s" % pprint.pformat(
                        self._incomplete_received_pdus[msg_source]))
                    logger.debug(
                        "allReceived: %s from 0x%x" %
                        (type(self._incomplete_received_pdus[msg_source]
                              [pdu_specific]), pdu_specific))
                    logger.debug("allReceived: %s" %
                                 (self._incomplete_received_pdus[msg_source]
                                  [pdu_specific]))
                    if pdu_specific == DESTINATION_ADDRESS_GLOBAL:
                        logger.debug(
                            "pdu_specific == DESTINATION_ADDRESS_GLOBAL")
                        # Looks strange but makes sense - in the absence of explicit flow control,
                        # the last CAN packet in a long message *is* the end of message acknowledgement
                        return self._process_eom_ack(msg)

                    # Find a Node object so we can search its list of known node addresses for this node
                    # so we can find if we are responsible for sending the EOM ACK message
                    # TODO: Was self.j1939_notifier.listeners

                    send_ack = any(
                        True
                        for (_listener, l_notifier) in self.node_queue_list
                        if isinstance(_listener, Node) and (
                            _listener.address == pdu_specific
                            or pdu_specific in _listener.address_list))

                    #send_ack = any(True for l in self.can_notifier.listeners
                    #               if isinstance(l, Node) and (l.address == pdu_specific or
                    #                                           pdu_specific in l.address_list))
                    if send_ack:
                        arbitration_id = ArbitrationID()
                        arbitration_id.pgn.value = PGN_TP_CONNECTION_MANAGEMENT
                        arbitration_id.pgn.pdu_specific = msg_source
                        arbitration_id.source_address = pdu_specific
                        arbitration_id.destination_address = 0x17

                        total_length = self._incomplete_received_pdu_lengths[
                            msg_source][pdu_specific]["total"]
                        _num_packages = self._incomplete_received_pdu_lengths[
                            msg_source][pdu_specific]["num_packages"]
                        pgn = self._incomplete_received_pdus[msg_source][
                            pdu_specific].arbitration_id.pgn
                        pgn_msb = ((pgn.value & 0xFF0000) >> 16)
                        _pgn_middle = ((pgn.value & 0x00FF00) >> 8)
                        _pgn_lsb = 0

                        logger.debug(
                            "in send_ack: arbitration_id=[%s], can_id=[%x], destAdder=0x%0x"
                            % (arbitration_id, int(arbitration_id.can_id),
                               arbitration_id.destination_address))
                        logger.debug("in send_ack: " % ())
                        div, mod = divmod(total_length, 256)
                        can_message = Message(
                            arbitration_id=arbitration_id.can_id,
                            extended_id=True,
                            dlc=8,
                            data=[
                                CM_MSG_TYPE_EOM_ACK,
                                mod,  # total_length % 256,
                                div,  # total_length / 256,
                                _num_packages,
                                0xFF,
                                _pgn_lsb,
                                _pgn_middle,
                                pgn_msb
                            ])
                        try:
                            self.can_bus.send(can_message)
                        except CanError:
                            if self._ignore_can_send_error:
                                pass
                            raise

                    logger.debug("_data_transfer_handler: returning %s" %
                                 (msg))
                    return self._process_eom_ack(msg)