Skip to content

Commit

Permalink
[Core]: Switch to smart pointers for CFs
Browse files Browse the repository at this point in the history
With this change all the current raw pointers are converted to smart pointers, e.g. `shared_ptr`
  • Loading branch information
GwnDaan committed Jun 19, 2023
1 parent fd61d5a commit 41c51d9
Show file tree
Hide file tree
Showing 62 changed files with 938 additions and 842 deletions.
2 changes: 1 addition & 1 deletion examples/diagnostic_protocol/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ int main()
TestDeviceNAME.set_device_class_instance(0);
TestDeviceNAME.set_manufacturer_code(64);

auto TestInternalECU = std::make_shared<isobus::InternalControlFunction>(TestDeviceNAME, 0x1C, 0);
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1C, 0);

// Wait to make sure address claiming is done. The time is arbitrary.
//! @todo Check this instead of asuming it is done
Expand Down
8 changes: 4 additions & 4 deletions examples/nmea2000/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ void nmea2k_callback(const isobus::CANMessage &message, void *)

void nmea2k_transmit_complete_callback(std::uint32_t parameterGroupNumber,
std::uint32_t dataLength,
isobus::InternalControlFunction *,
isobus::ControlFunction *,
std::shared_ptr<isobus::InternalControlFunction>,
std::shared_ptr<isobus::ControlFunction>,
bool successful,
void *)
{
Expand Down Expand Up @@ -85,7 +85,7 @@ int main()
TestDeviceNAME.set_device_class_instance(0);
TestDeviceNAME.set_manufacturer_code(64);

isobus::InternalControlFunction TestInternalECU(TestDeviceNAME, 0x1C, 0);
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1C, 0);

isobus::CANNetworkManager::CANNetwork.get_fast_packet_protocol().register_multipacket_message_callback(0x1F001, nmea2k_callback, nullptr);

Expand All @@ -105,7 +105,7 @@ int main()
while (running)
{
// Send a fast packet message
isobus::CANNetworkManager::CANNetwork.get_fast_packet_protocol().send_multipacket_message(0x1F001, testMessageData, TEST_MESSAGE_LENGTH, &TestInternalECU, nullptr, isobus::CANIdentifier::PriorityLowest7, nmea2k_transmit_complete_callback);
isobus::CANNetworkManager::CANNetwork.get_fast_packet_protocol().send_multipacket_message(0x1F001, testMessageData, TEST_MESSAGE_LENGTH, TestInternalECU, nullptr, isobus::CANIdentifier::PriorityLowest7, nmea2k_transmit_complete_callback);

// Sleep for a while
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
Expand Down
12 changes: 6 additions & 6 deletions examples/pgn_requests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

//! It is discouraged to use global variables, but it is done here for simplicity.
static std::uint32_t propARepetitionRate_ms = 0xFFFFFFFF;
static isobus::ControlFunction *repetitionRateRequestor = nullptr;
static std::shared_ptr<isobus::ControlFunction> repetitionRateRequestor = nullptr;
static std::atomic_bool running = { true };

void signal_handler(int)
Expand All @@ -22,7 +22,7 @@ void signal_handler(int)
}

bool example_proprietary_a_pgn_request_handler(std::uint32_t parameterGroupNumber,
isobus::ControlFunction *,
std::shared_ptr<isobus::ControlFunction>,
bool &acknowledge,
isobus::AcknowledgementType &acknowledgeType,
void *)
Expand Down Expand Up @@ -50,7 +50,7 @@ bool example_proprietary_a_pgn_request_handler(std::uint32_t parameterGroupNumbe
}

bool example_proprietary_a_request_for_repetition_rate_handler(std::uint32_t parameterGroupNumber,
isobus::ControlFunction *requestingControlFunction,
std::shared_ptr<isobus::ControlFunction> requestingControlFunction,
std::uint32_t repetitionRate,
void *)
{
Expand Down Expand Up @@ -125,7 +125,7 @@ int main()
TestDeviceNAME.set_device_class_instance(0);
TestDeviceNAME.set_manufacturer_code(64);

std::shared_ptr<isobus::InternalControlFunction> TestInternalECU = std::make_shared<isobus::InternalControlFunction>(TestDeviceNAME, 0x1C, 0);
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1C, 0);
std::signal(SIGINT, signal_handler);

// Wait to make sure address claiming is done. The time is arbitrary.
Expand Down Expand Up @@ -157,7 +157,7 @@ int main()

