diff --git a/commonLibs/livoxProto1/device.cpp b/commonLibs/livoxProto1/device.cpp index 21dea57..54b627e 100644 --- a/commonLibs/livoxProto1/device.cpp +++ b/commonLibs/livoxProto1/device.cpp @@ -1714,13 +1714,13 @@ private: // Transfer ownership of the socket from temporary to main descriptor if (tmpPcloudEnableFdDesc.is_open()) { + // Close the temporary descriptor (but don't close the fd) int fd = tmpPcloudEnableFdDesc.native_handle(); + tmpPcloudEnableFdDesc.release(); + // Give the transient FD to the Device object. device.pcloudDataSocketDesc = std::make_unique( device.componentThread->getIoService(), fd); - - // Close the temporary descriptor (but don't close the fd) - tmpPcloudEnableFdDesc.release(); } device.pcloudDataActive.store(true); } @@ -1888,6 +1888,14 @@ void Device::registerUdpCommandHandler( const std::string& deviceIP ) { + /** EXPLANATION: + * Register a UDP command handler for the given cmd_set and cmd_id. + * If the handler already exists for the given device IP, replace it. + * If the handler does not exist, add it to the temporary collection. + * + * Adding a handler to a cmd_set+cmd_id pair which already has a handler + * results in the new handler replacing the old one. + */ auto key = std::make_pair(cmd_set, cmd_id); udpCommandHandlers[key] = handler; // Don't move, we need to copy diff --git a/commonLibs/livoxProto1/device.h b/commonLibs/livoxProto1/device.h index c3adeb4..48c876f 100644 --- a/commonLibs/livoxProto1/device.h +++ b/commonLibs/livoxProto1/device.h @@ -90,18 +90,6 @@ public: uint8_t smoSubnetNbits; uint16_t dataPort, cmdPort, imuPort; - // Static collection for devices being constructed (not yet in DeviceManager) - // Maps device IP to list of command-specific UDP handlers for that device - struct CommandHandler { - uint8_t cmd_set; - uint8_t cmd_id; - std::function handler; - }; - static std::unordered_map> - devicesUnderConstruction; - private: // Heartbeat mechanism void startHeartbeat(); @@ -182,12 +170,47 @@ private: // Point cloud data setup void cleanupPcloudDataSocket(); + /** EXPLANATION: + * This is the "straightforward" map of command set and command id to + * handlers. This is useful for any commands which are guaranteed to be + * issued to the device *AFTER* the device has successfully been added + * to the DeviceManager's list of devices. + * + * I.e: it cannot be used for commands which are issued to the device before + * getOrCreateDevice() has added the device to the DeviceManager's list of + * devices. + */ // Command handler map std::unordered_map< std::pair, std::function> udpCommandHandlers; + +public: + /** EXPLANATION: + * This is the "temporary" map of command set and command id to + * handlers. This is useful for any commands which are issued to the device + * while it is being constructed. + * + * I.e: it shouldn't be used for cmds which are issued to the device after + * getOrCreateDevice() has added the device to the DeviceManager's list of + * devices. It will work for such commands, but we'd kind of prefer to use + * the "straightforward" map above for such commands. + * + * NOTE: + * There's a strong argument to be made for just getting rid of the + * "straightforward" map above and just using this one, tho. + */ + struct CommandHandler { + uint8_t cmd_set; + uint8_t cmd_id; + std::function handler; + }; + static std::unordered_map> + devicesUnderConstruction; }; } // namespace livoxProto1 diff --git a/commonLibs/livoxProto1/udpCommandDemuxer.h b/commonLibs/livoxProto1/udpCommandDemuxer.h index 7da218c..078f407 100644 --- a/commonLibs/livoxProto1/udpCommandDemuxer.h +++ b/commonLibs/livoxProto1/udpCommandDemuxer.h @@ -20,6 +20,17 @@ namespace comms { * This class listens on the command port (65000) for incoming UDP datagrams * from Livox devices and routes them to the appropriate Device based on * the source IP address. + * + * The reason we need a whole class for this is because we use the same port + * numbers for all connected devices, so we have no way to distinguish between + * devices except based on the devices' IP addrs. Since all commands are sent + * over UDP, our sockets don't have built-in binding to a specific source IP. + * + * So we need to discriminate between source IPs manually, and demultiplex + * the dgrams received from different devices manually. + * + * We'll prolly also have to do the same thing for point cloud and IMU data, so + * we'll prolly end up renaming this class to UdpResponseDemuxer. */ class UdpCommandDemuxer {