AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
can_network_manager.hpp
Go to the documentation of this file.
1//================================================================================================
10//================================================================================================
11
12#ifndef CAN_NETWORK_MANAGER_HPP
13#define CAN_NETWORK_MANAGER_HPP
14
28#include "isobus/utility/event_dispatcher.hpp"
29#include "isobus/utility/thread_synchronization.hpp"
30
31#include <array>
32#include <deque>
33#include <list>
34#include <memory>
35#include <queue>
36
38namespace isobus
39{
40 class PartneredControlFunction;
41
42 //================================================================================================
47 //================================================================================================
49 {
50 public:
52
54 void initialize();
55
60 std::shared_ptr<ControlFunction> get_control_function(std::uint8_t channelIndex, std::uint8_t address, CANLibBadge<AddressClaimStateMachine>) const;
61
66 void add_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent);
67
72 void remove_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent);
73
77
82 void add_any_control_function_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent);
83
88 void remove_any_control_function_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent);
89
93 EventDispatcher<CANMessage> &get_transmitted_message_event_dispatcher();
94
98 std::shared_ptr<InternalControlFunction> get_internal_control_function(std::shared_ptr<ControlFunction> controlFunction);
99
107 float get_estimated_busload(std::uint8_t canChannel);
108
124 bool send_can_message(std::uint32_t parameterGroupNumber,
125 const std::uint8_t *dataBuffer,
126 std::uint32_t dataLength,
127 std::shared_ptr<InternalControlFunction> sourceControlFunction,
128 std::shared_ptr<ControlFunction> destinationControlFunction = nullptr,
130 TransmitCompleteCallback txCompleteCallback = nullptr,
131 void *parentPointer = nullptr,
132 DataChunkCallback frameChunkCallback = nullptr);
133
135 void update();
136
140
144
147 void on_control_function_destroyed(std::shared_ptr<ControlFunction> controlFunction, CANLibBadge<ControlFunction>);
148
151 void on_control_function_created(std::shared_ptr<ControlFunction> controlFunction, CANLibBadge<ControlFunction>);
152
155 void on_control_function_created(std::shared_ptr<ControlFunction> controlFunction, CANLibBadge<InternalControlFunction>);
156
159 void on_control_function_created(std::shared_ptr<ControlFunction> controlFunction, CANLibBadge<PartneredControlFunction>);
160
165
169
172 const std::list<std::shared_ptr<InternalControlFunction>> &get_internal_control_functions() const;
173
176 const std::list<std::shared_ptr<PartneredControlFunction>> &get_partnered_control_functions() const;
177
181 std::list<std::shared_ptr<ControlFunction>> get_control_functions(bool includingOffline) const;
182
187 std::list<std::shared_ptr<TransportProtocolSessionBase>> get_active_transport_protocol_sessions(std::uint8_t canPortIndex) const;
188
193 std::unique_ptr<FastPacketProtocol> &get_fast_packet_protocol(std::uint8_t canPortIndex);
194
198 HeartbeatInterface &get_heartbeat_interface(std::uint8_t canPortIndex);
199
203
207 EventDispatcher<std::shared_ptr<InternalControlFunction>> &get_address_violation_event_dispatcher();
208
209 protected:
210 // Using protected region to allow protocols use of special functions from the network manager
214 friend class DiagnosticProtocol;
216 friend class FastPacketProtocol;
217
223 bool add_protocol_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parentPointer);
224
230 bool remove_protocol_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parentPointer);
231
241 bool send_can_message_raw(std::uint32_t portIndex,
242 std::uint8_t sourceAddress,
243 std::uint8_t destAddress,
244 std::uint32_t parameterGroupNumber,
245 std::uint8_t priority,
246 const void *data,
247 std::uint32_t size,
249
252 void protocol_message_callback(const CANMessage &message);
253
254 private:
257
260 void update_address_table(const CANMessage &message);
261
263 void update_internal_cfs();
264
268 void update_busload(std::uint8_t channelIndex, std::uint32_t numberOfBitsProcessed);
269
272
275 void update_control_functions(const CANMessageFrame &rxFrame);
276
278 void update_new_partners();
279
289 CANMessageFrame construct_frame(std::uint32_t portIndex,
290 std::uint8_t sourceAddress,
291 std::uint8_t destAddress,
292 std::uint32_t parameterGroupNumber,
293 std::uint8_t priority,
294 const void *data,
295 std::uint32_t size) const;
296
301 std::shared_ptr<ControlFunction> get_control_function(std::uint8_t channelIndex, std::uint8_t address) const;
302
307
312
315 void on_control_function_created(std::shared_ptr<ControlFunction> controlFunction);
316
319 void process_any_control_function_pgn_callbacks(const CANMessage &currentMessage);
320
326 void process_can_message_for_address_violations(const CANMessage &currentMessage);
327
332 void process_control_function_state_change_callback(std::shared_ptr<ControlFunction> controlFunction, ControlFunctionState state);
333
336 void process_protocol_pgn_callbacks(const CANMessage &currentMessage);
337
341
348
350 void process_rx_messages();
351
353 void process_tx_messages();
354
358
368 bool send_can_message_raw(std::uint32_t portIndex,
369 std::uint8_t sourceAddress,
370 std::uint8_t destAddress,
371 std::uint32_t parameterGroupNumber,
372 std::uint8_t priority,
373 const void *data,
374 std::uint32_t size) const;
375
380
381 static constexpr std::uint32_t BUSLOAD_SAMPLE_WINDOW_MS = 1000;
382 static constexpr std::uint32_t BUSLOAD_UPDATE_FREQUENCY_MS = 100;
383
385 std::array<std::unique_ptr<TransportProtocolManager>, CAN_PORT_MAXIMUM> transportProtocols;
386 std::array<std::unique_ptr<ExtendedTransportProtocolManager>, CAN_PORT_MAXIMUM> extendedTransportProtocols;
387 std::array<std::unique_ptr<FastPacketProtocol>, CAN_PORT_MAXIMUM> fastPacketProtocol;
388 std::array<std::unique_ptr<HeartbeatInterface>, CAN_PORT_MAXIMUM> heartBeatInterfaces;
389
390 std::array<std::deque<std::uint32_t>, CAN_PORT_MAXIMUM> busloadMessageBitsHistory;
391 std::array<std::uint32_t, CAN_PORT_MAXIMUM> currentBusloadBitAccumulator;
392 std::array<std::uint32_t, CAN_PORT_MAXIMUM> lastAddressClaimRequestTimestamp_ms;
393
394 std::array<std::array<std::shared_ptr<ControlFunction>, NULL_CAN_ADDRESS>, CAN_PORT_MAXIMUM> controlFunctionTable;
395 std::list<std::shared_ptr<ControlFunction>> inactiveControlFunctions;
396 std::list<std::shared_ptr<InternalControlFunction>> internalControlFunctions;
397 std::list<std::shared_ptr<PartneredControlFunction>> partneredControlFunctions;
398
399 std::list<ParameterGroupNumberCallbackData> protocolPGNCallbacks;
400 std::queue<CANMessage> receivedMessageQueue;
401 std::queue<CANMessage> transmittedMessageQueue;
402 std::list<ControlFunctionStateCallback> controlFunctionStateCallbacks;
403 std::vector<ParameterGroupNumberCallbackData> globalParameterGroupNumberCallbacks;
404 std::vector<ParameterGroupNumberCallbackData> anyControlFunctionParameterGroupNumberCallbacks;
405 EventDispatcher<CANMessage> messageTransmittedEventDispatcher;
406 EventDispatcher<std::shared_ptr<InternalControlFunction>> addressViolationEventDispatcher;
413 std::uint32_t busloadUpdateTimestamp_ms = 0;
414 std::uint32_t updateTimestamp_ms = 0;
415 bool initialized = false;
416 };
417
418} // namespace isobus
419
420#endif // CAN_NETWORK_MANAGER_HPP
Defines a class for managing the address claiming process.
A way to only allow certain object types to access certain functions that is enforced at compile time...
An object to represent common callbacks used within this CAN stack.
General constants used throughout this library.
A protocol class that handles the ISO11783 extended transport protocol. Designed for destination spec...
A representation of a classical CAN identifier with utility functions for ectracting values that are ...
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 classical CAN frame, with 8 data bytes.
This is a class for changing stack settings.
A protocol that handles the ISO11783/J1939 transport protocol. It handles both the broadcast version ...
This is a way to protect functions on public interfaces from being accessed by objects that shouldn't...
CANPriority
Defines all the CAN frame priorities that can be encoded in a frame ID.
@ PriorityDefault6
The default priority.
A CAN frame for interfacing with a hardware layer, like socket CAN or other interface.
A class that represents a generic CAN message of arbitrary length.
A class that defines stack-wide configuration data. You can set the values in there to suit your spec...
The main CAN network manager object, handles protocol management and updating other stack components....
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...
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 &currentMessage)
Processes a can message for callbacks added with add_protocol_parameter_group_number_callback.
void process_can_message_for_address_violations(const CANMessage &currentMessage)
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 &currentMessage)
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.
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.
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.
Manages the DM1, DM2, and DM3 messages for ISO11783 or J1939.
A class that handles the ISO11783 extended transport protocol.
A protocol that handles the NMEA 2000 fast packet protocol.
This class is used to send and receive ISOBUS heartbeats.
A storage class to hold data about callbacks for a specific PGN.
A class that handles the ISO11783/J1939 transport protocol.
Defines an interface for sending and receiving ISOBUS heartbeats. The heartbeat message is used to de...
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
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.
void(*)(const CANMessage &message, void *parentPointer) CANLibCallback
A callback for control functions to get CAN messages.
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.
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.
ControlFunctionState
Enumerates the "online" states of a control function.
A protocol that handles the NMEA 2000 (IEC 61162-3) fast packet protocol.