// This is how you would request a PGN from someone else. In this example, we request it from the broadcast address.
// Generally you'd want to replace nullptr with your partner control function as its a little nicer than just asking everyone on the bus for a PGN
isobus::ParameterGroupNumberRequestProtocol::request_parameter_group_number(static_cast<std::uint32_t>(isobus::CANLibParameterGroupNumber::ProprietaryA), TestInternalECU.get(), nullptr);
isobus::ParameterGroupNumberRequestProtocol::request_parameter_group_number(static_cast<std::uint32_t>(isobus::CANLibParameterGroupNumber::ProprietaryA), TestInternalECU, nullptr);
}

while (running)
Expand All @@ -166,7 +166,7 @@ int main()
{
// If someone has requested a repetition rate for PROPA, service it here (in the application layer)
std::uint8_t buffer[isobus::CAN_DATA_LENGTH] = { 0 };
isobus::CANNetworkManager::CANNetwork.send_can_message(static_cast<std::uint32_t>(isobus::CANLibParameterGroupNumber::ProprietaryA), buffer, isobus::CAN_DATA_LENGTH, TestInternalECU.get(), repetitionRateRequestor);
isobus::CANNetworkManager::CANNetwork.send_can_message(static_cast<std::uint32_t>(isobus::CANLibParameterGroupNumber::ProprietaryA), buffer, isobus::CAN_DATA_LENGTH, TestInternalECU, repetitionRateRequestor);
std::this_thread::sleep_for(std::chrono::milliseconds(propARepetitionRate_ms));
}
else
Expand Down
4 changes: 2 additions & 2 deletions examples/task_controller_client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ int main()

const isobus::NAMEFilter filterTaskController(isobus::NAME::NAMEParameters::FunctionCode, static_cast<std::uint8_t>(isobus::NAME::Function::TaskController));
const std::vector<isobus::NAMEFilter> tcNameFilters = { filterTaskController };
auto TestInternalECU = std::make_shared<isobus::InternalControlFunction>(TestDeviceNAME, 0x1C, 0);
auto TestPartnerTC = std::make_shared<isobus::PartneredControlFunction>(0, tcNameFilters);
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1C, 0);
auto TestPartnerTC = isobus::PartneredControlFunction::create(0, tcNameFilters);

TestTCClient = std::make_shared<isobus::TaskControllerClient>(TestPartnerTC, TestInternalECU, nullptr);

Expand Down
14 changes: 7 additions & 7 deletions examples/transport_layer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ int main()

const isobus::NAMEFilter filterVirtualTerminal(isobus::NAME::NAMEParameters::FunctionCode, static_cast<std::uint8_t>(isobus::NAME::Function::VirtualTerminal));

isobus::InternalControlFunction TestInternalECU(TestDeviceNAME, 0x1C, 0);
isobus::PartneredControlFunction TestPartner(0, { filterVirtualTerminal });
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1C, 0);
auto TestPartner = isobus::PartneredControlFunction::create(0, { filterVirtualTerminal });

// Wait to make sure address claiming is done. The time is arbitrary.
//! @todo Check this instead of asuming it is done
Expand All @@ -91,14 +91,14 @@ int main()
}

// Send a classic CAN message to a specific destination(8 bytes or less)
if (running && isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, ETPTestBuffer, isobus::CAN_DATA_LENGTH, &TestInternalECU, &TestPartner))
if (running && isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, ETPTestBuffer, isobus::CAN_DATA_LENGTH, TestInternalECU, TestPartner))
{
std::cout << "Sent a normal CAN Message with length 8" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(4)); // Arbitrary
}

// Send a classic CAN message to global (0xFF) (8 bytes or less)
if (running && isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, ETPTestBuffer, isobus::CAN_DATA_LENGTH, &TestInternalECU))
if (running && isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, ETPTestBuffer, isobus::CAN_DATA_LENGTH, TestInternalECU))
{
std::cout << "Sent a broadcast CAN Message with length 8" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(4)); // Arbitrary
Expand All @@ -115,7 +115,7 @@ int main()
}

// Send message
if (isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, TPTestBuffer, i, &TestInternalECU, &TestPartner))
if (isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, TPTestBuffer, i, TestInternalECU, TestPartner))
{
std::cout << "Started TP CM Session with length " << i << std::endl;
}
Expand All @@ -139,7 +139,7 @@ int main()
}

// Send message
if (isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, TPTestBuffer, i, &TestInternalECU))
if (isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, TPTestBuffer, i, TestInternalECU))
{
std::cout << "Started BAM Session with length " << i << std::endl;
}
Expand All @@ -153,7 +153,7 @@ int main()

