From c2e18e7902e3a061923695899f2395266d4335c0 Mon Sep 17 00:00:00 2001 From: rayRayray <60754400+hezy0426@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:59:15 -0500 Subject: [PATCH] Add new parameter to choose between BAM and RTS for Transport Protocol --- j1939/controller_application.py | 9 +++++++-- j1939/electronic_control_unit.py | 4 ++-- j1939/j1939_21.py | 13 +++++++++---- j1939/j1939_22.py | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/j1939/controller_application.py b/j1939/controller_application.py index df15549..7a054ff 100644 --- a/j1939/controller_application.py +++ b/j1939/controller_application.py @@ -1,6 +1,7 @@ import logging import j1939 from .message_id import FrameFormat +from .j1939_21 import J1939_21 logger = logging.getLogger(__name__) @@ -253,7 +254,7 @@ def send_message(self, priority, parameter_group_number, data): mid = j1939.MessageId(priority=priority, parameter_group_number=parameter_group_number, source_address=self._device_address) self._ecu.send_message(mid.can_id, True, data) - def send_pgn(self, data_page, pdu_format, pdu_specific, priority, data, time_limit=0, frame_format=FrameFormat.FEFF): + def send_pgn(self, data_page, pdu_format, pdu_specific, priority, data, time_limit=0, frame_format=FrameFormat.FEFF, tp_connection_mode=J1939_21.ConnectionMode.ABORT): """send a pgn :param int data_page: data page :param int pdu_format: pdu format @@ -263,11 +264,15 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, data, time_lim :param time_limit: option j1939-22 multi-pg: specify a time limit in s (e.g. 0.1 == 100ms), after this time, the multi-pg will be sent. several pgs can thus be combined in one multi-pg. 0 or no time-limit means immediate sending. + :param tp_connection_mode: optional to j1939-21. specify a TP method to be used. If it's left to the default value, + then TP messages will be chosen between BAM or RTS/CTS based on following criteria: + # if the PF is between 0 and 239, the message is destination dependent when pdu_specific != 255 + # if the PF is between 240 and 255, the message can only be broadcast """ if self.state != ControllerApplication.State.NORMAL: raise RuntimeError("Could not send message unless address claiming has finished") - return self._ecu.send_pgn(data_page, pdu_format, pdu_specific, priority, self._device_address, data, time_limit, frame_format) + return self._ecu.send_pgn(data_page, pdu_format, pdu_specific, priority, self._device_address, data, time_limit, frame_format, tp_connection_mode) def send_request(self, data_page, pgn, destination): """send a request message diff --git a/j1939/electronic_control_unit.py b/j1939/electronic_control_unit.py index 16fb98e..a38edd6 100644 --- a/j1939/electronic_control_unit.py +++ b/j1939/electronic_control_unit.py @@ -226,7 +226,7 @@ def remove_notifier(self): self._notifier.remove_listener(listener) self._notifier = None - def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit=0, frame_format=FrameFormat.FEFF): + def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit=0, frame_format=FrameFormat.FEFF, tp_connection_mode=J1939_21.ConnectionMode.ABORT): """send a pgn :param int data_page: data page :param int pdu_format: pdu format @@ -238,7 +238,7 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d after this time, the multi-pg will be sent. several pgs can thus be combined in one multi-pg. 0 or no time-limit means immediate sending. """ - return self.j1939_dll.send_pgn(data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format) + return self.j1939_dll.send_pgn(data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format, tp_connection_mode) def send_message(self, can_id, extended_id, data, fd_format=False): """Send a raw CAN message to the bus. diff --git a/j1939/j1939_21.py b/j1939/j1939_21.py index 75553eb..cf39224 100644 --- a/j1939/j1939_21.py +++ b/j1939/j1939_21.py @@ -89,7 +89,7 @@ def _buffer_hash(self, src_address, dest_address): """ return ((src_address & 0xFF) << 8) | (dest_address & 0xFF) - def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format): + def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format, tp_connection_mode): pgn = ParameterGroupNumber(data_page, pdu_format, pdu_specific) if len(data) <= 8: # send normal message @@ -112,8 +112,8 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d message_size = len(data) num_packets = int(message_size / 7) if (message_size % 7 == 0) else int(message_size / 7) + 1 - # if the PF is between 240 and 255, the message can only be broadcast - if dest_address == ParameterGroupNumber.Address.GLOBAL: + # if the PF is between 240 and 255 or users choose to use BAM, send message with broadcast + if dest_address == ParameterGroupNumber.Address.GLOBAL or tp_connection_mode == self.ConnectionMode.BAM: # send BAM self.__send_tp_bam(src_address, priority, pgn.value, message_size, num_packets) @@ -130,7 +130,12 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d 'dest_address' : ParameterGroupNumber.Address.GLOBAL, 'next_packet_to_send' : 0, } - else: + + # Since we want to send the BAM to a target address + if tp_connection_mode == self.ConnectionMode.BAM: + self._snd_buffer[buffer_hash]['dest_address'] = pdu_specific + + elif dest_address != ParameterGroupNumber.Address.GLOBAL or tp_connection_mode in [self.ConnectionMode.RTS, self.ConnectionMode.CTS]: # send RTS/CTS pgn.pdu_specific = 0 # this is 0 for peer-to-peer transfer # init new buffer for this connection diff --git a/j1939/j1939_22.py b/j1939/j1939_22.py index c55cf93..d84d6db 100644 --- a/j1939/j1939_22.py +++ b/j1939/j1939_22.py @@ -190,7 +190,7 @@ def __get_rts_cts_session(self): def __put_rts_cts_session(self, session): self.__rts_cts_session_list[session] = True - def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format, tos=2, trailer_format=0): + def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format, tp_connection_mode, tos=2, trailer_format=0): pgn = ParameterGroupNumber(data_page, pdu_format, pdu_specific) data_length = len(data)