DE Comm Architecture: Plugin-Broker Interaction
Overview
The DroneEngage Communication (DE Comm) system consists of two main components that communicate via UDP:
Plugin Side - Uses the
de_commlibraryBroker Side - The
de_commbroker module
This document explains the architecture, communication flow, and key interactions between these components.
Architecture Components
Plugin Side (de_comm library)
Core Classes
CModule(de_module.hpp/cpp) - Main interface for pluginsCUDPClient(udpClient.hpp/cpp) - UDP communication layerCFacade_Base(de_facade_base.cpp) - High-level API wrapperCAndruavMessageParserBase(de_message_parser_base.cpp) - Message parsing
Key Features
Singleton pattern for
CModuleThread-safe UDP communication with chunking
Message routing based on destination and type
Periodic module identification broadcasts
Broker Side (de_comm broker module)
Core Classes
CUavosModulesManager(de_modules_manager.cpp) - Central module managerCUDPCommunicator(udpCommunicator.cpp) - UDP server for modulesCMessageBuffer(andruav_message_buffer.cpp) - Thread-safe message queue
Key Features
Module registry and lifecycle management
Message routing and forwarding
License validation
Camera device management
Thread-safe message processing
Communication Flow
1. Module Registration
The registration process establishes the connection between plugins and the broker:
Plugin (CModule) → UDP → Broker (CUavosModulesManager)
Steps:
Plugin Initialization
// Plugin calls CModule::defineModule(class, id, key, version, filter); CModule::init(targetIP, broadcastPort, host, listenPort, chunkSize);
ID Broadcast
// Plugin sends identification CModule::createJSONID(true); // Request reply
Broker Processing
Broker receives via
CUDPCommunicator::InternalReceiverEntry()Processes in
CUavosModulesManager::handleModuleRegistration()Maintains module registry in
m_modules_list
Broker Response
// Broker replies with its identification CUavosModulesManager::createJSONID(false);
2. Message Types & Routing
Inter-Module Messages
Routing Type:
CMD_TYPE_INTERMODULEPurpose: Communication between plugins only
Flow: Plugin → Broker → Other Plugins (not forwarded to external server)
Use Case: Plugin coordination, internal commands
System Messages
Routing Type:
CMD_COMM_SYSTEMPurpose: Plugin-to-Broker system commands
Flow: Plugin → Broker (handled internally)
Use Case: Configuration, status updates, system control
Group/Individual Messages
Routing Type:
CMD_COMM_GROUPorCMD_COMM_INDIVIDUALPurpose: Messages to be forwarded to external DroneEngage server
Flow: Plugin → Broker → External Server
Use Case: External communication, telemetry, commands
3. Message Structure
Module Identification Message
{
"ty": "uv", // Inter-module routing
"1": 9100, // TYPE_AndruavModule_ID
"ms": {
"a": "module_id", // Module identifier
"b": "module_class", // Module type (fcb, camera, etc.)
"c": [1005, 1041], // Subscribed message types
"d": ["T", "R"], // Module features
"e": "module_key", // Unique module key
"s": "hardware_serial", // Hardware identifier
"t": 1, // Hardware type
"z": true, // Resend request flag
"v": "1.0.0", // Module version
"i": 1234567890 // Instance timestamp
}
}
Standard Message
{
"ty": "uv", // Routing type
"0": "target_id", // Target module/group
"1": message_type, // Message type ID
"k": "module_key", // Sender module key
"ms": { // Message payload
// Message-specific data
}
}
Thread Architecture
Plugin Side Threads
Main Thread
Application logic
Message sending via
CModule::sendJMSG(),sendBMSG()
UDP Receiver Thread
CUDPClient::InternalReceiverEntry()
Receives UDP packets
Handles chunked message reassembly
Calls
onReceive()callback
ID Sender Thread
CUDPClient::InternelSenderIDEntry()
Periodic module identification broadcasts
1-second intervals
Ensures broker knows module is alive
Broker Side Threads
Main Thread
Module management
Message routing decisions
Status tracking
UDP Receiver Thread
CUDPCommunicator::InternalReceiverEntry()
Receives UDP packets from modules
Handles chunked message reassembly
Queues messages for processing
Consumer Thread
CUavosModulesManager::consumerThreadFunc()
Processes queued messages
Calls
parseIntermoduleMessage()Handles message routing and forwarding
Module Management
Module Registry
The broker maintains several data structures:
Active Modules
std::map<std::string, std::unique_ptr<MODULE_ITEM_TYPE>> m_modules_list;
Registry of connected plugins
Contains module metadata, socket addresses, status
Message Subscriptions
std::map<int, std::vector<std::string>> m_module_messages;
Maps message types to subscribing modules
Enables efficient message routing
Camera Registry
std::map<std::string, std::unique_ptr<std::map<std::string, std::unique_ptr<MODULE_CAMERA_ENTRY>>>> m_camera_list;
Special handling for camera modules
Tracks available camera devices
Module Classes
Supported module types:
MODULE_CLASS_FCB- Flight Control BoardMODULE_CLASS_VIDEO- Camera modulesMODULE_CLASS_P2P- Peer-to-Peer communicationMODULE_CLASS_GPIO- GPIO controlMODULE_CLASS_TRACKING- Object trackingMODULE_CLASS_A_RECOGNITION- AI recognitionMODULE_CLASS_SDR- Software Defined RadioMODULE_CLASS_SOUND- Audio processing
Module Features
Modules declare capabilities:
T- Transmit telemetryR- Receive telemetryC- Capture imagesV- Capture videoG- GPIO controlA- AI recognitionK- Object trackingP- P2P communication
UDP Communication
Chunking Protocol
Large messages are split into chunks for reliable UDP transmission:
Chunk Structure
[2 bytes: chunk number] [chunk data]
Chunk Numbers
0toN-1: Sequential chunks0xFFFF: Last chunk marker
Reassembly Process
Receive chunks with same source port
Store in order using chunk number
When
0xFFFFreceived, concatenate all chunksAdd null terminator for text messages
Pass to message processor
Error Handling
Comprehensive try-catch blocks throughout
Graceful degradation on communication failures
Module restart detection via timestamp comparison
Socket cleanup and thread termination
Security & Licensing
License Validation
void CUavosModulesManager::checkLicenseStatus(MODULE_ITEM_TYPE* module_item)
Process:
Check if authentication is available
Validate hardware serial and type
Set license status:
LICENSE_VERIFIED_OK- Module allowedLICENSE_VERIFIED_BAD- Module blockedLICENSE_NOT_VERIFIED- Authentication unavailable
Send error notification if invalid
Hardware Types
HARDWARE_TYPE_CPU- Standard CPU-based modulesHARDWARE_TYPE_UNDEFINED- Unspecified hardware
Message Processing
Plugin Side Processing
void CModule::onReceive(const char* message, int len)
Steps:
Parse JSON message
Validate required fields
Handle special messages:
TYPE_AndruavModule_ID- Module identificationTYPE_AndruavMessage_DUMMY- Test messages
Call user-defined callback for other messages
Broker Side Processing
void CUavosModulesManager::parseIntermoduleMessage(const char* full_message, const std::size_t full_message_length, const struct sockaddr_in* ssock)
Steps:
Parse JSON message
Determine message type and routing
Handle special message types via switch statement
Route based on message type:
Inter-module: Forward to other modules
System: Handle internally
Other: Forward to external server
Key Interactions
Module Discovery
Plugin broadcasts identification
Broker registers module
Broker replies with its identification
Plugin stores party_id and group_id
Message Routing
Plugin sends message with routing type
Broker determines destination based on routing
Broker forwards accordingly:
To other modules (inter-module)
To external server (group/individual)
Handles internally (system)
Health Monitoring
Modules send periodic ID broadcasts
Broker tracks last access time
Broker marks modules as dead if no updates
Broker updates system status based on alive modules
Configuration
Plugin Configuration
CModule::defineModule(
"module_class", // Module type
"module_id", // Module identifier
"unique_key", // Unique module key
"1.0.0", // Module version
[1001, 1002] // Subscribed message types
);
Network Configuration
CModule::init(
"127.0.0.1", // Target IP (broker)
60000, // Broker port
"0.0.0.0", // Local bind address
60001, // Local port
8192 // UDP chunk size
);
Best Practices
Plugin Development
Use singleton
CModule::getInstance()for communicationSet message callback via
setMessageOnReceive()Handle both JSON and binary messages appropriately
Implement proper error handling
Use appropriate routing types for different message categories
Broker Development
Use thread-safe data structures
Implement proper message validation
Handle module restarts gracefully
Monitor module health and update status
Use message buffering for high-throughput scenarios
Debugging
Logging
Both components use colored console output:
_INFO_CONSOLE_TEXT- Informational messages_SUCCESS_CONSOLE_TEXT- Success messages_ERROR_CONSOLE_TEXT- Error messages_LOG_CONSOLE_TEXT- Debug messages
Common Issues
UDP Port Conflicts - Ensure unique ports for each module
Message Size - Use chunking for large messages
Thread Safety - Use proper mutex protection
Network Connectivity - Verify broker is reachable
Module Registration - Check module key uniqueness
Conclusion
The DE Comm architecture provides a robust, scalable communication system enabling:
Plugin Coordination - Direct inter-module communication
External Integration - Forwarding to DroneEngage servers
System Management - Centralized module lifecycle management
Security - License validation and access control
Reliability - Chunked UDP, error handling, health monitoring
This design supports complex drone systems with multiple specialized modules communicating efficiently through a central broker.