Skip to content

Commit e55177e

Browse files
committed
feat(core): Make heartbeat interface use the new messaging handler
1 parent ce31ac5 commit e55177e

File tree

6 files changed

+38
-37
lines changed

6 files changed

+38
-37
lines changed

isobus/include/isobus/isobus/can_message_handling.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ namespace isobus
108108
DataChunkCallback frameChunkCallback = nullptr) const;
109109

110110
friend class CANMessageHandler; ///< Allow the CANMessageHandler to modify the messaging provider
111-
std::shared_ptr<CANMessagingProvider> messagingProvider; ///< The messaging provider to use for sending messages
111+
std::weak_ptr<CANMessagingProvider> messagingProvider; ///< The messaging provider to use for sending messages
112112
};
113113

114114
/// @brief A class for managing the routing of incoming and outgoing CAN messages

isobus/include/isobus/isobus/can_network_manager.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ namespace isobus
395395
std::array<std::unique_ptr<TransportProtocolManager>, CAN_PORT_MAXIMUM> transportProtocols; ///< One instance of the transport protocol manager for each channel
396396
std::array<std::unique_ptr<ExtendedTransportProtocolManager>, CAN_PORT_MAXIMUM> extendedTransportProtocols; ///< One instance of the extended transport protocol manager for each channel
397397
std::array<std::unique_ptr<FastPacketProtocol>, CAN_PORT_MAXIMUM> fastPacketProtocol; ///< One instance of the fast packet protocol for each channel
398-
std::array<std::unique_ptr<HeartbeatInterface>, CAN_PORT_MAXIMUM> heartBeatInterfaces; ///< Manages ISOBUS heartbeat requests, one per channel
398+
std::array<std::shared_ptr<HeartbeatInterface>, CAN_PORT_MAXIMUM> heartBeatInterfaces; ///< Manages ISOBUS heartbeat requests, one per channel
399399

400400
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
401401
std::array<std::uint32_t, CAN_PORT_MAXIMUM> currentBusloadBitAccumulator; ///< Accumulates the approximate number of bits processed on each channel during the current time window
@@ -413,6 +413,7 @@ namespace isobus
413413
std::vector<ParameterGroupNumberCallbackData> globalParameterGroupNumberCallbacks; ///< A list of all global PGN callbacks
414414
std::vector<ParameterGroupNumberCallbackData> anyControlFunctionParameterGroupNumberCallbacks; ///< A list of all global PGN callbacks
415415
CANMessageHandler messageHandler; ///< The message handler driven by the network manager
416+
std::shared_ptr<CANMessagingProvider> messagingProvider; ///< The messaging provider for the network manager, currently set to itself
416417
EventDispatcher<CANMessage> messageTransmittedEventDispatcher; ///< An event dispatcher for notifying consumers about transmitted messages by our application
417418
EventDispatcher<std::shared_ptr<InternalControlFunction>> addressViolationEventDispatcher; ///< An event dispatcher for notifying consumers about address violations
418419
Mutex receivedMessageQueueMutex; ///< A mutex for receive messages thread safety

isobus/include/isobus/isobus/isobus_heartbeat.hpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
#include "isobus/isobus/can_callbacks.hpp"
2121
#include "isobus/isobus/can_internal_control_function.hpp"
2222
#include "isobus/isobus/can_message.hpp"
23+
#include "isobus/isobus/can_message_handling.hpp"
2324
#include "isobus/utility/event_dispatcher.hpp"
2425

2526
#include <list>
2627

2728
namespace isobus
2829
{
2930
/// @brief This class is used to send and receive ISOBUS heartbeats.
30-
class HeartbeatInterface
31+
class HeartbeatInterface : public CANMessagingConsumer
3132
{
3233
public:
3334
/// @brief This enum is used to define the possible errors that can occur when receiving a heartbeat.
@@ -37,10 +38,6 @@ namespace isobus
3738
TimedOut ///< The heartbeat message has not been received within the repetition rate
3839
};
3940

40-
/// @brief Constructor for a HeartbeatInterface
41-
/// @param[in] sendCANFrameCallback A callback used to send CAN frames
42-
HeartbeatInterface(const CANMessageFrameCallback &sendCANFrameCallback);
43-
4441
/// @brief This can be used to disable or enable this heartbeat functionality.
4542
/// It's probably best to leave it enabled for most applications, but it's not
4643
/// strictly needed.
@@ -91,7 +88,7 @@ namespace isobus
9188

9289
/// @brief Processes a CAN message, called by the network manager.
9390
/// @param[in] message The CAN message being received
94-
void process_rx_message(const CANMessage &message);
91+
void process_rx_message(const CANMessage &message) override;
9592

9693
/// @brief Updates the interface. Called by the network manager,
9794
/// so there is no need for you to call it in your application.
@@ -143,7 +140,6 @@ namespace isobus
143140
std::uint32_t repetitionRate,
144141
void *parentPointer);
145142

146-
const CANMessageFrameCallback sendCANFrameCallback; ///< A callback for sending a CAN frame
147143
EventDispatcher<HeartBeatError, std::shared_ptr<ControlFunction>> heartbeatErrorEventDispatcher; ///< Event dispatcher for heartbeat errors
148144
EventDispatcher<std::shared_ptr<ControlFunction>> newTrackedHeartbeatEventDispatcher; ///< Event dispatcher for when a heartbeat message from another control function becomes tracked by this interface
149145
std::list<Heartbeat> trackedHeartbeats; ///< Store tracked heartbeat data, per CF

