17#include "isobus/utility/system_timing.hpp"
18#include "isobus/utility/to_string.hpp"
39 if (transferred > get_message_length())
41 transferred = get_message_length();
48 auto packetsSinceDPO =
static_cast<std::uint8_t
>(get_last_packet_number() - lastAcknowledgedPacketNumber);
49 return dataPacketOffsetPacketCount - packetsSinceDPO;
54 dataPacketOffsetPacketCount = value;
60 return dataPacketOffsetPacketCount;
65 return clearToSendPacketCountLimit;
70 clearToSendPacketCountLimit = value;
76 return lastSequenceNumber;
81 return lastSequenceNumber + sequenceNumberOffset;
86 sequenceNumberOffset = value;
92 lastSequenceNumber = value;
98 lastAcknowledgedPacketNumber = value;
104 return lastAcknowledgedPacketNumber;
109 return get_total_number_of_packets() - get_last_packet_number();
117 totalNumberOfPackets++;
119 return totalNumberOfPackets;
132 const std::shared_ptr<ControlFunction> destination,
133 std::uint32_t parameterGroupNumber,
134 std::uint32_t totalMessageSize)
139 LOG_WARNING(
"[ETP]: Replying with abort to Request To Send (RTS) for 0x%05X, configured maximum number of sessions reached.",
140 parameterGroupNumber);
145 auto oldSession =
get_session(source, destination);
146 if (
nullptr != oldSession)
148 if (oldSession->get_parameter_group_number() != parameterGroupNumber)
150 LOG_ERROR(
"[ETP]: Received Request To Send (RTS) while a session already existed for this source and destination, aborting for 0x%05X...",
151 parameterGroupNumber);
156 LOG_WARNING(
"[ETP]: Received Request To Send (RTS) while a session already existed for this source and destination and parameterGroupNumber, overwriting for 0x%05X...",
157 parameterGroupNumber);
164 parameterGroupNumber,
176 LOG_DEBUG(
"[ETP]: New rx session for 0x%05X. Source: %hu, destination: %hu", parameterGroupNumber, source->get_address(), destination->get_address());
182 const std::shared_ptr<ControlFunction> destination,
183 std::uint32_t parameterGroupNumber,
184 std::uint8_t packetsToBeSent,
185 std::uint32_t nextPacketNumber)
188 if (
nullptr != session)
190 if (session->get_parameter_group_number() != parameterGroupNumber)
192 LOG_ERROR(
"[ETP]: Received a Clear To Send (CTS) message for 0x%05X while a session already existed for this source and destination, sending abort for both...", parameterGroupNumber);
196 else if (nextPacketNumber > session->get_total_number_of_packets())
198 LOG_ERROR(
"[ETP]: Received a Clear To Send (CTS) message for 0x%05X with a bad sequence number, aborting...", parameterGroupNumber);
204 LOG_WARNING(
"[ETP]: Received a Clear To Send (CTS) message for 0x%05X, but not expecting one, aborting session->", parameterGroupNumber);
209 session->set_acknowledged_packet_number(nextPacketNumber - 1);
210 session->set_cts_number_of_packet_limit(packetsToBeSent);
214 if (0 != packetsToBeSent)
223 LOG_WARNING(
"[ETP]: Received Clear To Send (CTS) for 0x%05X while no session existed for this source and destination, ignoring...", parameterGroupNumber);
228 const std::shared_ptr<ControlFunction> destination,
229 std::uint32_t parameterGroupNumber,
230 std::uint8_t numberOfPackets,
231 std::uint32_t packetOffset)
234 if (
nullptr != session)
236 if (session->get_parameter_group_number() != parameterGroupNumber)
238 LOG_ERROR(
"[ETP]: Received a Data Packet Offset message for 0x%05X while a session already existed for this source and destination with a different PGN, sending abort for both...", parameterGroupNumber);
245 LOG_WARNING(
"[ETP]: Received a Data Packet Offset message for 0x%05X, but not expecting one, aborting session->", parameterGroupNumber);
246 abort_session(session, ConnectionAbortReason::UnexpectedDataPacketOffsetReceived);
248 else if (numberOfPackets > session->get_cts_number_of_packet_limit())
250 LOG_ERROR(
"[ETP]: Received a Data Packet Offset message for 0x%05X with an higher number of packets than our CTS, aborting...", parameterGroupNumber);
253 else if (packetOffset != session->get_last_acknowledged_packet_number())
255 LOG_ERROR(
"[ETP]: Received a Data Packet Offset message for 0x%05X with a bad sequence number, aborting...", parameterGroupNumber);
260 session->set_dpo_number_of_packets(numberOfPackets);
261 session->set_sequence_number_offset(packetOffset);
262 session->set_last_sequency_number(0);
266 if (0 != numberOfPackets)
275 LOG_WARNING(
"[ETP]: Received Data Packet Offset for 0x%05X while no session existed for this source and destination, ignoring...", parameterGroupNumber);
280 const std::shared_ptr<ControlFunction> destination,
281 std::uint32_t parameterGroupNumber,
282 std::uint32_t numberOfBytesTransferred)
285 if (
nullptr != session)
290 bool successful = (numberOfBytesTransferred == session->get_message_length());
292 LOG_DEBUG(
"[ETP]: Completed tx session for 0x%05X from %hu", parameterGroupNumber, source->get_address());
297 LOG_WARNING(
"[ETP]: Received an End Of Message Acknowledgement message for 0x%05X, but not expecting one, ignoring.", parameterGroupNumber);
302 LOG_WARNING(
"[ETP]: Received End Of Message Acknowledgement for 0x%05X while no session existed for this source and destination, ignoring.", parameterGroupNumber);
307 const std::shared_ptr<ControlFunction> destination,
308 std::uint32_t parameterGroupNumber,
311 bool foundSession =
false;
314 if ((
nullptr != session) && (session->get_parameter_group_number() == parameterGroupNumber))
317 LOG_ERROR(
"[ETP]: Received an abort (reason=%hu) for an rx session for parameterGroupNumber 0x%05X",
static_cast<std::uint8_t
>(reason), parameterGroupNumber);
321 if ((
nullptr != session) && (session->get_parameter_group_number() == parameterGroupNumber))
324 LOG_ERROR(
"[ETP]: Received an abort (reason=%hu) for a tx session for parameterGroupNumber 0x%05X",
static_cast<std::uint8_t
>(reason), parameterGroupNumber);
330 LOG_WARNING(
"[ETP]: Received an abort (reason=%hu) with no matching session for parameterGroupNumber 0x%05X",
static_cast<std::uint8_t
>(reason), parameterGroupNumber);
338 LOG_WARNING(
"[ETP]: Received a Connection Management message of invalid length %hu", message.
get_data_length());
351 parameterGroupNumber,
362 parameterGroupNumber,
374 parameterGroupNumber,
382 const auto numberOfBytesTransferred = message.
get_uint32_at(1);
385 parameterGroupNumber,
386 numberOfBytesTransferred);
395 parameterGroupNumber,
402 LOG_WARNING(
"[ETP]: Bad Mux in Transport Protocol Connection Management message");
412 LOG_WARNING(
"[ETP]: Received a Data Transfer message of invalid length %hu", message.
get_data_length());
422 if (
nullptr != session)
426 LOG_WARNING(
"[ETP]: Received a Data Transfer message from %hu while not expecting one, sending abort", source->get_address());
429 else if (sequenceNumber == session->get_last_sequence_number())
431 LOG_ERROR(
"[ETP]: Aborting rx session for 0x%05X due to duplicate sequence number", session->get_parameter_group_number());
434 else if (sequenceNumber == (session->get_last_sequence_number() + 1))
443 if (currentDataIndex < session->get_message_length())
454 session->set_last_sequency_number(sequenceNumber);
455 if (session->get_number_of_remaining_packets() == 0)
462 session->get_parameter_group_number(),
464 destination->get_address(),
465 source->get_address());
475 LOG_DEBUG(
"[ETP]: Completed rx session for 0x%05X from %hu", session->get_parameter_group_number(), source->get_address());
477 else if (session->get_dpo_number_of_packets_remaining() == 0)
485 LOG_ERROR(
"[ETP]: Aborting rx session for 0x%05X due to bad sequence number", session->get_parameter_group_number());
498 case static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolConnectionManagement):
504 case static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolDataTransfer):
517 std::unique_ptr<CANMessageData> &data,
518 std::shared_ptr<ControlFunction> source,
519 std::shared_ptr<ControlFunction> destination,
529 else if ((
nullptr == source) || (!source->get_address_valid()) ||
530 (
nullptr == destination) || (!destination->get_address_valid()) ||
539 data = data->copy_if_not_owned(std::move(data));
540 auto dataLength =
static_cast<std::uint32_t
>(data->size());
544 parameterGroupNumber,
548 sessionCompleteCallback,
551 LOG_DEBUG(
"[ETP]: New tx session for 0x%05X. Source: %hu, destination: %hu",
552 parameterGroupNumber,
553 source->get_address(),
554 destination->get_address());
567 if (!session->get_source()->get_address_valid())
569 LOG_WARNING(
"[ETP]: Closing active session as the source control function is no longer valid");
572 else if (!session->get_destination()->get_address_valid())
574 LOG_WARNING(
"[ETP]: Closing active session as the destination control function is no longer valid");
586 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer;
587 std::uint8_t framesToSend = session->get_dpo_number_of_packets_remaining();
594 for (std::uint8_t i = 0; i < framesToSend; i++)
596 buffer[0] = session->get_last_sequence_number() + 1;
601 std::uint32_t index = dataOffset + j;
602 if (index < session->get_message_length())
604 buffer[1 + j] = session->get_data().get_byte(index);
608 buffer[1 + j] = 0xFF;
612 if (
sendCANFrameCallback(
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolDataTransfer),
614 std::static_pointer_cast<InternalControlFunction>(session->get_source()),
615 session->get_destination(),
618 session->set_last_sequency_number(session->get_last_sequence_number() + 1);
627 if (session->get_number_of_remaining_packets() == 0)
631 else if (session->get_dpo_number_of_packets_remaining() == 0)
639 switch (session->state)
657 LOG_ERROR(
"[ETP]: Timeout tx session for 0x%05X (expected CTS)", session->get_parameter_group_number());
658 if (session->get_cts_number_of_packet_limit() > 0)
685 LOG_ERROR(
"[ETP]: Timeout rx session for 0x%05X (expected DPO)", session->get_parameter_group_number());
710 LOG_ERROR(
"[ETP]: Timeout for destination-specific rx session (expected sequential data frame)");
720 LOG_ERROR(
"[ETP]: Timeout tx session for 0x%05X (expected EOMA)", session->get_parameter_group_number());
731 std::shared_ptr<InternalControlFunction> myControlFunction;
732 std::shared_ptr<ControlFunction> partnerControlFunction;
735 myControlFunction = std::static_pointer_cast<InternalControlFunction>(session->get_source());
736 partnerControlFunction = session->get_destination();
740 myControlFunction = std::static_pointer_cast<InternalControlFunction>(session->get_destination());
741 partnerControlFunction = session->get_source();
744 if ((
nullptr != myControlFunction) && (
nullptr != partnerControlFunction))
746 retVal =
send_abort(myControlFunction, partnerControlFunction, session->get_parameter_group_number(), reason);
753 std::shared_ptr<ControlFunction> receiver,
754 std::uint32_t parameterGroupNumber,
757 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
759 static_cast<std::uint8_t
>(reason),
763 static_cast<std::uint8_t
>(parameterGroupNumber & 0xFF),
764 static_cast<std::uint8_t
>((parameterGroupNumber >> 8) & 0xFF),
765 static_cast<std::uint8_t
>((parameterGroupNumber >> 16) & 0xFF)
767 return sendCANFrameCallback(
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolConnectionManagement),
776 session->complete(successful);
781 LOG_DEBUG(
"[ETP]: Session Closed");
787 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
789 static_cast<std::uint8_t
>(session->get_message_length() & 0xFF),
790 static_cast<std::uint8_t
>((session->get_message_length() >> 8) & 0xFF),
791 static_cast<std::uint8_t
>((session->get_message_length() >> 16) & 0xFF),
792 static_cast<std::uint8_t
>((session->get_message_length() >> 24) & 0xFF),
793 static_cast<std::uint8_t
>(session->get_parameter_group_number() & 0xFF),
794 static_cast<std::uint8_t
>((session->get_parameter_group_number() >> 8) & 0xFF),
795 static_cast<std::uint8_t
>((session->get_parameter_group_number() >> 16) & 0xFF)
797 return sendCANFrameCallback(
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolConnectionManagement),
799 std::static_pointer_cast<InternalControlFunction>(session->get_source()),
800 session->get_destination(),
806 std::uint32_t nextPacketNumber = session->get_last_packet_number() + 1;
807 std::uint8_t packetLimit = session->get_cts_number_of_packet_limit();
809 if (packetLimit > session->get_number_of_remaining_packets())
811 packetLimit =
static_cast<std::uint8_t
>(session->get_number_of_remaining_packets());
814 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
817 static_cast<std::uint8_t
>(nextPacketNumber & 0xFF),
818 static_cast<std::uint8_t
>((nextPacketNumber >> 8) & 0xFF),
819 static_cast<std::uint8_t
>((nextPacketNumber >> 16) & 0xFF),
820 static_cast<std::uint8_t
>(session->get_parameter_group_number() & 0xFF),
821 static_cast<std::uint8_t
>((session->get_parameter_group_number() >> 8) & 0xFF),
822 static_cast<std::uint8_t
>((session->get_parameter_group_number() >> 16) & 0xFF)
824 bool retVal =
sendCANFrameCallback(
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolConnectionManagement),
826 std::static_pointer_cast<InternalControlFunction>(session->get_destination()),
827 session->get_source(),
831 session->set_acknowledged_packet_number(session->get_last_packet_number());
838 std::uint8_t packetsThisSegment = 0xFF;
839 if (packetsThisSegment > session->get_number_of_remaining_packets())
841 packetsThisSegment =
static_cast<std::uint8_t
>(session->get_number_of_remaining_packets());
844 if (packetsThisSegment > session->get_cts_number_of_packet_limit())
846 packetsThisSegment = session->get_cts_number_of_packet_limit();
848 if (packetsThisSegment > configuration->get_number_of_packets_per_dpo_message())
850 LOG_DEBUG(
"[TP]: Received Request To Send (RTS) with a CTS packet count of %hu, which is greater than the configured maximum of %hu, using the configured maximum instead.",
852 configuration->get_number_of_packets_per_dpo_message());
853 packetsThisSegment = configuration->get_number_of_packets_per_dpo_message();
856 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
857 DATA_PACKET_OFFSET_MULTIPLXOR,
859 static_cast<std::uint8_t
>(session->get_last_packet_number()),
860 static_cast<std::uint8_t
>((session->get_last_packet_number() >> 8) & 0xFF),
861 static_cast<std::uint8_t
>((session->get_last_packet_number() >> 16) & 0xFF),
862 static_cast<std::uint8_t
>(session->get_parameter_group_number() & 0xFF),
863 static_cast<std::uint8_t
>((session->get_parameter_group_number() >> 8) & 0xFF),
864 static_cast<std::uint8_t
>((session->get_parameter_group_number() >> 16) & 0xFF)
866 bool retVal = sendCANFrameCallback(
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolConnectionManagement),
868 std::static_pointer_cast<InternalControlFunction>(session->get_source()),
869 session->get_destination(),
873 session->set_dpo_number_of_packets(packetsThisSegment);
874 session->set_sequence_number_offset(session->get_last_packet_number());
875 session->set_last_sequency_number(0);
882 std::uint32_t messageLength = session->get_message_length();
883 std::uint32_t parameterGroupNumber = session->get_parameter_group_number();
885 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
887 static_cast<std::uint8_t
>(messageLength & 0xFF),
888 static_cast<std::uint8_t
>((messageLength >> 8) & 0xFF),
889 static_cast<std::uint8_t
>((messageLength >> 16) & 0xFF),
890 static_cast<std::uint8_t
>((messageLength >> 24) & 0xFF),
891 static_cast<std::uint8_t
>(parameterGroupNumber & 0xFF),
892 static_cast<std::uint8_t
>((parameterGroupNumber >> 8) & 0xFF),
893 static_cast<std::uint8_t
>((parameterGroupNumber >> 16) & 0xFF),
896 return sendCANFrameCallback(
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ExtendedTransportProtocolConnectionManagement),
898 std::static_pointer_cast<InternalControlFunction>(session->get_destination()),
899 session->get_source(),
905 return std::any_of(
activeSessions.begin(),
activeSessions.end(), [&](
const std::shared_ptr<ExtendedTransportProtocolSession> &session) {
906 return session->matches(source, destination);
911 std::shared_ptr<ControlFunction> destination)
913 auto result = std::find_if(
activeSessions.begin(),
activeSessions.end(), [&](
const std::shared_ptr<ExtendedTransportProtocolSession> &session) {
914 return session->matches(source, destination);
A protocol class that handles the ISO11783 extended transport protocol. Designed for destination spec...
Defines some PGNs that are used in the library or are very common.
A representation of an ISOBUS ECU that we can send from. Use this class when defining your own contro...
An abstraction of a CAN message, could be > 8 data bytes.
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
A utility class that allows easy interpretation of a 32 bit CAN identifier.
@ PriorityLowest7
The lowest priority.
@ PriorityDefault6
The default priority.
std::uint32_t get_parameter_group_number() const
Returns the PGN encoded in the identifier.
@ Extended
Frame is a modern 29 bit ID CAN frame.
A class that represents data of a CAN message by holding a vector of bytes.
void set_byte(std::size_t index, std::uint8_t value)
Set the byte at the given index.
A class that represents a generic CAN message of arbitrary length.
@ Receive
Message is being received.
std::uint32_t get_data_length() const
Returns the length of the data in the CAN message.
bool has_valid_source_control_function() const
Returns whether the message is sent by a device that claimed its address on the bus.
std::uint32_t get_uint24_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a right-aligned 24-bit integer from the buffer (returned as a uint32_t) at a specific index....
std::shared_ptr< ControlFunction > get_source_control_function() const
Gets the source control function that the message is from.
std::uint8_t get_uint8_at(const std::uint32_t index) const
Get a 8-bit unsigned byte from the buffer at a specific index. A 8-bit unsigned byte can hold a value...
CANIdentifier get_identifier() const
Returns the identifier of the message.
std::uint32_t get_uint32_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 32-bit unsigned integer from the buffer at a specific index. A 32-bit unsigned integer can hold...
std::shared_ptr< ControlFunction > get_destination_control_function() const
Gets the destination control function that the message is to.
bool is_destination_our_device() const
Returns whether the message is destined for our device on the bus.
A class that defines stack-wide configuration data. You can set the values in there to suit your spec...
std::uint8_t get_max_number_of_network_manager_protocol_frames_per_update() const
Returns the max number of data frames the stack will send from each transport layer protocol,...
std::uint32_t get_max_number_transport_protocol_sessions() const
Returns the max number of concurrent TP sessions.
std::uint8_t get_number_of_packets_per_dpo_message() const
Returns the max number of data frames the stack will use when in an ETP session, between EDPO phases....
std::uint32_t get_last_acknowledged_packet_number() const
Get the last acknowledged packet number by the receiver.
std::uint32_t get_last_packet_number() const
Get the last packet number that was processed.
std::uint8_t get_dpo_number_of_packets_remaining() const
Get the number of packets to be sent with the current DPO.
std::uint8_t get_last_sequence_number() const
Get the last sequence number that was processed.
StateMachineState get_state() const
< Inherit the base constructor
void set_last_sequency_number(std::uint8_t value)
Set the last sequence number that has be processed.
std::uint8_t get_cts_number_of_packet_limit() const
Get the maximum number of packets that can be sent per DPO as indicated by the CTS message.
void set_cts_number_of_packet_limit(std::uint8_t value)
Set the maximum number of packets that can be sent per DPO as indicated by the CTS message.
void set_dpo_number_of_packets(std::uint8_t value)
Set the number of packets to be sent with the current DPO.
void set_sequence_number_offset(std::uint32_t value)
Set the last packet number that was processed.
std::uint32_t get_total_number_of_packets() const
Get the total number of packets that will be sent or received in this session.
void set_acknowledged_packet_number(std::uint32_t value)
Set the last acknowledged packet number by the receiver.
std::uint32_t get_number_of_remaining_packets() const
Get the number of packets that remain to be sent or received in this session.
StateMachineState state
The state machine state for this session.
std::uint32_t get_total_bytes_transferred() const override
Get the number of bytes that have been sent or received in this session.
std::uint8_t get_dpo_number_of_packets() const
Get the number of packets that will be sent with the current DPO.
void set_state(StateMachineState value)
Set the state of the session.
static constexpr std::uint16_t T1_TIMEOUT_MS
The t1 timeout as defined by the standard.
void process_message(const CANMessage &message)
A generic way for a protocol to process a received message.
bool send_request_to_send(std::shared_ptr< ExtendedTransportProtocolSession > &session) const
Sends the "request to send" message as part of initiating a transmit.
bool abort_session(std::shared_ptr< ExtendedTransportProtocolSession > &session, ConnectionAbortReason reason)
Aborts the session with the specified abort reason. Sends a CAN message.
static constexpr std::uint8_t PROTOCOL_BYTES_PER_FRAME
The number of payload bytes per frame minus overhead of sequence number.
void process_abort(const std::shared_ptr< ControlFunction > source, const std::shared_ptr< ControlFunction > destination, std::uint32_t parameterGroupNumber, ExtendedTransportProtocolManager::ConnectionAbortReason reason)
Processes an abort message in the CAN transport protocol.
void process_clear_to_send(const std::shared_ptr< ControlFunction > source, const std::shared_ptr< ControlFunction > destination, std::uint32_t parameterGroupNumber, std::uint8_t packetsToBeSent, std::uint32_t nextPacketNumber)
Processes the Clear To Send (CTS) message.
void send_data_transfer_packets(std::shared_ptr< ExtendedTransportProtocolSession > &session) const
Sends data transfer packets for the specified ExtendedTransportProtocolSession.
const CANMessageFrameCallback sendCANFrameCallback
A callback for sending a CAN frame.
void process_data_packet_offset(const std::shared_ptr< ControlFunction > source, const std::shared_ptr< ControlFunction > destination, std::uint32_t parameterGroupNumber, std::uint8_t numberOfPackets, std::uint32_t packetOffset)
Processes the Data Packet Offset (DPO) message.
bool send_end_of_session_acknowledgement(std::shared_ptr< ExtendedTransportProtocolSession > &session) const
Sends the "end of message acknowledgement" message for the provided session.
std::shared_ptr< ExtendedTransportProtocolSession > get_session(std::shared_ptr< ControlFunction > source, std::shared_ptr< ControlFunction > destination)
Gets a ETP session from the passed in source and destination and PGN combination.
const std::vector< std::shared_ptr< ExtendedTransportProtocolSession > > & get_sessions() const
Gets all the active transport protocol sessions that are currently active.
ExtendedTransportProtocolManager(const CANMessageFrameCallback &sendCANFrameCallback, const CANMessageCallback &canMessageReceivedCallback, const CANNetworkConfiguration *configuration)
The constructor for the ExtendedTransportProtocolManager, for advanced use only. In most cases,...
static constexpr std::uint32_t CLEAR_TO_SEND_MULTIPLEXOR
(21) ETP.CM_CTS Multiplexor
std::vector< std::shared_ptr< ExtendedTransportProtocolSession > > activeSessions
A list of all active ETP sessions.
void update()
Updates all sessions managed by this protocol manager instance.
void process_request_to_send(const std::shared_ptr< ControlFunction > source, const std::shared_ptr< ControlFunction > destination, std::uint32_t parameterGroupNumber, std::uint32_t totalMessageSize)
Processes a request to send a message over the CAN transport protocol.
const CANNetworkConfiguration * configuration
The configuration to use for this protocol.
static constexpr std::uint32_t END_OF_MESSAGE_ACKNOWLEDGE_MULTIPLEXOR
(23) TP.CM_EOMA Multiplexor
bool send_abort(std::shared_ptr< InternalControlFunction > sender, std::shared_ptr< ControlFunction > receiver, std::uint32_t parameterGroupNumber, ConnectionAbortReason reason) const
Send an abort with no corresponding session with the specified abort reason. Sends a CAN message.
void update_state_machine(std::shared_ptr< ExtendedTransportProtocolSession > &session)
Update the state machine for the passed in session.
static constexpr std::uint8_t SEQUENCE_NUMBER_DATA_INDEX
The index of the sequence number in a frame.
const CANMessageCallback canMessageReceivedCallback
A callback for when a complete CAN message is received using the ETP protocol.
bool protocol_transmit_message(std::uint32_t parameterGroupNumber, std::unique_ptr< CANMessageData > &data, std::shared_ptr< ControlFunction > source, std::shared_ptr< ControlFunction > destination, TransmitCompleteCallback sessionCompleteCallback, void *parentPointer)
The network manager calls this to see if the protocol can accept a long CAN message for processing.
static constexpr std::uint32_t CONNECTION_ABORT_MULTIPLEXOR
(255) Abort multiplexor
void close_session(std::shared_ptr< ExtendedTransportProtocolSession > &session, bool successful)
Gracefully closes a session to prepare for a new session.
void process_end_of_session_acknowledgement(const std::shared_ptr< ControlFunction > source, const std::shared_ptr< ControlFunction > destination, std::uint32_t parameterGroupNumber, std::uint32_t numberOfBytesTransferred)
Processes the end of session acknowledgement.
static constexpr std::uint32_t MAX_PROTOCOL_DATA_LENGTH
The max number of bytes that this protocol can transfer.
static constexpr std::uint16_t T2_T3_TIMEOUT_MS
The t2/t3 timeouts as defined by the standard.
void process_data_transfer_message(const CANMessage &message)
Processes a data transfer message.
bool send_data_packet_offset(std::shared_ptr< ExtendedTransportProtocolSession > &session) const
Sends the "data packet offset" message for the provided session.
bool send_clear_to_send(std::shared_ptr< ExtendedTransportProtocolSession > &session) const
Sends the "clear to send" message.
static constexpr std::uint32_t DATA_PACKET_OFFSET_MULTIPLXOR
(22) ETP.CM_DPO Multiplexor
bool has_session(std::shared_ptr< ControlFunction > source, std::shared_ptr< ControlFunction > destination)
Checks if the source and destination control function have an active session/connection.
void process_connection_management_message(const CANMessage &message)
Processes a connection management message.
StateMachineState
The states that a ETP session could be in. Used for the internal state machine.
@ WaitForEndOfMessageAcknowledge
We are waiting for an end of message acknowledgement.
@ SendClearToSend
We are sending clear to send message.
@ SendRequestToSend
We are sending the request to send message.
@ WaitForDataTransferPacket
We are waiting for data transfer packets.
@ WaitForClearToSend
We are waiting for a clear to send message.
@ SendDataPacketOffset
We are sending a data packet offset message.
@ None
Protocol session is not in progress.
@ WaitForDataPacketOffset
We are waiting for a data packet offset message.
@ SendDataTransferPackets
A Tx data session is in progress.
static constexpr std::uint32_t REQUEST_TO_SEND_MULTIPLEXOR
(20) ETP.CM_RTS Multiplexor
ConnectionAbortReason
A list of all defined abort reasons in ISO11783.
@ DataPacketOffsetExceedsClearToSend
Received a number of packets in EDPO greater than CTS.
@ DuplicateSequenceNumber
Re-received a sequence number we've already processed.
@ BadSequenceNumber
Incorrect sequence number was received and cannot be recovered.
@ AlreadyInCMSession
We are already in a connection mode session and can't support another.
@ ClearToSendReceivedWhileTransferInProgress
A CTS was received while already processing the last CTS.
@ Timeout
General timeout.
@ NumberOfClearToSendPacketsExceedsMessage
Received a CTS with a number of packets greater than the message.
@ UnexpectedDataPacketOffsetPGN
Received a data packet offset with an unexpected PGN.
@ UnexpectedDataTransferPacketReceived
A data packet was received outside the proper state.
@ BadDataPacketOffset
Received a data packet offset that is incorrect.
@ Receive
We are receiving a message.
@ Transmit
We are transmitting a message.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
DataSpan< const std::uint8_t > CANDataSpan
A read-only span of data for a CAN message.
std::function< bool(std::uint32_t parameterGroupNumber, CANDataSpan data, std::shared_ptr< InternalControlFunction > sourceControlFunction, std::shared_ptr< ControlFunction > destinationControlFunction, CANIdentifier::CANPriority priority)> CANMessageFrameCallback
A callback for communicating CAN message frames.
void(*)(std::uint32_t parameterGroupNumber, std::uint32_t dataLength, std::shared_ptr< InternalControlFunction > sourceControlFunction, std::shared_ptr< ControlFunction > destinationControlFunction, bool successful, void *parentPointer) TransmitCompleteCallback
A callback for when a transmit is completed by the stack.
constexpr std::uint8_t CAN_DATA_LENGTH
The length of a classical CAN frame.
std::function< void(const CANMessage &message)> CANMessageCallback
A callback for communicating CAN messages.