-
Notifications
You must be signed in to change notification settings - Fork 58
Add middleware proxy, skeleton and cluster connections #363
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
Merged
Merged
Changes from all commits
Commits
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 hidden or 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 hidden or 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 hidden or 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
61 changes: 61 additions & 0 deletions
61
libs/bsw/middleware/include/middleware/concurrency/LockStrategies.h
This file contains hidden or 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,61 @@ | ||
| // Copyright 2025 BMW AG | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cstdint> | ||
|
|
||
| namespace middleware | ||
| { | ||
| namespace concurrency | ||
| { | ||
|
|
||
| /** | ||
| * Suspend all interrupts. | ||
| * Platform-specific function that suspends all interrupts to ensure critical sections | ||
| * are protected. This is used in conjunction with lock strategies for thread-safe operations. | ||
| * The implementation must be provided for each platform integration. | ||
| */ | ||
| extern void suspendAllInterrupts(); | ||
|
|
||
| /** | ||
| * Scoped lock for single-core protection. | ||
| * RAII-style lock that protects critical sections within a single core by disabling | ||
| * interrupts or using other single-core synchronization mechanisms. The lock is acquired in the | ||
| * constructor and automatically released in the destructor, ensuring proper cleanup even in the | ||
| * presence of exceptions. | ||
| * The implementation must be provided for each platform integration. | ||
| */ | ||
| struct ScopedCoreLock | ||
| { | ||
| /** Acquires the single-core lock. */ | ||
| ScopedCoreLock(); | ||
|
|
||
| /** Releases the single-core lock. */ | ||
| ~ScopedCoreLock(); | ||
|
|
||
| ScopedCoreLock(ScopedCoreLock const&) = delete; | ||
| ScopedCoreLock& operator=(ScopedCoreLock const&) = delete; | ||
| }; | ||
|
|
||
| /** | ||
| * Scoped lock for ECU-wide (multi-core) protection. | ||
| * RAII-style lock that protects critical sections across multiple cores in an ECU by | ||
| * using hardware-supported spinlocks or other multi-core synchronization mechanisms. The lock is | ||
| * acquired in the constructor and automatically released in the destructor, ensuring proper | ||
| * cleanup even in the presence of exceptions. | ||
| * The implementation must be provided for each platform integration. | ||
| */ | ||
| struct ScopedECULock | ||
| { | ||
| /** Acquires the ECU-wide lock using \p lock. */ | ||
| ScopedECULock(uint8_t volatile* lock); | ||
|
|
||
| /** Releases the ECU-wide lock. */ | ||
| ~ScopedECULock(); | ||
|
|
||
| ScopedECULock(ScopedECULock const&) = delete; | ||
| ScopedECULock& operator=(ScopedECULock const&) = delete; | ||
| }; | ||
|
|
||
| } // namespace concurrency | ||
| } // namespace middleware | ||
284 changes: 284 additions & 0 deletions
284
libs/bsw/middleware/include/middleware/core/ClusterConnection.h
This file contains hidden or 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,284 @@ | ||
| // Copyright 2025 BMW AG | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <etl/type_traits.h> | ||
|
|
||
| #include "middleware/core/ClusterConnectionBase.h" | ||
| #include "middleware/core/IClusterConnectionConfigurationBase.h" | ||
| #include "middleware/core/Message.h" | ||
|
|
||
| namespace middleware | ||
| { | ||
| namespace core | ||
| { | ||
| class ProxyBase; | ||
| class SkeletonBase; | ||
|
|
||
| /** | ||
| * Cluster connection for proxy-only communication without timeout support. | ||
| * This class provides a cluster connection that only supports proxy subscriptions, | ||
| * without timeout management. Skeleton subscriptions are not implemented and will return | ||
| * NotImplemented. | ||
| */ | ||
| class ClusterConnectionNoTimeoutProxyOnly final : public ClusterConnectionBase | ||
| { | ||
| using Base = ClusterConnectionBase; | ||
|
|
||
| public: | ||
| /** Constructs from \p configuration. */ | ||
| explicit ClusterConnectionNoTimeoutProxyOnly( | ||
| IClusterConnectionConfigurationProxyOnly& configuration); | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(ProxyBase& proxy, uint16_t const serviceInstanceId) final; | ||
|
|
||
| /** Not supported: this is a proxy-only connection. */ | ||
| HRESULT subscribe(SkeletonBase&, uint16_t const) final { return HRESULT::NotImplemented; } | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(ProxyBase& proxy, uint16_t const serviceId) final; | ||
|
|
||
| /** No-op: this is a proxy-only connection. */ | ||
| void unsubscribe(SkeletonBase&, uint16_t const) final {} | ||
| }; | ||
|
|
||
| /** | ||
| * Cluster connection for skeleton-only communication without timeout support. | ||
| * This class provides a cluster connection that only supports skeleton subscriptions, | ||
| * without timeout management. Proxy subscriptions are not implemented and will return | ||
| * NotImplemented. | ||
| */ | ||
| class ClusterConnectionNoTimeoutSkeletonOnly final : public ClusterConnectionBase | ||
| { | ||
| using Base = ClusterConnectionBase; | ||
|
|
||
| public: | ||
| /** Constructs from \p configuration. */ | ||
| explicit ClusterConnectionNoTimeoutSkeletonOnly( | ||
| IClusterConnectionConfigurationSkeletonOnly& configuration); | ||
|
|
||
| /** Not supported: this is a skeleton-only connection. */ | ||
| HRESULT subscribe(ProxyBase&, uint16_t const) final { return HRESULT::NotImplemented; } | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(SkeletonBase& skeleton, uint16_t const serviceInstanceId) final; | ||
|
|
||
| /** No-op: this is a skeleton-only connection. */ | ||
| void unsubscribe(ProxyBase&, uint16_t const) final {} | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(SkeletonBase& skeleton, uint16_t const serviceId) final; | ||
| }; | ||
|
|
||
| /** | ||
| * Cluster connection for bidirectional communication without timeout support. | ||
| * This class provides a cluster connection that supports both proxy and skeleton | ||
| * subscriptions, without timeout management. It enables full bidirectional communication | ||
| * between clusters. | ||
| */ | ||
| class ClusterConnectionNoTimeoutBidirectional final : public ClusterConnectionBase | ||
| { | ||
| using Base = ClusterConnectionBase; | ||
|
|
||
| public: | ||
| /** Constructs from \p configuration. */ | ||
| explicit ClusterConnectionNoTimeoutBidirectional( | ||
| IClusterConnectionConfigurationBidirectional& configuration); | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(ProxyBase& proxy, uint16_t const serviceInstanceId) final; | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(SkeletonBase& skeleton, uint16_t const serviceInstanceId) final; | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(ProxyBase& proxy, uint16_t const serviceId) final; | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(SkeletonBase& skeleton, uint16_t const serviceId) final; | ||
| }; | ||
|
|
||
| /** | ||
| * Cluster connection for bidirectional communication with timeout support. | ||
| * This class provides a cluster connection that supports both proxy and skeleton | ||
| * subscriptions, with timeout management capabilities. It enables full bidirectional | ||
| * communication between clusters with timeout tracking. | ||
| */ | ||
| class ClusterConnectionBidirectionalWithTimeout final : public ClusterConnectionTimeoutBase | ||
| { | ||
| using Base = ClusterConnectionTimeoutBase; | ||
|
|
||
| public: | ||
| /** Constructs from \p configuration. */ | ||
| explicit ClusterConnectionBidirectionalWithTimeout( | ||
| IClusterConnectionConfigurationBidirectionalWithTimeout& configuration); | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(ProxyBase& proxy, uint16_t const serviceInstanceId) final; | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(SkeletonBase& skeleton, uint16_t const serviceInstanceId) final; | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(ProxyBase& proxy, uint16_t const serviceId) final; | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(SkeletonBase& skeleton, uint16_t const serviceId) final; | ||
| }; | ||
|
|
||
| /** | ||
| * Cluster connection for proxy-only communication with timeout support. | ||
| * This class provides a cluster connection that only supports proxy subscriptions, | ||
| * with timeout management capabilities. Skeleton subscriptions are not implemented. | ||
| */ | ||
| class ClusterConnectionProxyOnlyWithTimeout final : public ClusterConnectionTimeoutBase | ||
| { | ||
| using Base = ClusterConnectionTimeoutBase; | ||
|
|
||
| public: | ||
| /** Constructs from \p configuration. */ | ||
| explicit ClusterConnectionProxyOnlyWithTimeout( | ||
| IClusterConnectionConfigurationProxyOnlyWithTimeout& configuration); | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(ProxyBase& proxy, uint16_t const serviceInstanceId) final; | ||
|
|
||
| /** Not supported: this is a proxy-only connection. */ | ||
| HRESULT subscribe(SkeletonBase&, uint16_t const) final { return HRESULT::NotImplemented; } | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(ProxyBase& proxy, uint16_t const serviceId) final; | ||
|
|
||
| /** No-op: this is a proxy-only connection. */ | ||
| void unsubscribe(SkeletonBase&, uint16_t const) final {} | ||
| }; | ||
|
|
||
| /** | ||
| * Cluster connection for skeleton-only communication with timeout support. | ||
| * This class provides a cluster connection that only supports skeleton subscriptions, | ||
| * with timeout management capabilities. Proxy subscriptions are not implemented. | ||
| */ | ||
| class ClusterConnectionSkeletonOnlyWithTimeout final : public ClusterConnectionTimeoutBase | ||
| { | ||
| using Base = ClusterConnectionTimeoutBase; | ||
|
|
||
| public: | ||
| /** Constructs from \p configuration. */ | ||
| explicit ClusterConnectionSkeletonOnlyWithTimeout( | ||
| IClusterConnectionConfigurationSkeletonOnlyWithTimeout& configuration); | ||
|
|
||
| /** Not supported: this is a skeleton-only connection. */ | ||
| HRESULT subscribe(ProxyBase&, uint16_t const) final { return HRESULT::NotImplemented; } | ||
|
|
||
| /** \see IClusterConnection::subscribe() */ | ||
| HRESULT subscribe(SkeletonBase&, uint16_t const) final; | ||
|
|
||
| /** No-op: this is a skeleton-only connection. */ | ||
| void | ||
| unsubscribe([[maybe_unused]] ProxyBase& proxy, [[maybe_unused]] uint16_t const serviceId) final | ||
| {} | ||
|
|
||
| /** \see IClusterConnection::unsubscribe() */ | ||
| void unsubscribe(SkeletonBase&, [[maybe_unused]] uint16_t const) final; | ||
| }; | ||
|
|
||
| /** | ||
| * Type selector for cluster connection implementations. | ||
| * This template struct selects the appropriate cluster connection type based on the | ||
| * configuration type provided. It uses SFINAE (Substitution Failure Is Not An Error) with | ||
| * enable_if to select the correct specialization. Instantiation without a valid configuration | ||
| * type will lead to a compilation error by design. | ||
| * | ||
| * \tparam T the configuration type | ||
| * \tparam Specialization SFINAE enabler parameter | ||
| */ | ||
| template<typename T, typename Specialization = void> | ||
| struct ClusterConnectionTypeSelector; | ||
|
|
||
| /** | ||
| * Type selector specialization for proxy-only configurations. | ||
| * \tparam T the proxy-only configuration type | ||
| */ | ||
| template<typename T> | ||
| struct ClusterConnectionTypeSelector< | ||
| T, | ||
| typename etl::enable_if< | ||
| etl::is_base_of<IClusterConnectionConfigurationProxyOnly, T>::value>::type> | ||
| { | ||
| /** The selected cluster connection type. */ | ||
| using type = ClusterConnectionNoTimeoutProxyOnly; | ||
| }; | ||
|
|
||
| /** | ||
| * Type selector specialization for skeleton-only configurations. | ||
| * \tparam T the skeleton-only configuration type | ||
| */ | ||
| template<typename T> | ||
| struct ClusterConnectionTypeSelector< | ||
| T, | ||
| typename etl::enable_if< | ||
| etl::is_base_of<IClusterConnectionConfigurationSkeletonOnly, T>::value>::type> | ||
| { | ||
| /** The selected cluster connection type. */ | ||
| using type = ClusterConnectionNoTimeoutSkeletonOnly; | ||
| }; | ||
|
|
||
| /** | ||
| * Type selector specialization for bidirectional configurations. | ||
| * \tparam T the bidirectional configuration type | ||
| */ | ||
| template<typename T> | ||
| struct ClusterConnectionTypeSelector< | ||
| T, | ||
| typename etl::enable_if< | ||
| etl::is_base_of<IClusterConnectionConfigurationBidirectional, T>::value>::type> | ||
| { | ||
| /** The selected cluster connection type. */ | ||
| using type = ClusterConnectionNoTimeoutBidirectional; | ||
| }; | ||
|
|
||
| /** | ||
| * Type selector specialization for proxy-only configurations with timeout. | ||
| * \tparam T the proxy-only with timeout configuration type | ||
| */ | ||
| template<typename T> | ||
| struct ClusterConnectionTypeSelector< | ||
| T, | ||
| typename etl::enable_if< | ||
| etl::is_base_of<IClusterConnectionConfigurationProxyOnlyWithTimeout, T>::value>::type> | ||
| { | ||
| /** The selected cluster connection type. */ | ||
| using type = ClusterConnectionProxyOnlyWithTimeout; | ||
| }; | ||
|
|
||
| /** | ||
| * Type selector specialization for skeleton-only configurations with timeout. | ||
| * \tparam T the skeleton-only with timeout configuration type | ||
| */ | ||
| template<typename T> | ||
| struct ClusterConnectionTypeSelector< | ||
| T, | ||
| typename etl::enable_if< | ||
| etl::is_base_of<IClusterConnectionConfigurationSkeletonOnlyWithTimeout, T>::value>::type> | ||
| { | ||
| /** The selected cluster connection type. */ | ||
| using type = ClusterConnectionSkeletonOnlyWithTimeout; | ||
| }; | ||
|
|
||
| /** | ||
| * Type selector specialization for bidirectional configurations with timeout. | ||
| * \tparam T the bidirectional with timeout configuration type | ||
| */ | ||
| template<typename T> | ||
| struct ClusterConnectionTypeSelector< | ||
| T, | ||
| typename etl::enable_if< | ||
| etl::is_base_of<IClusterConnectionConfigurationBidirectionalWithTimeout, T>::value>::type> | ||
| { | ||
| /** The selected cluster connection type. */ | ||
| using type = ClusterConnectionBidirectionalWithTimeout; | ||
| }; | ||
|
|
||
| } // namespace core | ||
| } // namespace middleware |
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.