isobus/src/can_message_handling.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ namespace isobus
2222
void *parentPointer,
2323
DataChunkCallback frameChunkCallback) const
2424
{
25-
if (nullptr != messagingProvider)
25+
if (!messagingProvider.expired())
2626
{
27-
return messagingProvider->send_can_message(parameterGroupNumber,
28-
dataBuffer,
29-
dataLength,
30-
sourceControlFunction,
31-
destinationControlFunction,
32-
priority,
33-
txCompleteCallback,
34-
parentPointer,
35-
frameChunkCallback);
27+
return messagingProvider.lock()->send_can_message(parameterGroupNumber,
28+
dataBuffer,
29+
dataLength,
30+
sourceControlFunction,
31+
destinationControlFunction,
32+
priority,
33+
txCompleteCallback,
34+
parentPointer,
35+
frameChunkCallback);
3636
}
3737
return false;
3838
}
@@ -73,10 +73,13 @@ namespace isobus
7373

7474
void CANMessageHandler::add_consumer(std::shared_ptr<CANMessagingConsumer> consumer)
7575
{
76-
// Ensure the consumer is not already in the list
77-
remove_consumer(consumer);
78-
consumer->messagingProvider = messagingProvider;
79-
consumers.push_back(consumer);
76+
if (nullptr != consumer)
77+
{
78+
// Ensure the consumer is not already in the list
79+
remove_consumer(consumer);
80+
consumer->messagingProvider = messagingProvider;
81+
consumers.push_back(consumer);
82+
}
8083
}
8184

8285
void CANMessageHandler::remove_consumer(std::shared_ptr<CANMessagingConsumer> consumer)

isobus/src/can_network_manager.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,14 @@ namespace isobus
4141
get_next_can_message_from_tx_queue();
4242
}
4343

44-
//! @todo: Remove this unsafe way of making a shared pointer to the network manager once the network manager is no longer a singleton
45-
messageHandler.set_messaging_provider(std::shared_ptr<CANNetworkManager>(this));
44+
//! @todo: Remove this unsafe way of making a shared pointer to the network manager once the network manager is no longer a singleton,
45+
//! it's the cause of a double-free right now, but since it must be at the end of an application since the CANNetwork is a sngleton, it shouldn't harm too much for now
46+
messagingProvider = std::shared_ptr<CANNetworkManager>(this);
47+
messageHandler.set_messaging_provider(messagingProvider);
48+
for (std::uint8_t i = 0; i < CAN_PORT_MAXIMUM; i++)
49+
{
50+
messageHandler.add_consumer(heartBeatInterfaces.at(i));
51+
}
4652
initialized = true;
4753
}
4854

@@ -501,6 +507,7 @@ namespace isobus
501507
currentBusloadBitAccumulator.fill(0);
502508
lastAddressClaimRequestTimestamp_ms.fill(0);
503509
controlFunctionTable.fill({ nullptr });
510+
heartBeatInterfaces.fill({ std::make_shared<HeartbeatInterface>() });
504511

505512
auto send_frame_callback = [this](std::uint32_t parameterGroupNumber,
506513
CANDataSpan data,
@@ -523,7 +530,6 @@ namespace isobus
523530
transportProtocols.at(i).reset(new TransportProtocolManager(send_frame_callback, receive_message_callback, &configuration));
524531
extendedTransportProtocols.at(i).reset(new ExtendedTransportProtocolManager(send_frame_callback, receive_message_callback, &configuration));
525532
fastPacketProtocol.at(i).reset(new FastPacketProtocol(send_frame_callback));
526-
heartBeatInterfaces.at(i).reset(new HeartbeatInterface(send_frame_callback));
527533
}
528534
}
529535

@@ -1029,7 +1035,6 @@ namespace isobus
10291035
transportProtocols.at(currentMessage.get_can_port_index())->process_message(currentMessage);
10301036
extendedTransportProtocols.at(currentMessage.get_can_port_index())->process_message(currentMessage);
10311037
fastPacketProtocol.at(currentMessage.get_can_port_index())->process_message(currentMessage);
1032-
heartBeatInterfaces.at(currentMessage.get_can_port_index())->process_rx_message(currentMessage);
10331038
process_protocol_pgn_callbacks(currentMessage);
10341039
process_any_control_function_pgn_callbacks(currentMessage);
10351040
messageHandler.process_rx_message(currentMessage);

isobus/src/isobus_heartbeat.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@
2323

2424
namespace isobus
2525
{
26-
HeartbeatInterface::HeartbeatInterface(const CANMessageFrameCallback &sendCANFrameCallback) :
27-
sendCANFrameCallback(sendCANFrameCallback)
28-
{
29-
}
30-
3126
void HeartbeatInterface::set_enabled(bool enable)
3227
{
3328
if ((!enable) && (enable != enabled))
@@ -139,11 +134,12 @@ namespace isobus
139134
bool retVal = false;
140135
const std::array<std::uint8_t, 1> buffer = { sequenceCounter };
141136

142-
retVal = parent.sendCANFrameCallback(static_cast<std::uint32_t>(CANLibParameterGroupNumber::HeartbeatMessage),
143-
CANDataSpan(buffer.data(), buffer.size()),
144-
CANNetworkManager::CANNetwork.get_internal_control_function(controlFunction),
145-
nullptr,
146-
CANIdentifier::CANPriority::Priority3);
137+
retVal = parent.send_can_message(static_cast<std::uint32_t>(CANLibParameterGroupNumber::HeartbeatMessage),
138+
buffer.data(),
139+
buffer.size(),
140+
std::static_pointer_cast<InternalControlFunction>(controlFunction),
141+
nullptr,
142+
CANIdentifier::CANPriority::Priority3);
147143
if (retVal)
148144
{
149145
timestamp_ms = SystemTiming::get_timestamp_ms(); // Sent OK

0 commit comments

Comments
 (0)