Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TC]: Extending DDOP with binary object pool #524

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "isobus/isobus/can_NAME.hpp"
#include "isobus/isobus/isobus_task_controller_client_objects.hpp"

#include <functional>
#include <memory>

namespace isobus
Expand Down Expand Up @@ -107,25 +108,43 @@ namespace isobus
std::uint8_t numberDecimals,
std::uint16_t uniqueID);

/// @brief Removes all objects from the DDOP that have a certain type
/// @param objectType The type of object to remove
/// @returns `true` if any objects were removed, `false` if no objects were removed
bool remove_objects_with_type(task_controller_object::ObjectTypes objectType);

/// @brief Removes all objects from the DDOP that have a certain object ID
/// @param objectID The object ID to remove
/// @returns `true` if any objects were removed, `false` if no objects were removed
bool remove_object_with_id(std::uint16_t objectID);

/// @brief Removes all objects from the DDOP that match a certain predicate
/// @param predicate The predicate to match against
/// @returns `true` if any objects were removed, `false` if no objects were removed
bool remove_where(std::function<bool(const task_controller_object::Object &)> predicate);

/// @brief Attempts to take a binary object pool and convert it back into
/// C++ objects. Useful for a task controller server or to view the content
/// C++ objects. The object's will be added to the list of objects,
/// or replaced if an object already exists with the same identifier.
/// of a DDOP captured in a CAN log, for example.
/// @param binaryPool The binary object pool, as an array of bytes.
/// @param clientNAME The ISO NAME of the source ECU for this DDOP, or NAME(0) to ignore checking against actual ECU NAME
/// @returns True if the object pool was successfully deserialized, otherwise false.
/// NOTE: This only means that the pool was deserialized. It does not mean that the
/// @note This only means that the pool was deserialized. It does not mean that the
/// relationship between objects is valid. You may have to do additional
/// checking on the pool before using it.
bool deserialize_binary_object_pool(std::vector<std::uint8_t> &binaryPool, NAME clientNAME = NAME(0));

/// @brief Attempts to take a binary object pool and convert it back into
/// C++ objects. Useful for a task controller server or to view the content
/// C++ objects. The object's will be added to the list of objects,
/// or replaced if an object already exists with the same identifier.
/// Useful for a task controller server or to view the content
/// of a DDOP captured in a CAN log, for example.
/// @param binaryPool The binary object pool, as an array of bytes.
/// @param binaryPoolSizeBytes The size of the DDOP to process in bytes.
/// @param clientNAME The ISO NAME of the source ECU for this DDOP, or NAME(0) to ignore checking against actual ECU NAME
/// @returns True if the object pool was successfully deserialized, otherwise false.
/// NOTE: This only means that the pool was deserialized. It does not mean that the
/// @note This only means that the pool was deserialized. It does not mean that the
/// relationship between objects is valid. You may have to do additional
/// checking on the pool before using it.
bool deserialize_binary_object_pool(const std::uint8_t *binaryPool, std::uint32_t binaryPoolSizeBytes, NAME clientNAME = NAME(0));
Expand Down
35 changes: 34 additions & 1 deletion isobus/src/isobus_device_descriptor_object_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,35 @@ namespace isobus
return retVal;
}

bool DeviceDescriptorObjectPool::remove_objects_with_type(task_controller_object::ObjectTypes objectType)
{
return remove_where([objectType](const task_controller_object::Object &object) { return object.get_object_type() == objectType; });
}

bool DeviceDescriptorObjectPool::remove_object_with_id(std::uint16_t objectID)
{
return remove_where([objectID](const task_controller_object::Object &object) { return object.get_object_id() == objectID; });
}

bool DeviceDescriptorObjectPool::remove_where(std::function<bool(const task_controller_object::Object &)> predicate)
{
bool retVal = false;

for (auto it = objectList.begin(); it != objectList.end();)
{
if (predicate(*(*it)))
{
it = objectList.erase(it);
retVal = true;
}
else
{
++it;
}
}
return retVal;
}

bool DeviceDescriptorObjectPool::deserialize_binary_object_pool(std::vector<std::uint8_t> &binaryPool, NAME clientNAME)
{
return deserialize_binary_object_pool(binaryPool.data(), static_cast<std::uint32_t>(binaryPool.size()), clientNAME);
Expand All @@ -357,7 +386,6 @@ namespace isobus
if ((nullptr != binaryPool) && (0 != binaryPoolSizeBytes))
{
LOG_DEBUG("[DDOP]: Attempting to deserialize a binary object pool with size %u.", binaryPoolSizeBytes);
clear();

// Iterate over the DDOP and convert to objects.
// Using the size to track how much is left to process.
Expand Down Expand Up @@ -489,6 +517,7 @@ namespace isobus
extendedStructureLabel.push_back(binaryPool[31 + numberDeviceSerialNumberBytes + numberDesignatorBytes + numberSoftwareVersionBytes + i]);
}

remove_objects_with_type(task_controller_object::ObjectTypes::Device); // Make sure the previous device object is removed
if (add_device(deviceDesignator, deviceSoftwareVersion, deviceSerialNumber, deviceStructureLabel, localizationLabel, extendedStructureLabel, clientNAME.get_full_name()))
{
binaryPoolSizeBytes -= expectedSize;
Expand Down Expand Up @@ -553,6 +582,7 @@ namespace isobus
deviceElementDesignator.push_back(binaryPool[7 + i]);
}

remove_object_with_id(uniqueID); // Make sure the previous device element object is removed
if (add_device_element(deviceElementDesignator, elementNumber, parentObject, type, uniqueID))
{
auto DETObject = std::static_pointer_cast<task_controller_object::DeviceElementObject>(get_object_by_id(uniqueID));
Expand Down Expand Up @@ -611,6 +641,7 @@ namespace isobus
processDataDesignator.push_back(binaryPool[10 + i]);
}

remove_object_with_id(uniqueID); // Make sure the previous device process data object is removed
if (add_device_process_data(processDataDesignator, DDI, presentationObjectID, binaryPool[7], binaryPool[8], uniqueID))
{
binaryPoolSizeBytes -= expectedSize;
Expand Down Expand Up @@ -661,6 +692,7 @@ namespace isobus
designator.push_back(binaryPool[12 + i]);
}

remove_object_with_id(uniqueID); // Make sure the previous device property object is removed
if (add_device_property(designator, propertyValue, DDI, presentationObjectID, uniqueID))
{
binaryPoolSizeBytes -= expectedSize;
Expand Down Expand Up @@ -723,6 +755,7 @@ namespace isobus
designator.push_back(binaryPool[15 + i]);
}

remove_object_with_id(uniqueID); // Make sure the previous device value presentation object is removed
if (add_device_value_presentation(designator, offset, scale, binaryPool[13], uniqueID))
{
binaryPoolSizeBytes -= expectedSize;
Expand Down
Loading