LivoxProto1: Document UDP demuxer purpose & use cases
Also fix bug in transient resource transfer from continuation to Device object.
This commit is contained in:
@@ -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<boost::asio::posix::stream_descriptor>(
|
||||
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
|
||||
|
||||
|
||||
@@ -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<void(
|
||||
const uint8_t* data, ssize_t bytesReceived,
|
||||
const struct sockaddr_in& senderAddr)> handler;
|
||||
};
|
||||
static std::unordered_map<std::string, std::vector<CommandHandler>>
|
||||
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<uint8_t, uint8_t>,
|
||||
std::function<void(
|
||||
const uint8_t* data, ssize_t bytesReceived,
|
||||
const struct sockaddr_in& senderAddr)>> 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<void(
|
||||
const uint8_t* data, ssize_t bytesReceived,
|
||||
const struct sockaddr_in& senderAddr)> handler;
|
||||
};
|
||||
static std::unordered_map<std::string, std::vector<CommandHandler>>
|
||||
devicesUnderConstruction;
|
||||
};
|
||||
|
||||
} // namespace livoxProto1
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user