Summary
Gateway plugins can create entities via IntrospectionProvider, but those entities cannot serve standard SOVD resource collections (/data, /operations). Requests to plugin-created entities hit the built-in ROS 2 handlers (DataAccessManager, OperationManager) instead of being routed to the plugin.
This means plugins that represent non-ROS 2 subsystems (industrial PLCs, ECUs, external services) can appear in the entity tree but cannot respond to standard SOVD data/operation queries on their entities.
Proposed solution
Add two new provider interfaces following the established pattern (LogProvider, ScriptProvider):
- DataProvider -
list_data(), read_data(), write_data() per entity
- OperationProvider -
list_operations(), execute_operation() per entity
Unlike existing singleton providers, these use per-entity routing: PluginManager tracks entity ownership (entity_id -> plugin) from IntrospectionProvider results. Data and operation handlers check ownership before calling ROS 2 managers - if plugin-owned, delegate to the provider; otherwise use existing ROS 2 path.
Additional changes:
- IntrospectionProvider works in all discovery modes (not just hybrid) - plugin entities injected during cache refresh
- PluginLayer sets
source = "plugin" on all entities it creates
- EntityInfo gets
is_plugin / plugin_name fields for handler routing
- Capabilities auto-deduction - entity detail response auto-includes
data/operations when providers are registered
- Plugins export
get_data_provider() and get_operation_provider() via dlsym (same pattern as existing providers)
Additional context
This is a prerequisite for any plugin that needs to serve standard SOVD endpoints on its entities rather than using vendor-prefixed routes. Future providers (FaultProvider, ConfigurationProvider, BulkDataProvider, CyclicSubscriptionProvider) can follow the same pattern in a separate PR.
Summary
Gateway plugins can create entities via
IntrospectionProvider, but those entities cannot serve standard SOVD resource collections (/data,/operations). Requests to plugin-created entities hit the built-in ROS 2 handlers (DataAccessManager, OperationManager) instead of being routed to the plugin.This means plugins that represent non-ROS 2 subsystems (industrial PLCs, ECUs, external services) can appear in the entity tree but cannot respond to standard SOVD data/operation queries on their entities.
Proposed solution
Add two new provider interfaces following the established pattern (LogProvider, ScriptProvider):
list_data(),read_data(),write_data()per entitylist_operations(),execute_operation()per entityUnlike existing singleton providers, these use per-entity routing: PluginManager tracks entity ownership (entity_id -> plugin) from IntrospectionProvider results. Data and operation handlers check ownership before calling ROS 2 managers - if plugin-owned, delegate to the provider; otherwise use existing ROS 2 path.
Additional changes:
source = "plugin"on all entities it createsis_plugin/plugin_namefields for handler routingdata/operationswhen providers are registeredget_data_provider()andget_operation_provider()via dlsym (same pattern as existing providers)Additional context
This is a prerequisite for any plugin that needs to serve standard SOVD endpoints on its entities rather than using vendor-prefixed routes. Future providers (FaultProvider, ConfigurationProvider, BulkDataProvider, CyclicSubscriptionProvider) can follow the same pattern in a separate PR.