-
Notifications
You must be signed in to change notification settings - Fork 3
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
Data Broker #98
Open
shivamdesai04
wants to merge
8
commits into
Chris/UartDriver-DISCO
Choose a base branch
from
Shivam/DataBrokerDisco
base: Chris/UartDriver-DISCO
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Data Broker #98
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
d5e015a
Init
shivamdesai04 919208b
Add ability to check if subscriber already exists
shivamdesai04 dfc5e52
Protect Data Router Functions with Mutex
shivamdesai04 5e2898c
Added Data Parser
shivamdesai04 15a7afb
Rename class functions to avoid long names
shivamdesai04 74fd621
tabs to spaces
shivamdesai04 90ec9d0
Rename API from PublishData to Publish
shivamdesai04 3532b7c
Update with example of adding thermcouple publisher to wdg tsk
shivamdesai04 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/** | ||
******************************************************************************** | ||
* @file DataBroker.hpp | ||
* @author shivam | ||
* @date Nov 23, 2024 | ||
* @brief | ||
******************************************************************************** | ||
*/ | ||
|
||
#ifndef DATA_BROKER_HPP_ | ||
#define DATA_BROKER_HPP_ | ||
|
||
/************************************ | ||
* INCLUDES | ||
************************************/ | ||
#include "Publisher.hpp" | ||
#include "SensorDataTypes.hpp" | ||
#include "Command.hpp" | ||
#include "DataBrokerMessageTypes.hpp" | ||
#include "SystemDefines.hpp" | ||
#include "Mutex.hpp" | ||
#include <type_traits> | ||
#include <cstring> | ||
|
||
/************************************ | ||
* MACROS AND DEFINES | ||
************************************/ | ||
|
||
/************************************ | ||
* TYPEDEFS | ||
************************************/ | ||
|
||
/************************************ | ||
* CLASS DEFINITIONS | ||
************************************/ | ||
class DataBroker { | ||
public: | ||
/** | ||
* @brief Publish data of a certain type | ||
* NOTE: You must ensure that there is a publisher for that type | ||
*/ | ||
template <typename T> | ||
static void Publish(T* dataToPublish) { | ||
if (subscriberListLock.Lock(SUBSCRIBER_LIST_MUTEX_TIMEOUT)) { | ||
Publisher<T>* publisher = getPublisher<T>(); | ||
if (publisher != nullptr) { | ||
publisher->Publish(dataToPublish); | ||
} | ||
else { | ||
SOAR_ASSERT("Data Publisher not found \n"); | ||
} | ||
subscriberListLock.Unlock(); | ||
return; | ||
} | ||
else { | ||
SOAR_PRINT("Could Not Subscribe to Data Broker Publisher \n"); | ||
} | ||
return; | ||
} | ||
|
||
/** | ||
* @brief Subscribe to a certain type of data in the system | ||
* @param taskToSubscribe Task Handle of the task that will receive | ||
* and handle the data. (i.e. -> Subscribe<T>(this)) | ||
*/ | ||
template <typename T> | ||
static void Subscribe(Task* taskToSubscribe) { | ||
if (subscriberListLock.Lock(SUBSCRIBER_LIST_MUTEX_TIMEOUT)) { | ||
Publisher<T>* publisher = getPublisher<T>(); | ||
if (publisher != nullptr) { | ||
publisher->Subscribe(taskToSubscribe); | ||
} | ||
else { | ||
SOAR_ASSERT("Data Publisher not found \n"); | ||
} | ||
subscriberListLock.Unlock(); | ||
return; | ||
} | ||
else { | ||
SOAR_PRINT("Could Not Subscribe to Data Broker Publisher \n"); | ||
} | ||
return; | ||
} | ||
|
||
/** | ||
* @brief Unsubscribe to a certain type of data in the system | ||
* @param taskToUnsubscribe Task Handle of the task that will stop | ||
* receiving the data. (i.e. -> Unsubscribe<T>(this)) | ||
*/ | ||
template <typename T> | ||
static void Unsubscribe(Task* taskToUnsubscribe) { | ||
if (subscriberListLock.Lock(SUBSCRIBER_LIST_MUTEX_TIMEOUT)) { | ||
Publisher<T>* publisher = getPublisher<T>(); | ||
if (publisher != nullptr) { | ||
publisher->Unsubscribe(taskToUnsubscribe); | ||
} | ||
else { | ||
SOAR_ASSERT("Data Publisher not found \n"); | ||
} | ||
subscriberListLock.Unlock(); | ||
return; | ||
} | ||
else { | ||
SOAR_PRINT("Could Not Unsubscribe to Data Broker Publisher \n"); | ||
} | ||
return; | ||
} | ||
|
||
template <typename T> | ||
static constexpr T ExtractData(const Command &cm) { | ||
if (cm.GetCommand() != DATA_BROKER_COMMAND) { | ||
SOAR_ASSERT("Not a Data Broker Command!\n"); | ||
} | ||
|
||
// The data allocated by this command ptr will be freed when cm.Reset()] | ||
// is called. So we do not have to free this memory here | ||
T* dataPtr = reinterpret_cast<T*>(cm.GetDataPointer()); | ||
|
||
T data{}; | ||
|
||
std::memcpy(&data, dataPtr, sizeof(T)); | ||
|
||
return data; | ||
} | ||
|
||
static DataBrokerMessageTypes getMessageType(const Command &cm) { | ||
return static_cast<DataBrokerMessageTypes>(cm.GetTaskCommand()); | ||
} | ||
|
||
private: | ||
// Deleting the default constructor as this class is not | ||
// instanceable | ||
DataBroker() = delete; | ||
|
||
// Deleting the copy constructor to prevent copies | ||
DataBroker(const DataBroker& obj) = delete; | ||
|
||
// Deleting assignment operator to prevent assignment operations | ||
DataBroker& operator=(DataBroker const&) = delete; | ||
|
||
// Mutex to access the Subscriber List | ||
inline static Mutex subscriberListLock{}; | ||
// Mutex lock wait time | ||
static constexpr uint16_t SUBSCRIBER_LIST_MUTEX_TIMEOUT = 1000; | ||
|
||
// matcher - match template type with publisher type | ||
template <typename T, typename U> | ||
static constexpr bool matchType() { | ||
return std::is_same_v<T, U>; | ||
} | ||
|
||
// get data publisher | ||
template <typename T> | ||
static constexpr auto getPublisher(void) { | ||
if constexpr (matchType<T, IMUData>()) { | ||
return &IMU_Data_publisher; | ||
} else if constexpr (matchType<T, ThermocoupleData>()) { | ||
return &Thermocouple_Data_publisher; | ||
} else { | ||
SOAR_ASSERT(false, "This publisher type does not exist, you must create it"); | ||
} | ||
} | ||
|
||
// list of publishers | ||
inline static Publisher<IMUData> IMU_Data_publisher {DataBrokerMessageTypes::IMU_DATA}; | ||
inline static Publisher<ThermocoupleData> Thermocouple_Data_publisher {DataBrokerMessageTypes::THERMOCOUPLE_DATA}; | ||
|
||
}; | ||
/************************************ | ||
* FUNCTION DECLARATIONS | ||
************************************/ | ||
|
||
#endif /* DATA_BROKER_HPP_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/** | ||
******************************************************************************** | ||
* @file Publisher.hpp | ||
* @author shivam | ||
* @date Nov 23, 2024 | ||
* @brief | ||
******************************************************************************** | ||
*/ | ||
|
||
#ifndef PUBLISHER_HPP_ | ||
#define PUBLISHER_HPP_ | ||
|
||
/************************************ | ||
* INCLUDES | ||
************************************/ | ||
#include <DataBrokerMessageTypes.hpp> | ||
#include <stdint.h> | ||
#include <array> | ||
#include "Task.hpp" | ||
#include "Subscriber.hpp" | ||
#include "SystemDefines.hpp" | ||
|
||
|
||
/************************************ | ||
* MACROS AND DEFINES | ||
************************************/ | ||
|
||
/************************************ | ||
* TYPEDEFS | ||
************************************/ | ||
|
||
/************************************ | ||
* CLASS DEFINITIONS | ||
************************************/ | ||
template <typename T, uint8_t MaxSubscribers = 5> | ||
class Publisher { | ||
public: | ||
// Constructor | ||
Publisher(DataBrokerMessageTypes messageType) { | ||
publisherMessageType = messageType; | ||
} | ||
|
||
// subscribe | ||
bool Subscribe(Task* taskToSubscribe) { | ||
// Check if subscriber already exists | ||
for (Subscriber& subscriber : subscribersList) { | ||
if (subscriber.getSubscriberTaskHandle() == taskToSubscribe) { | ||
return true; | ||
} | ||
} | ||
|
||
// Add the subscriber | ||
for (Subscriber& subscriber : subscribersList) { | ||
if (subscriber.getSubscriberTaskHandle() == nullptr) { | ||
subscriber.Init(taskToSubscribe); | ||
return true; | ||
} | ||
} | ||
|
||
SOAR_ASSERT(true, "Failed to add subscriber\n"); | ||
return false; | ||
} | ||
|
||
// unsubscribe | ||
bool Unsubscribe(Task* taskToUnsubscribe) { | ||
for (Subscriber& subscriber : subscribersList) { | ||
if (subscriber.getSubscriberTaskHandle() == taskToUnsubscribe) { | ||
subscriber.Delete(); | ||
return true; | ||
} | ||
} | ||
|
||
SOAR_ASSERT(true, "Subscriber not Deleted\n"); | ||
return false; | ||
} | ||
|
||
// publish | ||
void Publish(T* dataToPublish) { | ||
for (const Subscriber& subscriber : subscribersList) { | ||
if (subscriber.getSubscriberTaskHandle() != nullptr) { | ||
// create command | ||
uint16_t messageType = static_cast<uint16_t>(publisherMessageType); | ||
|
||
Command brokerData(DATA_BROKER_COMMAND, messageType); | ||
|
||
uint8_t* messsageData = reinterpret_cast<uint8_t*>(dataToPublish); | ||
|
||
// copy data to command | ||
brokerData.CopyDataToCommand(messsageData, sizeof(T)); | ||
|
||
subscriber.getSubscriberQueueHandle()->Send(brokerData); | ||
} | ||
} | ||
} | ||
|
||
private: | ||
// list of subscribers | ||
Subscriber subscribersList[MaxSubscribers] = {}; | ||
|
||
// message type for system routing | ||
DataBrokerMessageTypes publisherMessageType = DataBrokerMessageTypes::INVALID; | ||
}; | ||
|
||
/************************************ | ||
* FUNCTION DECLARATIONS | ||
************************************/ | ||
|
||
#endif /* PUBLISHER_HPP_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/** | ||
******************************************************************************** | ||
* @file Subscriber.hpp | ||
* @author shiva | ||
* @date Nov 23, 2024 | ||
* @brief | ||
******************************************************************************** | ||
*/ | ||
|
||
#ifndef SUBSCRIBER_HPP_ | ||
#define SUBSCRIBER_HPP_ | ||
|
||
/************************************ | ||
* INCLUDES | ||
************************************/ | ||
#include "Task.hpp" | ||
#include "SystemDefines.hpp" | ||
|
||
/************************************ | ||
* MACROS AND DEFINES | ||
************************************/ | ||
|
||
/************************************ | ||
* TYPEDEFS | ||
************************************/ | ||
|
||
/************************************ | ||
* CLASS DEFINITIONS | ||
************************************/ | ||
class Subscriber { | ||
public: | ||
void Init(Task* subscriberTaskHandle) { | ||
if (taskHandle != nullptr || taskQueue != nullptr) { | ||
SOAR_ASSERT(false, "You cannot overwrite a subscriber"); | ||
return; | ||
} | ||
taskHandle = subscriberTaskHandle; | ||
taskQueue = taskHandle->GetEventQueue(); | ||
} | ||
|
||
void Delete() { | ||
taskHandle = nullptr; | ||
taskQueue = nullptr; | ||
} | ||
|
||
inline const Task* getSubscriberTaskHandle() const { return taskHandle; } | ||
|
||
inline Queue* getSubscriberQueueHandle() const { return taskQueue; } | ||
|
||
private: | ||
Task* taskHandle = nullptr; | ||
Queue* taskQueue = nullptr; | ||
}; | ||
|
||
/************************************ | ||
* FUNCTION DECLARATIONS | ||
************************************/ | ||
|
||
#endif /* SUBSCRIBER_HPP_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider making a static instance of the class instead of making everything in the class static