## Overview Module DAP Plugin provides comprehensive dynamic plugin management and extensibility functionality for the DAP SDK, enabling applications to load, manage, and execute plugins at runtime with advanced features. This module supports dynamic library loading, plugin lifecycle management, inter-plugin communication, secure plugin sandboxing, and sophisticated plugin orchestration for building highly modular and extensible distributed applications. **Based on:** `dap-sdk/plugin/include/dap_plugin.h`, `dap-sdk/plugin/src/dap_plugin.c` ## Document Structure - [[#Overview|Overview]] - [[#Module Structures|Module Structures]] - [[#dap_plugin_manager_t|dap_plugin_manager_t - Plugin Manager]] - [[#dap_plugin_t|dap_plugin_t - Plugin Instance]] - [[#dap_plugin_info_t|dap_plugin_info_t - Plugin Metadata]] - [[#dap_plugin_message_t|dap_plugin_message_t - Inter-Plugin Messages]] - [[#dap_plugin_config_t|dap_plugin_config_t - Plugin Configuration]] - [[#Module Functions|Module Functions]] - [[#Plugin Manager Functions|Manager Creation and Control]] - [[#Plugin Lifecycle Functions|Plugin Loading and Management]] - [[#Inter-Plugin Communication Functions|Message Passing and Events]] - [[#Configuration Functions|Plugin Configuration]] - [[#Error Codes|Error Codes]] - [[#Typical Examples|Typical Examples]] ## Module Structures ### dap_plugin_manager_t Core plugin manager structure for managing multiple plugins and their interactions. ```c typedef struct dap_plugin_manager { struct { char *plugin_directory; // Plugin search directory dap_plugin_config_t *config; // Manager configuration uint32_t plugins_count; // Number of loaded plugins bool is_initialized; // Manager initialization status dap_plugin_state_t state; // Manager operational state uint64_t plugins_loaded; // Total plugins loaded uint64_t plugins_failed; // Failed plugin loads } pub; struct { dap_htable_t *plugins_table; // Plugin hash table dap_list_t *plugins_list; // Plugins list dap_list_t *load_order; // Plugin loading order dap_htable_t *services_registry; // Services registry dap_plugin_deps_t *dependency_graph; // Dependency graph pthread_mutex_t manager_mutex; // Manager synchronization dap_events_t *event_system; // Event system integration void *security_context; // Security context } priv; } dap_plugin_manager_t; ``` **Public Fields:** - `plugin_directory` - Directory path for plugin discovery and loading - `config` - Configuration parameters for plugin management - `plugins_count` - Current number of successfully loaded plugins - `is_initialized` - Manager initialization and readiness status - `state` - Current operational state of the plugin manager - `plugins_loaded` - Total count of plugins loaded since initialization - `plugins_failed` - Count of failed plugin loading attempts ### dap_plugin_t Individual plugin instance structure managing plugin state and resources. ```c typedef struct dap_plugin { struct { char *name; // Plugin name identifier char *path; // Plugin file path dap_plugin_info_t *info; // Plugin metadata dap_plugin_state_t state; // Current plugin state bool is_running; // Plugin execution status dap_time_t loaded_time; // Plugin load timestamp dap_time_t started_time; // Plugin start timestamp uint64_t messages_sent; // Messages sent by plugin uint64_t messages_received; // Messages received by plugin } pub; struct { void *handle; // Dynamic library handle dap_plugin_api_t *api; // Plugin API interface dap_plugin_manager_t *manager; // Parent manager reference dap_list_t *dependencies; // Plugin dependencies dap_htable_t *services; // Provided services dap_htable_t *config_table; // Plugin configuration pthread_mutex_t plugin_mutex; // Plugin synchronization void *private_data; // Plugin private data uint64_t memory_usage; // Current memory usage bool sandbox_enabled; // Sandbox status } priv; } dap_plugin_t; ``` **Plugin State Management:** - `name` - Unique plugin identifier name - `path` - Full file system path to plugin library - `info` - Comprehensive plugin metadata and information - `state` - Current execution state (loaded, running, stopped, error) - `is_running` - Boolean flag indicating active execution - `loaded_time` - Timestamp when plugin was loaded - `started_time` - Timestamp when plugin execution started ### dap_plugin_info_t Plugin metadata and information structure. ```c typedef struct dap_plugin_info { struct { char *name; // Plugin name char *version; // Plugin version string char *description; // Plugin description char *author; // Plugin author char *license; // License information dap_plugin_type_t type; // Plugin type category uint32_t api_version; // Required API version bool is_core; // Core plugin flag } pub; struct { char **dependencies; // Required dependencies uint32_t dependencies_count; // Number of dependencies char **provides; // Services provided uint32_t provides_count; // Number of services dap_plugin_caps_t capabilities; // Plugin capabilities uint64_t min_memory; // Minimum memory requirement uint64_t max_memory; // Maximum memory limit bool requires_network; // Network access required } priv; } dap_plugin_info_t; ``` ### dap_plugin_message_t Inter-plugin message structure for communication. ```c typedef struct dap_plugin_message { struct { uint64_t message_id; // Unique message identifier char *from_plugin; // Source plugin name char *to_plugin; // Target plugin name dap_plugin_msg_type_t type; // Message type void *data; // Message data payload size_t data_size; // Size of message data dap_time_t timestamp; // Message timestamp uint32_t priority; // Message priority } pub; struct { dap_plugin_message_t *next; // Next message in queue dap_plugin_callback_t response_cb; // Response callback void *callback_context; // Callback context dap_time_t expires; // Message expiration uint32_t retry_count; // Retry attempts bool is_broadcast; // Broadcast message flag bool requires_response; // Response required flag } priv; } dap_plugin_message_t; ``` ### dap_plugin_config_t Plugin configuration structure for runtime settings. ```c typedef struct dap_plugin_config { struct { char *plugin_directory; // Plugin search directory uint32_t max_plugins; // Maximum plugins allowed uint32_t load_timeout_sec; // Plugin load timeout bool enable_sandbox; // Enable plugin sandboxing bool enable_hot_reload; // Enable hot reloading dap_plugin_security_level_t security_level; // Security level } pub; struct { uint64_t memory_limit_per_plugin; // Memory limit per plugin uint32_t max_message_queue_size; // Message queue size limit uint32_t message_timeout_sec; // Message timeout bool debug_mode; // Debug logging enabled char *log_directory; // Plugin log directory dap_plugin_isolation_t isolation_mode; // Isolation mode bool enable_profiling; // Performance profiling } priv; } dap_plugin_config_t; ``` ## Module Functions ### Plugin Manager Functions #### `dap_plugin_manager_init()` Initializes the plugin manager with specified directory and configuration. ```c dap_plugin_manager_t* dap_plugin_manager_init(const char *plugin_dir, const dap_plugin_config_t *config); ``` **Parameters:** - `plugin_dir` (const char*) - Directory path to search for plugins - `config` (const dap_plugin_config_t*) - Manager configuration parameters **Returns:** - `dap_plugin_manager_t*` - New plugin manager instance - `NULL` - Manager initialization failed **Error Conditions:** - Returns NULL if plugin_dir is NULL or doesn't exist - Returns NULL if config is NULL or invalid - Returns NULL if memory allocation fails - Returns NULL if directory access fails **Description:** Creates and initializes a new plugin manager instance with the specified plugin directory and configuration. Sets up internal data structures, creates plugin registry, and prepares manager for plugin loading operations. #### `dap_plugin_manager_shutdown()` Shuts down plugin manager and unloads all plugins. ```c int dap_plugin_manager_shutdown(dap_plugin_manager_t *manager); ``` **Parameters:** - `manager` (dap_plugin_manager_t*) - Plugin manager to shutdown **Returns:** - `0` - Shutdown completed successfully - `-1` - Invalid manager parameter - `-2` - Shutdown already in progress - `-3` - Plugin unloading failed #### `dap_plugin_manager_scan()` Scans plugin directory for available plugins. ```c int dap_plugin_manager_scan(dap_plugin_manager_t *manager); ``` **Parameters:** - `manager` (dap_plugin_manager_t*) - Plugin manager instance **Returns:** - `int` - Number of plugins found - `-1` - Invalid manager parameter - `-2` - Directory scan failed ### Plugin Lifecycle Functions #### `dap_plugin_load()` Loads plugin from specified file path. ```c dap_plugin_t* dap_plugin_load(dap_plugin_manager_t *manager, const char *plugin_path); ``` **Parameters:** - `manager` (dap_plugin_manager_t*) - Plugin manager instance - `plugin_path` (const char*) - Path to plugin library file **Returns:** - `dap_plugin_t*` - Loaded plugin instance - `NULL` - Plugin loading failed **Error Conditions:** - Returns NULL if manager is NULL - Returns NULL if plugin_path is NULL or invalid - Returns NULL if plugin file doesn't exist - Returns NULL if plugin loading fails - Returns NULL if dependency resolution fails #### `dap_plugin_start()` Starts plugin execution and activates its services. ```c int dap_plugin_start(dap_plugin_t *plugin); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance to start **Returns:** - `0` - Plugin started successfully - `-1` - Invalid plugin parameter - `-2` - Plugin already running - `-3` - Dependencies not satisfied - `-4` - Plugin initialization failed #### `dap_plugin_stop()` Stops plugin execution and deactivates services. ```c int dap_plugin_stop(dap_plugin_t *plugin); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance to stop **Returns:** - `0` - Plugin stopped successfully - `-1` - Invalid plugin parameter - `-2` - Plugin not running - `-3` - Plugin shutdown failed #### `dap_plugin_restart()` Restarts plugin by stopping and starting it. ```c int dap_plugin_restart(dap_plugin_t *plugin); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance to restart **Returns:** - `0` - Plugin restarted successfully - `-1` - Invalid plugin parameter - `-2` - Stop operation failed - `-3` - Start operation failed #### `dap_plugin_unload()` Unloads plugin and frees all associated resources. ```c void dap_plugin_unload(dap_plugin_t *plugin); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance to unload **Description:** Safely unloads plugin by stopping execution, cleaning up resources, and freeing memory. Handles dependency cleanup and service deregistration. ### Inter-Plugin Communication Functions #### `dap_plugin_send_message()` Sends message between plugins with delivery confirmation. ```c int dap_plugin_send_message(dap_plugin_t *from_plugin, const char *to_plugin, const dap_plugin_message_t *message); ``` **Parameters:** - `from_plugin` (dap_plugin_t*) - Source plugin instance - `to_plugin` (const char*) - Target plugin name - `message` (const dap_plugin_message_t*) - Message to send **Returns:** - `0` - Message sent successfully - `-1` - Invalid parameters - `-2` - Target plugin not found - `-3` - Message queue full - `-4` - Permission denied #### `dap_plugin_broadcast_message()` Broadcasts message to all loaded plugins. ```c int dap_plugin_broadcast_message(dap_plugin_t *from_plugin, const dap_plugin_message_t *message); ``` **Parameters:** - `from_plugin` (dap_plugin_t*) - Source plugin instance - `message` (const dap_plugin_message_t*) - Message to broadcast **Returns:** - `int` - Number of plugins that received the message - `-1` - Invalid parameters - `-2` - Broadcast failed #### `dap_plugin_register_service()` Registers plugin service for discovery by other plugins. ```c int dap_plugin_register_service(dap_plugin_t *plugin, const char *service_name, dap_plugin_service_callback_t callback); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin providing the service - `service_name` (const char*) - Name of service to register - `callback` (dap_plugin_service_callback_t) - Service callback function **Returns:** - `0` - Service registered successfully - `-1` - Invalid parameters - `-2` - Service name already exists - `-3` - Registration failed #### `dap_plugin_call_service()` Calls service provided by another plugin. ```c int dap_plugin_call_service(dap_plugin_t *plugin, const char *service_name, void *request, void **response); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin calling the service - `service_name` (const char*) - Name of service to call - `request` (void*) - Request data for service - `response` (void**) - Response data from service **Returns:** - `0` - Service call successful - `-1` - Invalid parameters - `-2` - Service not found - `-3` - Service call failed ### Configuration Functions #### `dap_plugin_config_set()` Sets plugin configuration parameter. ```c int dap_plugin_config_set(dap_plugin_t *plugin, const char *key, const void *value); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance - `key` (const char*) - Configuration parameter name - `value` (const void*) - Parameter value **Returns:** - `0` - Configuration set successfully - `-1` - Invalid parameters - `-2` - Unknown configuration key - `-3` - Invalid value for parameter #### `dap_plugin_config_get()` Gets plugin configuration parameter. ```c const void* dap_plugin_config_get(dap_plugin_t *plugin, const char *key); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance - `key` (const char*) - Configuration parameter name **Returns:** - `const void*` - Configuration parameter value - `NULL` - Parameter not found or invalid key #### `dap_plugin_get_info()` Retrieves plugin information and metadata. ```c const dap_plugin_info_t* dap_plugin_get_info(dap_plugin_t *plugin); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance **Returns:** - `const dap_plugin_info_t*` - Plugin information structure - `NULL` - Invalid plugin parameter #### `dap_plugin_get_stats()` Retrieves plugin performance statistics. ```c dap_plugin_stats_t* dap_plugin_get_stats(dap_plugin_t *plugin); ``` **Parameters:** - `plugin` (dap_plugin_t*) - Plugin instance **Returns:** - `dap_plugin_stats_t*` - Plugin statistics structure - `NULL` - Invalid plugin parameter or statistics unavailable ## Error Codes ### DAP Plugin Error Codes ```c typedef enum dap_plugin_error { DAP_PLUGIN_ERROR_SUCCESS = 0, // Operation successful DAP_PLUGIN_ERROR_INVALID_PARAM, // Invalid parameter provided DAP_PLUGIN_ERROR_NO_MEMORY, // Memory allocation failed DAP_PLUGIN_ERROR_FILE_NOT_FOUND, // Plugin file not found DAP_PLUGIN_ERROR_LOAD_FAILED, // Plugin loading failed DAP_PLUGIN_ERROR_SYMBOL_NOT_FOUND, // Required symbol not found DAP_PLUGIN_ERROR_VERSION_MISMATCH, // API version mismatch DAP_PLUGIN_ERROR_DEPENDENCY_MISSING, // Required dependency missing DAP_PLUGIN_ERROR_ALREADY_LOADED, // Plugin already loaded DAP_PLUGIN_ERROR_NOT_LOADED, // Plugin not loaded DAP_PLUGIN_ERROR_ALREADY_RUNNING, // Plugin already running DAP_PLUGIN_ERROR_NOT_RUNNING, // Plugin not running DAP_PLUGIN_ERROR_INIT_FAILED, // Plugin initialization failed DAP_PLUGIN_ERROR_SHUTDOWN_FAILED, // Plugin shutdown failed DAP_PLUGIN_ERROR_MESSAGE_FAILED, // Message sending failed DAP_PLUGIN_ERROR_SERVICE_EXISTS, // Service already registered DAP_PLUGIN_ERROR_SERVICE_NOT_FOUND, // Service not found DAP_PLUGIN_ERROR_PERMISSION_DENIED, // Permission denied DAP_PLUGIN_ERROR_SANDBOX_VIOLATION, // Sandbox security violation DAP_PLUGIN_ERROR_TIMEOUT, // Operation timed out DAP_PLUGIN_ERROR_QUEUE_FULL, // Message queue is full DAP_PLUGIN_ERROR_CONFIG_INVALID // Invalid configuration } dap_plugin_error_t; ``` ## Typical Examples ### Basic Plugin Manager Setup Example ```c #include "dap_common.h" #include "dap_plugin.h" void basic_plugin_manager_example() { log_it(L_INFO, "=== Basic DAP Plugin Manager Example ==="); // Step 1: Create plugin configuration dap_plugin_config_t config = { .pub.plugin_directory = "./plugins", .pub.max_plugins = 50, .pub.load_timeout_sec = 30, .pub.enable_sandbox = true, .pub.enable_hot_reload = false, .pub.security_level = DAP_PLUGIN_SECURITY_MEDIUM, .priv.memory_limit_per_plugin = 104857600, // 100MB per plugin .priv.max_message_queue_size = 1000, .priv.message_timeout_sec = 10, .priv.debug_mode = true, .priv.log_directory = "./logs/plugins", .priv.isolation_mode = DAP_PLUGIN_ISOLATION_PROCESS, .priv.enable_profiling = true }; // Step 2: Initialize plugin manager dap_plugin_manager_t *manager = dap_plugin_manager_init(config.pub.plugin_directory, &config); if (!manager) { log_it(L_ERROR, "✗ Failed to initialize plugin manager"); return; } log_it(L_INFO, "✓ Plugin manager initialized successfully"); log_it(L_INFO, " Plugin directory: %s", config.pub.plugin_directory); log_it(L_INFO, " Max plugins: %d", config.pub.max_plugins); log_it(L_INFO, " Sandbox enabled: %s", config.pub.enable_sandbox ? "Yes" : "No"); log_it(L_INFO, " Security level: %d", config.pub.security_level); // Step 3: Scan for available plugins int plugins_found = dap_plugin_manager_scan(manager); if (plugins_found < 0) { log_it(L_ERROR, "✗ Failed to scan plugin directory: %d", plugins_found); goto cleanup; } log_it(L_INFO, "✓ Plugin directory scan completed"); log_it(L_INFO, " Plugins found: %d", plugins_found); // Step 4: Load specific plugins const char *plugins_to_load[] = { "./plugins/example_service.so", "./plugins/data_processor.so", "./plugins/logger_plugin.so" }; const int num_plugins = sizeof(plugins_to_load) / sizeof(plugins_to_load[0]); dap_plugin_t *loaded_plugins[num_plugins]; int successfully_loaded = 0; for (int i = 0; i < num_plugins; i++) { loaded_plugins[i] = dap_plugin_load(manager, plugins_to_load[i]); if (loaded_plugins[i]) { log_it(L_INFO, "✓ Plugin loaded: %s", plugins_to_load[i]); // Get plugin information const dap_plugin_info_t *info = dap_plugin_get_info(loaded_plugins[i]); if (info) { log_it(L_INFO, " Name: %s", info->pub.name); log_it(L_INFO, " Version: %s", info->pub.version); log_it(L_INFO, " Description: %s", info->pub.description); log_it(L_INFO, " Author: %s", info->pub.author); log_it(L_INFO, " Type: %d", info->pub.type); log_it(L_INFO, " API Version: %d", info->pub.api_version); log_it(L_INFO, " Dependencies: %d", info->priv.dependencies_count); log_it(L_INFO, " Provides: %d services", info->priv.provides_count); } successfully_loaded++; } else { log_it(L_ERROR, "✗ Failed to load plugin: %s", plugins_to_load[i]); } } log_it(L_INFO, "Plugin loading summary: %d/%d successful", successfully_loaded, num_plugins); // Step 5: Start loaded plugins for (int i = 0; i < num_plugins; i++) { if (loaded_plugins[i]) { int result = dap_plugin_start(loaded_plugins[i]); switch (result) { case 0: log_it(L_INFO, "✓ Plugin started: %s", loaded_plugins[i]->pub.name); break; case -1: log_it(L_ERROR, "✗ Invalid plugin parameter"); break; case -2: log_it(L_WARNING, "Plugin already running: %s", loaded_plugins[i]->pub.name); break; case -3: log_it(L_ERROR, "✗ Dependencies not satisfied for: %s", loaded_plugins[i]->pub.name); break; case -4: log_it(L_ERROR, "✗ Plugin initialization failed: %s", loaded_plugins[i]->pub.name); break; default: log_it(L_ERROR, "✗ Unknown error starting plugin: %s (%d)", loaded_plugins[i]->pub.name, result); break; } } } // Step 6: Display manager statistics log_it(L_INFO, "Plugin Manager Statistics:"); log_it(L_INFO, " Total plugins loaded: %lu", manager->pub.plugins_loaded); log_it(L_INFO, " Failed plugin loads: %lu", manager->pub.plugins_failed); log_it(L_INFO, " Current plugins count: %d", manager->pub.plugins_count); log_it(L_INFO, " Manager state: %d", manager->pub.state); // Step 7: Demonstrate plugin operations (wait for activity) log_it(L_INFO, "Plugins running... (10 second demo)"); sleep(10); // Step 8: Stop all plugins for (int i = 0; i < num_plugins; i++) { if (loaded_plugins[i] && loaded_plugins[i]->pub.is_running) { int result = dap_plugin_stop(loaded_plugins[i]); if (result == 0) { log_it(L_INFO, "✓ Plugin stopped: %s", loaded_plugins[i]->pub.name); } else { log_it(L_ERROR, "✗ Failed to stop plugin: %s (%d)", loaded_plugins[i]->pub.name, result); } } } // Step 9: Unload all plugins for (int i = 0; i < num_plugins; i++) { if (loaded_plugins[i]) { dap_plugin_unload(loaded_plugins[i]); log_it(L_INFO, "✓ Plugin unloaded: %s", plugins_to_load[i]); } } log_it(L_INFO, "✓ Basic plugin manager example completed"); cleanup: // Step 10: Shutdown manager if (manager) { int result = dap_plugin_manager_shutdown(manager); if (result == 0) { log_it(L_INFO, "✓ Plugin manager shutdown successfully"); } else { log_it(L_ERROR, "✗ Plugin manager shutdown failed: %d", result); } } log_it(L_INFO, "Basic plugin manager example completed"); } ``` --- **See also:** [[Module DAP Core|Module DAP Core]], [[Module DAP IO|Module DAP IO]], [[Module DAP Server|Module DAP Server]] --- *Based on: `dap-sdk/plugin/include/dap_plugin.h`, `dap-sdk/plugin/src/dap_plugin.c`*