// ETP Example
// Send one ETP message
if (running && isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, ETPTestBuffer, ETP_TEST_SIZE, &TestInternalECU, &TestPartner))
if (running && isobus::CANNetworkManager::CANNetwork.send_can_message(0xEF00, ETPTestBuffer, ETP_TEST_SIZE, TestInternalECU, TestPartner))
{
std::cout << "Started ETP Session with length " << ETP_TEST_SIZE << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
Expand Down
4 changes: 2 additions & 2 deletions examples/virtual_terminal/aux_functions/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ int main()

const isobus::NAMEFilter filterVirtualTerminal(isobus::NAME::NAMEParameters::FunctionCode, static_cast<std::uint8_t>(isobus::NAME::Function::VirtualTerminal));
const std::vector<isobus::NAMEFilter> vtNameFilters = { filterVirtualTerminal };
auto TestInternalECU = std::make_shared<isobus::InternalControlFunction>(TestDeviceNAME, 0x1D, 0);
auto TestPartnerVT = std::make_shared<isobus::PartneredControlFunction>(0, vtNameFilters);
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1D, 0);
auto TestPartnerVT = isobus::PartneredControlFunction::create(0, vtNameFilters);

TestVirtualTerminalClient = std::make_shared<isobus::VirtualTerminalClient>(TestPartnerVT, TestInternalECU);
TestVirtualTerminalClient->set_object_pool(0, isobus::VirtualTerminalClient::VTVersion::Version3, testPool.data(), testPool.size(), objectPoolHash);
Expand Down
4 changes: 2 additions & 2 deletions examples/virtual_terminal/aux_inputs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ int main()

const isobus::NAMEFilter filterVirtualTerminal(isobus::NAME::NAMEParameters::FunctionCode, static_cast<std::uint8_t>(isobus::NAME::Function::VirtualTerminal));
const std::vector<isobus::NAMEFilter> vtNameFilters = { filterVirtualTerminal };
auto TestInternalECU = std::make_shared<isobus::InternalControlFunction>(TestDeviceNAME, 0x1E, 0);
auto TestPartnerVT = std::make_shared<isobus::PartneredControlFunction>(0, vtNameFilters);
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1E, 0);
auto TestPartnerVT = isobus::PartneredControlFunction::create(0, vtNameFilters);

TestVirtualTerminalClient = std::make_shared<isobus::VirtualTerminalClient>(TestPartnerVT, TestInternalECU);
TestVirtualTerminalClient->set_object_pool(0, isobus::VirtualTerminalClient::VTVersion::Version3, testPool.data(), testPool.size(), objectPoolHash);
Expand Down
4 changes: 2 additions & 2 deletions examples/virtual_terminal/version3_object_pool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ int main()

const isobus::NAMEFilter filterVirtualTerminal(isobus::NAME::NAMEParameters::FunctionCode, static_cast<std::uint8_t>(isobus::NAME::Function::VirtualTerminal));
const std::vector<isobus::NAMEFilter> vtNameFilters = { filterVirtualTerminal };
auto TestInternalECU = std::make_shared<isobus::InternalControlFunction>(TestDeviceNAME, 0x1C, 0);
auto TestPartnerVT = std::make_shared<isobus::PartneredControlFunction>(0, vtNameFilters);
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1C, 0);
auto TestPartnerVT = isobus::PartneredControlFunction::create(0, vtNameFilters);

TestVirtualTerminalClient = std::make_shared<isobus::VirtualTerminalClient>(TestPartnerVT, TestInternalECU);
TestVirtualTerminalClient->set_object_pool(0, isobus::VirtualTerminalClient::VTVersion::Version3, testPool.data(), testPool.size(), objectPoolHash);
Expand Down
14 changes: 7 additions & 7 deletions isobus/include/isobus/isobus/can_callbacks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ namespace isobus
/// @brief A callback for when a transmit is completed by the stack
using TransmitCompleteCallback = void (*)(std::uint32_t parameterGroupNumber,
std::uint32_t dataLength,
InternalControlFunction *sourceControlFunction,
ControlFunction *destinationControlFunction,
std::shared_ptr<InternalControlFunction> sourceControlFunction,
std::shared_ptr<ControlFunction> destinationControlFunction,
bool successful,
void *parentPointer);
/// @brief A callback for handling a PGN request
using PGNRequestCallback = bool (*)(std::uint32_t parameterGroupNumber,
ControlFunction *requestingControlFunction,
std::shared_ptr<ControlFunction> requestingControlFunction,
bool &acknowledge,
AcknowledgementType &acknowledgeType,
void *parentPointer);
/// @brief A callback for handling a request for repetition rate for a specific PGN
using PGNRequestForRepetitionRateCallback = bool (*)(std::uint32_t parameterGroupNumber,
ControlFunction *requestingControlFunction,
std::shared_ptr<ControlFunction> requestingControlFunction,
std::uint32_t repetitionRate,
void *parentPointer);

