diff --git a/commonLibs/livoxProto1/core.cpp b/commonLibs/livoxProto1/core.cpp index beceb57..fa058f6 100644 --- a/commonLibs/livoxProto1/core.cpp +++ b/commonLibs/livoxProto1/core.cpp @@ -257,6 +257,7 @@ void main(const std::shared_ptr &componentThread, protoState.smoCallbacks = smoCallbacks; protoState.deviceManager = std::make_unique(); protoState.deviceManager->broadcastListener.start(); + protoState.deviceManager->udpCommandDemuxer.start(); } void exit(void) @@ -265,10 +266,11 @@ void exit(void) return; } + protoState.deviceManager->udpCommandDemuxer.stop(); protoState.deviceManager->broadcastListener.stop(); protoState.deviceManager.reset(); protoState.componentThread.reset(); protoState.isInitialized = false; } -} // namespace livoxProto1 \ No newline at end of file +} // namespace livoxProto1 diff --git a/commonLibs/livoxProto1/device.cpp b/commonLibs/livoxProto1/device.cpp index abd2f99..4c19ba7 100644 --- a/commonLibs/livoxProto1/device.cpp +++ b/commonLibs/livoxProto1/device.cpp @@ -1743,11 +1743,11 @@ void Device::cleanupPcloudDataSocket() pcloudDataActive.store(false); } -void Device::handleUdpDgram(const uint8_t *data, ssize_t bytesReceived, - const struct sockaddr_in &senderAddr) +void Device::handleUdpDgram( + const uint8_t *data, ssize_t bytesReceived, + const struct sockaddr_in &senderAddr + ) { - (void)senderAddr; - // Check minimum size for any valid protocol message if (bytesReceived < static_cast( sizeof(comms::Header) + sizeof(comms::Command))) @@ -1760,37 +1760,44 @@ void Device::handleUdpDgram(const uint8_t *data, ssize_t bytesReceived, uint8_t cmd_set = data[sizeof(comms::Header)]; uint8_t cmd_id = data[sizeof(comms::Header) + 1]; - // Route based on command type - if (cmd_set == 0x00 && cmd_id == 0x01) + // Look for a registered handler for this command + auto key = std::make_pair(cmd_set, cmd_id); + auto it = udpCommandHandlers.find(key); + + if (it != udpCommandHandlers.end()) { - // Handshake ACK - check if we have enough data for HandshakeResponse - if (bytesReceived >= static_cast( - sizeof(comms::HandshakeResponse))) + // Found a registered handler, invoke it + try { - std::cout << __func__ << ": Received handshake ACK from " - << discoveredDevice.deviceIdentifier << std::endl; + it->second(data, bytesReceived, senderAddr); } - } - else if (cmd_set == 0x00 && cmd_id == 0x03) - { - // Heartbeat ACK - check if we have enough data for HeartbeatMessage - if (bytesReceived >= static_cast( - sizeof(comms::HeartbeatMessage))) + catch (const std::exception& e) { - // Empty intentionally. - } - } - else if (cmd_set == 0x00 && cmd_id == 0x04) - { - // Sampling response - check if we have enough data for SamplingResponse - if (bytesReceived >= static_cast( - sizeof(comms::SamplingResponse))) - { - std::cout << __func__ << ": Received sampling response from " - << discoveredDevice.deviceIdentifier << std::endl; + std::cerr << __func__ << ": Exception in command handler for " + << discoveredDevice.deviceIdentifier + << " cmd_set=" << (int)cmd_set + << " cmd_id=" << (int)cmd_id + << ": " << e.what() << std::endl; } } // Unknown command types are silently ignored } +void Device::registerUdpCommandHandler( + uint8_t cmd_set, uint8_t cmd_id, + std::function handler + ) +{ + auto key = std::make_pair(cmd_set, cmd_id); + udpCommandHandlers[key] = std::move(handler); +} + +void Device::unregisterUdpCommandHandler(uint8_t cmd_set, uint8_t cmd_id) +{ + auto key = std::make_pair(cmd_set, cmd_id); + udpCommandHandlers.erase(key); +} + } // namespace livoxProto1 diff --git a/commonLibs/livoxProto1/device.h b/commonLibs/livoxProto1/device.h index e88f1ed..7a3223d 100644 --- a/commonLibs/livoxProto1/device.h +++ b/commonLibs/livoxProto1/device.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,16 @@ #include "protocol.h" #include +// Custom hash function for std::pair +namespace std { + template<> + struct hash> { + size_t operator()(const std::pair& p) const noexcept { + return (static_cast(p.first) << 8) | static_cast(p.second); + } + }; +} + // Forward declaration namespace smo { class ComponentThread; @@ -146,10 +157,25 @@ public: const uint8_t* data, ssize_t bytesReceived, const struct sockaddr_in& senderAddr); + // Command handler registration + void registerUdpCommandHandler( + uint8_t cmd_set, uint8_t cmd_id, + std::function handler); + void unregisterUdpCommandHandler(uint8_t cmd_set, uint8_t cmd_id); + private: // Point cloud data setup bool setupPcloudDataSocket(); void cleanupPcloudDataSocket(); + + // Command handler map + std::unordered_map< + std::pair, + std::function> udpCommandHandlers; }; } // namespace livoxProto1