19#include "isobus/utility/system_timing.hpp"
20#include "isobus/utility/to_string.hpp"
94 std::shared_ptr<InternalControlFunction> retVal =
nullptr;
96 if ((
nullptr != controlFunction) &&
99 retVal = std::static_pointer_cast<InternalControlFunction>(controlFunction);
107 constexpr float ISOBUS_BAUD_RATE_BPS = 250000.0f;
114 retVal = (0 != totalTimeInAccumulatorWindow) ? ((totalBitCount / (totalTimeInAccumulatorWindow * ISOBUS_BAUD_RATE_BPS)) * 100.0f) : 0.0f;
120 const std::uint8_t *dataBuffer,
121 std::uint32_t dataLength,
122 std::shared_ptr<InternalControlFunction> sourceControlFunction,
123 std::shared_ptr<ControlFunction> destinationControlFunction,
131 if (((
nullptr != dataBuffer) ||
132 (
nullptr != frameChunkCallback)) &&
135 (
nullptr != sourceControlFunction) &&
136 ((parameterGroupNumber ==
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::AddressClaim)) ||
137 (sourceControlFunction->get_address_valid())))
139 std::unique_ptr<CANMessageData> messageData;
140 if (
nullptr != frameChunkCallback)
148 if (
transportProtocols[sourceControlFunction->get_can_port()]->protocol_transmit_message(parameterGroupNumber,
150 sourceControlFunction,
151 destinationControlFunction,
152 transmitCompleteCallback,
160 sourceControlFunction,
161 destinationControlFunction,
162 transmitCompleteCallback,
171 (
nullptr != dataBuffer))
173 if (
nullptr == destinationControlFunction)
176 retVal =
send_can_message_raw(sourceControlFunction->get_can_port(), sourceControlFunction->get_address(), 0xFF, parameterGroupNumber,
static_cast<std::uint8_t
>(priority), dataBuffer, dataLength);
178 else if (destinationControlFunction->get_address_valid())
180 retVal =
send_can_message_raw(sourceControlFunction->get_can_port(), sourceControlFunction->get_address(), destinationControlFunction->get_address(), parameterGroupNumber,
static_cast<std::uint8_t
>(priority), dataBuffer, dataLength);
184 (
nullptr != transmitCompleteCallback))
187 transmitCompleteCallback(parameterGroupNumber, dataLength, sourceControlFunction, destinationControlFunction, retVal, parentPointer);
197 LOCK_GUARD(Mutex, processingMutex);
233 std::uint8_t sourceAddress,
234 std::uint8_t destAddress,
235 std::uint32_t parameterGroupNumber,
236 std::uint8_t priority,
241 return send_can_message_raw(portIndex, sourceAddress, destAddress, parameterGroupNumber, priority, data, size);
316 heartBeatInterfaces.at(controlFunction->canPortIndex)->on_destroyed_internal_control_function(std::static_pointer_cast<InternalControlFunction>(controlFunction));
334 if (i != controlFunction->get_address())
336 LOG_WARNING(
"[NM]: %s control function with address '%d' was at incorrect address '%d' in the lookup table prior to deletion.",
337 controlFunction->get_type_string().c_str(),
338 controlFunction->get_address(),
357 LOG_INFO(
"[NM]: %s control function with address '%d' is deleted.",
358 controlFunction->get_type_string().c_str(),
359 controlFunction->get_address());
370 heartBeatInterfaces.at(controlFunction->canPortIndex)->on_new_internal_control_function(std::static_pointer_cast<InternalControlFunction>(controlFunction));
380 if (
nullptr != callback)
389 if (
nullptr != callback)
414 std::list<std::shared_ptr<ControlFunction>> retVal;
416 for (std::uint8_t channelIndex = 0; channelIndex <
CAN_PORT_MAXIMUM; channelIndex++)
420 if (
nullptr != controlFunctionTable[channelIndex][address])
422 retVal.push_back(controlFunctionTable[channelIndex][address]);
427 if (includingOffline)
429 retVal.insert(retVal.end(), inactiveControlFunctions.begin(), inactiveControlFunctions.end());
437 std::list<std::shared_ptr<TransportProtocolSessionBase>> retVal;
438 retVal.insert(retVal.end(), transportProtocols[canPortIndex]->get_sessions().begin(), transportProtocols[canPortIndex]->get_sessions().end());
439 retVal.insert(retVal.end(), extendedTransportProtocols[canPortIndex]->get_sessions().begin(), extendedTransportProtocols[canPortIndex]->get_sessions().end());
482 if (
nullptr != callback)
484 std::list<ParameterGroupNumberCallbackData>::iterator callbackLocation;
502 auto send_frame_callback = [
this](std::uint32_t parameterGroupNumber,
504 std::shared_ptr<InternalControlFunction> sourceControlFunction,
505 std::shared_ptr<ControlFunction> destinationControlFunction,
510 auto receive_message_callback = [
this, i](
const CANMessage &message) {
513 message.get_identifier(),
515 message.get_source_control_function(),
516 message.get_destination_control_function(),
536 if ((
nullptr != targetControlFunction) &&
543 LOG_INFO(
"[NM]: %s CF '%016llx' is evicted from address '%d' on channel '%d', as their address is probably stolen.",
544 targetControlFunction->get_type_string().c_str(),
545 targetControlFunction->get_NAME().get_full_name(),
548 targetControlFunction =
nullptr;
551 if (targetControlFunction !=
nullptr)
553 targetControlFunction->claimedAddressSinceLastAddressClaimRequest =
true;
560 if ((currentControlFunction->get_address() == claimedAddress) &&
561 (currentControlFunction->get_can_port() == channelIndex))
564 LOG_DEBUG(
"[NM]: %s CF '%016llx' is now active at address '%d' on channel '%d'.",
565 currentControlFunction->get_type_string().c_str(),
566 currentControlFunction->get_NAME().get_full_name(),
580 if (
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::AddressClaim) == requestedPGN)
586 return (channelIndex == controlFunction->get_can_port());
590 (*result)->claimedAddressSinceLastAddressClaimRequest =
true;
593 if (
nullptr != controlFunction)
595 controlFunction->claimedAddressSinceLastAddressClaimRequest =
false;
606 if (currentInternalControlFunction->update_address_claiming({}))
608 std::uint8_t channelIndex = currentInternalControlFunction->get_can_port();
609 std::uint8_t claimedAddress = currentInternalControlFunction->get_address();
666 std::uint64_t claimedNAME;
667 std::shared_ptr<ControlFunction> foundControlFunction =
nullptr;
670 claimedNAME = rxFrame.
data[0];
671 claimedNAME |= (
static_cast<std::uint64_t
>(rxFrame.
data[1]) << 8);
672 claimedNAME |= (
static_cast<std::uint64_t
>(rxFrame.
data[2]) << 16);
673 claimedNAME |= (
static_cast<std::uint64_t
>(rxFrame.
data[3]) << 24);
674 claimedNAME |= (
static_cast<std::uint64_t
>(rxFrame.
data[4]) << 32);
675 claimedNAME |= (
static_cast<std::uint64_t
>(rxFrame.
data[5]) << 40);
676 claimedNAME |= (
static_cast<std::uint64_t
>(rxFrame.
data[6]) << 48);
677 claimedNAME |= (
static_cast<std::uint64_t
>(rxFrame.
data[7]) << 56);
682 [claimedNAME](
const std::shared_ptr<ControlFunction> &cf) {
683 return (nullptr != cf) && (cf->controlFunctionNAME.get_full_name() == claimedNAME);
687 foundControlFunction = *activeResult;
693 [claimedNAME, &rxFrame](
const std::shared_ptr<ControlFunction> &cf) {
694 return (cf->controlFunctionNAME.get_full_name() == claimedNAME) && (cf->get_can_port() == rxFrame.channel);
698 foundControlFunction = *inActiveResult;
702 if (
nullptr == foundControlFunction)
707 if ((partner->get_can_port() == rxFrame.
channel) &&
708 (partner->check_matches_name(
NAME(claimedNAME))) &&
709 (0 == partner->get_NAME().get_full_name()))
711 partner->controlFunctionNAME =
NAME(claimedNAME);
712 foundControlFunction = partner;
722 [&foundControlFunction, &claimedAddress](
const std::shared_ptr<ControlFunction> &cf) {
723 if ((nullptr != cf) && (foundControlFunction != cf) && (cf->address == claimedAddress))
724 cf->address = CANIdentifier::NULL_ADDRESS;
729 [&rxFrame, &foundControlFunction, &claimedAddress](
const std::shared_ptr<ControlFunction> &cf) {
730 if ((foundControlFunction != cf) && (cf->address == claimedAddress) && (cf->get_can_port() == rxFrame.channel))
731 cf->address = CANIdentifier::NULL_ADDRESS;
734 if (
nullptr == foundControlFunction)
739 LOG_DEBUG(
"[NM]: A control function claimed address %u on channel %u", foundControlFunction->get_address(), foundControlFunction->get_can_port());
741 else if (foundControlFunction->address != claimedAddress)
743 if (foundControlFunction->get_address_valid())
747 LOG_INFO(
"[NM]: The %s control function at address %d changed it's address to %d on channel %u.",
748 foundControlFunction->get_type_string().c_str(),
749 foundControlFunction->get_address(),
751 foundControlFunction->get_can_port());
755 LOG_INFO(
"[NM]: %s control function with name %016llx has claimed address %u on channel %u.",
756 foundControlFunction->get_type_string().c_str(),
757 foundControlFunction->get_NAME().get_full_name(),
759 foundControlFunction->get_can_port());
762 foundControlFunction->address = claimedAddress;
771 if (!partner->initialized)
776 if ((partner->check_matches_name((*currentInactiveControlFunction)->get_NAME())) &&
777 (partner->get_can_port() == (*currentInactiveControlFunction)->get_can_port()) &&
787 if ((
nullptr != currentActiveControlFunction) &&
788 (partner->check_matches_name(currentActiveControlFunction->get_NAME())) &&
793 partner->address = currentActiveControlFunction->get_address();
794 partner->controlFunctionNAME = currentActiveControlFunction->get_NAME();
795 partner->initialized =
true;
796 controlFunctionTable[partner->get_can_port()][partner->address] = std::shared_ptr<ControlFunction>(partner);
799 LOG_INFO(
"[NM]: A partner with name %016llx has claimed address %u on channel %u.",
800 partner->get_NAME().get_full_name(),
801 partner->get_address(),
802 partner->get_can_port());
806 partner->initialized =
true;
812 std::uint8_t sourceAddress,
813 std::uint8_t destAddress,
814 std::uint32_t parameterGroupNumber,
815 std::uint8_t priority,
817 std::uint32_t size)
const
824 std::uint32_t identifier = 0;
827 identifier |= ((priority & 0x07) << 26);
828 identifier |= (sourceAddress & 0xFF);
832 if ((parameterGroupNumber & 0xF000) >= 0xF000)
834 identifier |= ((parameterGroupNumber & 0x3FFFF) << 8);
838 identifier |= (destAddress << 8);
839 identifier |= ((parameterGroupNumber & 0x3FF00) << 8);
844 if ((parameterGroupNumber & 0xF000) < 0xF000)
846 identifier |= (destAddress << 8);
847 identifier |= ((parameterGroupNumber & 0x3FF00) << 8);
851 LOG_WARNING(
"[NM]: Cannot send a message with PGN " +
852 isobus::to_string(
static_cast<int>(parameterGroupNumber)) +
853 " as a destination specific message. " +
854 "Try resending it using nullptr as your destination control function.");
862 memcpy(
reinterpret_cast<void *
>(txFrame.
data), data, size);
873 std::shared_ptr<ControlFunction> retVal =
nullptr;
927 currentCallback.get_callback()(currentMessage, currentCallback.get_parent());
941 if ((
nullptr != internalCF) &&
942 (internalCF->get_address() == sourceAddress) &&
945 internalCF->on_address_violation({});
957 callback(controlFunction, state);
968 currentCallback.get_callback()(currentMessage, currentCallback.get_parent());
976 if ((
nullptr == messageDestination) &&
997 if ((
nullptr != partner) &&
1001 for (std::size_t k = 0; k < partner->get_number_parameter_group_number_callbacks(); k++)
1004 (
nullptr != partner->get_parameter_group_number_callback(k).get_callback()) &&
1005 ((
nullptr == partner->get_parameter_group_number_callback(k).get_internal_control_function()) ||
1009 partner->get_parameter_group_number_callback(k).get_callback()(message, partner->get_parameter_group_number_callback(k).get_parent());
1019 constexpr std::uint8_t COMMANDED_ADDRESS_LENGTH = 9;
1030 (currentICF->get_NAME().get_full_name() == targetNAME))
1032 currentICF->process_commanded_address(message.
get_uint8_at(8), {});
1075 for (std::uint_fast8_t channelIndex = 0; channelIndex <
CAN_PORT_MAXIMUM; channelIndex++)
1077 constexpr std::uint32_t MAX_ADDRESS_CLAIM_RESOLUTION_TIME = 755;
1084 if ((
nullptr != controlFunction) &&
1085 (!controlFunction->claimedAddressSinceLastAddressClaimRequest) &&
1089 LOG_INFO(
"[NM]: Control function with address %u and NAME %016llx is now offline on channel %u.", controlFunction->get_address(), controlFunction->get_NAME(), channelIndex);
1094 else if ((
nullptr != controlFunction) &&
1095 (!controlFunction->claimedAddressSinceLastAddressClaimRequest))
1105 bool CANNetworkManager::send_can_message_raw(std::uint32_t portIndex, std::uint8_t sourceAddress, std::uint8_t destAddress, std::uint32_t parameterGroupNumber, std::uint8_t priority,
const void *data, std::uint32_t size)
const
1108 bool retVal =
false;
General constants used throughout this library.
Defines some PGNs that are used in the library or are very common.
An abstraction between this CAN stack and any hardware layer.
An abstraction of a CAN message, could be > 8 data bytes.
The main class that manages the ISOBUS stack including: callbacks, Name to Address management,...
A class that describes a control function on the bus that the stack should communicate with....
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
This is a way to protect functions on public interfaces from being accessed by objects that shouldn't...
A utility class that allows easy interpretation of a 32 bit CAN identifier.
CANPriority
Defines all the CAN frame priorities that can be encoded in a frame ID.
@ PriorityLowest7
The lowest priority.
static constexpr std::uint8_t NULL_ADDRESS
The NULL CAN address as defined by ISO11783.
std::uint8_t get_source_address() const
Returns the source address of the frame encoded in the identifier.
std::uint32_t get_parameter_group_number() const
Returns the PGN encoded in the identifier.
std::uint8_t get_destination_address() const
Returns the destination address of the frame encoded in the identifier.
A class that represents data of a CAN message by using a callback function.
A class that represents data of a CAN message by holding a view of an array of bytes....
A CAN frame for interfacing with a hardware layer, like socket CAN or other interface.
std::uint8_t dataLength
The length of the data used in the frame.
std::uint32_t identifier
The 32 bit identifier of the frame.
bool isExtendedFrame
Denotes if the frame is extended format.
std::uint32_t get_number_bits_in_message() const
std::uint8_t data[8]
The data payload of the frame.
std::uint8_t channel
The CAN channel index associated with the frame.
A class that represents a generic CAN message of arbitrary length.
static const std::uint32_t ABSOLUTE_MAX_MESSAGE_LENGTH
ISO11783-3 defines this: The maximum number of packets that can be sent in a single connection with e...
@ Receive
Message is being received.
@ Transmit
Message is to be transmitted from the stack.
static CANMessage create_invalid_message()
Factory method to construct an intentionally invalid CANMessage.
std::uint8_t get_can_port_index() const
Returns the CAN channel index associated with the message.
std::uint32_t get_data_length() const
Returns the length of the data in the CAN message.
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::shared_ptr< ControlFunction > get_destination_control_function() const
Gets the destination control function that the message is to.
std::uint64_t get_uint64_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 64-bit unsigned integer from the buffer at a specific index. A 64-bit unsigned integer can hold...
A class that defines stack-wide configuration data. You can set the values in there to suit your spec...
std::unique_ptr< FastPacketProtocol > & get_fast_packet_protocol(std::uint8_t canPortIndex)
Returns the class instance of the NMEA2k fast packet protocol. Use this to register for FP multipacke...
friend class TransportProtocolManager
Allows the network manager to work closely with the transport protocol manager object.
std::list< std::shared_ptr< ControlFunction > > inactiveControlFunctions
A list of the control function that currently don't have a valid address.
std::queue< CANMessage > transmittedMessageQueue
A queue of transmitted messages to process (already sent, so changes to the message won't affect the ...
EventDispatcher< std::shared_ptr< InternalControlFunction > > & get_address_violation_event_dispatcher()
Returns the network manager's event dispatcher for notifying consumers whenever an address violation ...
void update_address_table(const CANMessage &message)
Updates the internal address table based on a received CAN message.
static constexpr std::uint32_t BUSLOAD_SAMPLE_WINDOW_MS
Using a 1s window to average the bus load, otherwise it's very erratic.
void on_control_function_destroyed(std::shared_ptr< ControlFunction > controlFunction, CANLibBadge< ControlFunction >)
Informs the network manager that a control function object has been destroyed, so that it can be purg...
Mutex anyControlFunctionCallbacksMutex
Mutex to protect the "any CF" callbacks.
void add_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
This is how you register a callback for any PGN destined for the global address (0xFF)
EventDispatcher< CANMessage > messageTransmittedEventDispatcher
An event dispatcher for notifying consumers about transmitted messages by our application.
void remove_control_function_status_change_callback(ControlFunctionStateCallback callback)
Used to remove callbacks added with add_control_function_status_change_callback.
void update_new_partners()
Checks if new partners have been created and matches them to existing control functions.
bool send_can_message_raw(std::uint32_t portIndex, std::uint8_t sourceAddress, std::uint8_t destAddress, std::uint32_t parameterGroupNumber, std::uint8_t priority, const void *data, std::uint32_t size, CANLibBadge< AddressClaimStateMachine >) const
Sends a CAN message using raw addresses. Used only by the stack.
std::array< std::deque< std::uint32_t >, CAN_PORT_MAXIMUM > busloadMessageBitsHistory
Stores the approximate number of bits processed on each channel over multiple previous time windows.
std::shared_ptr< ControlFunction > get_control_function(std::uint8_t channelIndex, std::uint8_t address, CANLibBadge< AddressClaimStateMachine >) const
Called only by the stack, returns a control function based on certain port and address.
CANNetworkConfiguration & get_configuration()
Returns the configuration of this network manager.
void process_tx_messages()
Processes the internal transmitted message queue.
std::array< std::uint32_t, CAN_PORT_MAXIMUM > lastAddressClaimRequestTimestamp_ms
Stores timestamps for when the last request for the address claim PGN was received....
void process_receive_can_message_frame(const CANMessageFrame &rxFrame)
Used to tell the network manager when frames are received on the bus.
void process_protocol_pgn_callbacks(const CANMessage ¤tMessage)
Processes a can message for callbacks added with add_protocol_parameter_group_number_callback.
void process_can_message_for_address_violations(const CANMessage ¤tMessage)
Validates that a CAN message has not caused an address violation. If a violation is found,...
std::vector< ParameterGroupNumberCallbackData > anyControlFunctionParameterGroupNumberCallbacks
A list of all global PGN callbacks.
std::array< std::array< std::shared_ptr< ControlFunction >, NULL_CAN_ADDRESS >, CAN_PORT_MAXIMUM > controlFunctionTable
Table to maintain address to NAME mappings.
static CANNetworkManager CANNetwork
Static singleton of the one network manager. Use this to access stack functionality.
void on_control_function_created(std::shared_ptr< ControlFunction > controlFunction, CANLibBadge< ControlFunction >)
Informs the network manager that a control function object has been created, so that it can be added ...
EventDispatcher< CANMessage > & get_transmitted_message_event_dispatcher()
Returns the network manager's event dispatcher for notifying consumers whenever a message is transmit...
std::vector< ParameterGroupNumberCallbackData > globalParameterGroupNumberCallbacks
A list of all global PGN callbacks.
bool remove_protocol_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parentPointer)
Removes a PGN callback for a protocol class.
EventDispatcher< std::shared_ptr< InternalControlFunction > > addressViolationEventDispatcher
An event dispatcher for notifying consumers about address violations.
CANNetworkManager()
Constructor for the network manager. Sets default values for members.
std::list< std::shared_ptr< InternalControlFunction > > internalControlFunctions
A list of the internal control functions.
void process_can_message_for_commanded_address(const CANMessage &message)
Processes a CAN message to see if it's a commanded address message, and if it is, it attempts to set ...
bool add_protocol_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parentPointer)
Adds a PGN callback for a protocol class.
std::list< std::shared_ptr< PartneredControlFunction > > partneredControlFunctions
A list of the partnered control functions.
std::list< ControlFunctionStateCallback > controlFunctionStateCallbacks
List of all control function state callbacks.
void update_internal_cfs()
Updates the internal address table based on updates to internal cfs addresses.
std::shared_ptr< InternalControlFunction > get_internal_control_function(std::shared_ptr< ControlFunction > controlFunction)
Returns an internal control function if the passed-in control function is an internal type.
std::array< std::unique_ptr< ExtendedTransportProtocolManager >, CAN_PORT_MAXIMUM > extendedTransportProtocols
One instance of the extended transport protocol manager for each channel.
void add_any_control_function_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
Registers a callback for ANY control function sending the associated PGN.
std::list< ParameterGroupNumberCallbackData > protocolPGNCallbacks
A list of PGN callback registered by CAN protocols.
void add_control_function_status_change_callback(ControlFunctionStateCallback callback)
Use this to get a callback when a control function goes online or offline. This could be useful if yo...
void initialize()
Initializer function for the network manager.
const std::list< std::shared_ptr< PartneredControlFunction > > & get_partnered_control_functions() const
Gets all the partnered control functions that are currently registered in the network manager.
void process_can_message_for_global_and_partner_callbacks(const CANMessage &message)
Matches a CAN message to any matching PGN callback, and calls that callback.
void remove_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
This is how you remove a callback for any PGN destined for the global address (0xFF)
static constexpr std::uint32_t BUSLOAD_UPDATE_FREQUENCY_MS
Bus load bit accumulation happens over a 100ms window.
CANMessage get_next_can_message_from_rx_queue()
Get the next CAN message from the received message queue, and remove it from the queue.
CANNetworkConfiguration configuration
The configuration for this network manager.
void process_any_control_function_pgn_callbacks(const CANMessage ¤tMessage)
Processes a can message for callbacks added with add_any_control_function_parameter_group_number_call...
const std::list< std::shared_ptr< InternalControlFunction > > & get_internal_control_functions() const
Gets all the internal control functions that are currently registered in the network manager.
bool initialized
True if the network manager has been initialized by the update function.
void update_busload(std::uint8_t channelIndex, std::uint32_t numberOfBitsProcessed)
Processes a CAN message's contribution to the current busload.
std::list< std::shared_ptr< ControlFunction > > get_control_functions(bool includingOffline) const
Gets all the control functions that are known to the network manager.
std::list< std::shared_ptr< TransportProtocolSessionBase > > get_active_transport_protocol_sessions(std::uint8_t canPortIndex) const
Gets all the active transport protocol sessions that are currently active.
void process_rx_messages()
Processes the internal received message queue.
void prune_inactive_control_functions()
Checks to see if any control function didn't claim during a round of address claiming and removes it ...
void process_transmitted_can_message_frame(const CANMessageFrame &txFrame)
Used to tell the network manager when frames are emitted on the bus.
bool send_can_message(std::uint32_t parameterGroupNumber, const std::uint8_t *dataBuffer, std::uint32_t dataLength, std::shared_ptr< InternalControlFunction > sourceControlFunction, std::shared_ptr< ControlFunction > destinationControlFunction=nullptr, CANIdentifier::CANPriority priority=CANIdentifier::CANPriority::PriorityDefault6, TransmitCompleteCallback txCompleteCallback=nullptr, void *parentPointer=nullptr, DataChunkCallback frameChunkCallback=nullptr)
This is the main way to send a CAN message of any length.
void process_control_function_state_change_callback(std::shared_ptr< ControlFunction > controlFunction, ControlFunctionState state)
Checks the control function state callback list to see if we need to call a control function state ca...
std::array< std::unique_ptr< TransportProtocolManager >, CAN_PORT_MAXIMUM > transportProtocols
One instance of the transport protocol manager for each channel.
std::queue< CANMessage > receivedMessageQueue
A queue of received messages to process.
void protocol_message_callback(const CANMessage &message)
Processes completed protocol messages. Causes PGN callbacks to trigger.
CANMessageFrame construct_frame(std::uint32_t portIndex, std::uint8_t sourceAddress, std::uint8_t destAddress, std::uint32_t parameterGroupNumber, std::uint8_t priority, const void *data, std::uint32_t size) const
Builds a CAN frame from a frame's discrete components.
HeartbeatInterface & get_heartbeat_interface(std::uint8_t canPortIndex)
Returns an interface which can be used to manage ISO11783-7 heartbeat messages.
friend class ExtendedTransportProtocolManager
Allows the network manager to access the ETP manager.
void update()
The main update function for the network manager. Updates all protocols.
Mutex controlFunctionStatusCallbacksMutex
A Mutex that protects access to the control function status callback list.
ParameterGroupNumberCallbackData get_global_parameter_group_number_callback(std::uint32_t index) const
Gets a PGN callback for the global address by index.
void update_busload_history()
Updates the stored bit accumulators for calculating the bus load over a multiple sample windows.
friend class FastPacketProtocol
Allows the FP protocol to access the network manager protected functions.
std::uint32_t busloadUpdateTimestamp_ms
Tracks a time window for determining approximate busload.
CANMessage get_next_can_message_from_tx_queue()
Get the next CAN message from the received message queue, and remove it from the queue.
std::array< std::uint32_t, CAN_PORT_MAXIMUM > currentBusloadBitAccumulator
Accumulates the approximate number of bits processed on each channel during the current time window.
std::array< std::unique_ptr< HeartbeatInterface >, CAN_PORT_MAXIMUM > heartBeatInterfaces
Manages ISOBUS heartbeat requests, one per channel.
std::uint32_t updateTimestamp_ms
Keeps track of the last time the CAN stack was update in milliseconds.
void remove_any_control_function_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
This is how you remove a callback added with add_any_control_function_parameter_group_number_callback...
std::size_t get_number_global_parameter_group_number_callbacks() const
Returns the number of global PGN callbacks that have been registered with the network manager.
Mutex protocolPGNCallbacksMutex
A mutex for PGN callback thread safety.
Mutex busloadUpdateMutex
A mutex that protects the busload metrics since we calculate it on our own thread.
Mutex transmittedMessageQueueMutex
A mutex for protecting the transmitted message queue.
void update_control_functions(const CANMessageFrame &rxFrame)
Creates new control function classes based on the frames coming in from the bus.
Mutex receivedMessageQueueMutex
A mutex for receive messages thread safety.
float get_estimated_busload(std::uint8_t canChannel)
Returns an estimated busload between 0.0f and 100.0f.
std::array< std::unique_ptr< FastPacketProtocol >, CAN_PORT_MAXIMUM > fastPacketProtocol
One instance of the fast packet protocol for each channel.
static Mutex controlFunctionProcessingMutex
Protects the control function tables.
static std::shared_ptr< ControlFunction > create(NAME NAMEValue, std::uint8_t addressValue, std::uint8_t CANPort)
The factory function to construct a control function.
@ Internal
The control function is part of our stack and can address claim.
@ External
The control function is some other device on the bus.
@ Partnered
An external control function that you explicitly want to talk to.
This class is used to send and receive ISOBUS heartbeats.
A class that represents an ISO11783 control function NAME from an address claim.
A storage class to hold data about callbacks for a specific PGN.
void * get_parent() const
Returns the parent pointer for this data object.
CANLibCallback get_callback() const
Returns the callback pointer for this data object.
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.
constexpr std::uint8_t NULL_CAN_ADDRESS
The NULL CAN address defined by J1939 and ISO11783.
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.
void(*)(const CANMessage &message, void *parentPointer) CANLibCallback
A callback for control functions to get CAN messages.
bool send_can_message_frame_to_hardware(const CANMessageFrame &frame)
The sending abstraction layer between the hardware and the stack.
constexpr std::uint8_t BROADCAST_CAN_ADDRESS
The global/broadcast CAN address.
void on_transmit_can_message_frame_from_hardware(const CANMessageFrame &txFrame)
Informs the network manager whenever messages are emitted on the bus.
void periodic_update_from_hardware()
The periodic update abstraction layer between the hardware and the stack.
bool(*)(std::uint32_t callbackIndex, std::uint32_t bytesOffset, std::uint32_t numberOfBytesNeeded, std::uint8_t *chunkBuffer, void *parentPointer) DataChunkCallback
A callback to get chunks of data for transfer by a protocol.
constexpr std::uint32_t DEFAULT_IDENTIFIER
An invalid identifier used as a default.
void(*)(std::shared_ptr< ControlFunction > controlFunction, ControlFunctionState state) ControlFunctionStateCallback
A callback that can inform you when a control function changes state between online and offline.
constexpr std::uint32_t CAN_PORT_MAXIMUM
An arbitrary limit for memory consumption.
void receive_can_message_frame_from_hardware(const CANMessageFrame &frame)
The receiving abstraction layer between the hardware and the stack.
ControlFunctionState
Enumerates the "online" states of a control function.
@ Online
The CF's address claim state is valid.
@ Offline
The CF's address claim state is not valid.