Expand All @@ -67,7 +67,7 @@ namespace isobus
/// @param[in] callback The function you want the stack to call when it gets receives a message with a matching PGN
/// @param[in] parentPointer A generic variable that can provide context to which object the callback was meant for
/// @param[in] internalControlFunction An internal control function to use as an additional filter for the callback
ParameterGroupNumberCallbackData(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parentPointer, InternalControlFunction *internalControlFunction);
ParameterGroupNumberCallbackData(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parentPointer, std::shared_ptr<InternalControlFunction> internalControlFunction);

/// @brief A copy constructor for holding callback data
/// @param[in] oldObj The object to copy from
Expand Down Expand Up @@ -96,13 +96,13 @@ namespace isobus

/// @brief Returns the ICF being used as a filter for this callback
/// @returns A pointer to the ICF being used as a filter, or nullptr
InternalControlFunction *get_internal_control_function() const;
std::shared_ptr<InternalControlFunction> get_internal_control_function() const;

private:
CANLibCallback mCallback; ///< The callback that will get called when a matching PGN is received
std::uint32_t mParameterGroupNumber; ///< The PGN assocuiated with this callback
void *mParent; ///< A generic variable that can provide context to which object the callback was meant for
InternalControlFunction *mInternalControlFunctionFilter; ///< An optional way to filter callbacks based on the destination of messages from the partner
std::shared_ptr<InternalControlFunction> mInternalControlFunctionFilter; ///< An optional way to filter callbacks based on the destination of messages from the partner
};
} // namespace isobus

Expand Down
32 changes: 24 additions & 8 deletions isobus/include/isobus/isobus/can_control_function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
///
/// @brief Defines a base class to represent a generic ISOBUS control function.
/// @author Adrian Del Grosso
/// @author Daan Steenbergen
///
/// @copyright 2022 Adrian Del Grosso
//================================================================================================
Expand All @@ -12,6 +13,7 @@

#include "isobus/isobus/can_NAME.hpp"

#include <memory>
#include <mutex>

namespace isobus
Expand All @@ -21,7 +23,7 @@ namespace isobus
///
/// @brief A class that describes an ISO11783 control function, which includes a NAME and address.
//================================================================================================
class ControlFunction
class ControlFunction : public std::enable_shared_from_this<ControlFunction>
{
public:
/// @brief The type of the control function
Expand All @@ -32,14 +34,18 @@ namespace isobus
Partnered ///< An external control function that you explicitly want to talk to
};

/// @brief The base class constructor for a control function
virtual ~ControlFunction() = default;

/// @brief The factory function to construct a control function
/// @param[in] NAMEValue The NAME of the control function
/// @param[in] addressValue The current address of the control function
/// @param[in] CANPort The CAN channel index that the control function communicates on
ControlFunction(NAME NAMEValue, std::uint8_t addressValue, std::uint8_t CANPort);
static std::shared_ptr<ControlFunction> create(NAME NAMEValue, std::uint8_t addressValue, std::uint8_t CANPort);

/// @brief The base class destructor for a control function
virtual ~ControlFunction();
/// @brief Destroys this control function, by removing it from the network manager
/// @param[in] expectedRefCount The expected number of shared pointers to this control function after removal
/// @returns true if the control function was successfully removed from everywhere in the stack, otherwise false
virtual bool destroy(std::uint32_t expectedRefCount = 1);

/// @brief Returns the current address of the control function
/// @returns The current address of the control function
Expand All @@ -61,14 +67,24 @@ namespace isobus
/// @returns The control function type
Type get_type() const;

///@brief Returns the 'Type' of the control function as a string
///@returns The control function type as a string
std::string get_type_string() const;

protected:
/// @brief The protected constructor for the control function, which is called by the (inherited) factory function
/// @param[in] NAMEValue The NAME of the control function
/// @param[in] addressValue The current address of the control function
/// @param[in] CANPort The CAN channel index that the control function communicates on
ControlFunction(NAME NAMEValue, std::uint8_t addressValue, std::uint8_t CANPort, Type type = Type::External);

friend class CANNetworkManager;
static std::mutex controlFunctionProcessingMutex; ///< Protects the control function tables
const Type controlFunctionType; ///< The Type of the control function
NAME controlFunctionNAME; ///< The NAME of the control function
Type controlFunctionType = Type::External; ///< The Type of the control function
std::uint8_t address; ///< The address of the control function
std::uint8_t canPortIndex; ///< The CAN channel index of the control function
bool claimedAddressSinceLastAddressClaimRequest = false; ///< Used to mark CFs as stale if they don't claim within a certain time
std::uint8_t address; ///< The address of the control function
const std::uint8_t canPortIndex; ///< The CAN channel index of the control function
};

} // namespace isobus
Expand Down
Loading

0 comments on commit 41c51d9

Please sign in to comment.