LivoxProto1: ExecuteHandshake uses udpCommandDemuxer

UdpCommandDemuxer also now supports devices "under construction".
This commit is contained in:
2025-10-22 22:13:38 -04:00
parent 01ad1ff073
commit a4d99e5d4d
4 changed files with 231 additions and 170 deletions
+43 -10
View File
@@ -10,6 +10,7 @@
#include "udpCommandDemuxer.h"
#include "core.h"
#include "device.h"
namespace livoxProto1 {
namespace comms {
@@ -80,10 +81,10 @@ void UdpCommandDemuxer::stop()
timer.cancel();
// Close socket and cleanup
if (socketDesc)
if (cmdEndpointFdDesc)
{
socketDesc->cancel();
socketDesc.reset();
cmdEndpointFdDesc->cancel();
cmdEndpointFdDesc.reset();
}
isActive.store(false);
@@ -141,7 +142,7 @@ void UdpCommandDemuxer::setupSocket()
}
// Create boost wrapper for async operations
socketDesc =std::make_unique<boost::asio::posix::stream_descriptor>(
cmdEndpointFdDesc = std::make_shared<boost::asio::posix::stream_descriptor>(
componentThread->getIoService(), socketGuard.getFd());
// Transfer ownership, prevent auto-close
@@ -153,7 +154,7 @@ void UdpCommandDemuxer::startAsyncReceive()
if (!isActive.load() || shouldStop.load())
{ return; }
socketDesc->async_wait(
cmdEndpointFdDesc->async_wait(
boost::asio::posix::stream_descriptor::wait_read,
std::bind(
&UdpCommandDemuxer::onDataReady, this, std::placeholders::_1));
@@ -177,7 +178,7 @@ void UdpCommandDemuxer::onDataReady(const boost::system::error_code &error)
// Read the data
bytesReceived = recvfrom(
socketDesc->native_handle(), receiveBuffer,
cmdEndpointFdDesc->native_handle(), receiveBuffer,
sizeof(receiveBuffer), 0,
(struct sockaddr *)&senderAddr, &senderAddrLen);
@@ -205,8 +206,8 @@ void UdpCommandDemuxer::onTimerTick(const boost::system::error_code &error)
if (shouldStop.load())
{
// Stop was called, cancel async operations and stop timer
if (socketDesc) {
socketDesc->cancel();
if (cmdEndpointFdDesc) {
cmdEndpointFdDesc->cancel();
}
timer.cancel();
return;
@@ -234,7 +235,7 @@ void UdpCommandDemuxer::processIncomingData()
char sourceIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &senderAddr.sin_addr, sourceIP, INET_ADDRSTRLEN);
// Find device with matching IP address
// First, find device with matching IP address in DeviceManager collection
for (const auto &device : deviceManager.devices)
{
if (device->discoveredDevice.ipAddr != sourceIP) { continue; }
@@ -254,7 +255,39 @@ void UdpCommandDemuxer::processIncomingData()
return;
}
// No device found with matching IP, discard the data
// If not found in DeviceManager, check temporary collection (devices under construction)
auto tempIt = livoxProto1::Device::devicesUnderConstruction.find(sourceIP);
if (tempIt != livoxProto1::Device::devicesUnderConstruction.end())
{
// Extract command set and command ID from the datagram
if (bytesReceived >= static_cast<ssize_t>(
sizeof(livoxProto1::comms::Header) + sizeof(livoxProto1::comms::Command)))
{
uint8_t cmd_set = receiveBuffer[sizeof(livoxProto1::comms::Header)];
uint8_t cmd_id = receiveBuffer[sizeof(livoxProto1::comms::Header) + 1];
// Found matching device in temporary collection, invoke matching handlers
for (const auto& cmdHandler : tempIt->second)
{
if (cmdHandler.cmd_set == cmd_set && cmdHandler.cmd_id == cmd_id)
{
try
{
cmdHandler.handler(receiveBuffer, bytesReceived, senderAddr);
}
catch (const std::exception &e)
{
std::cerr
<< __func__ << ": Temporary device handler exception for IP "
<< sourceIP << ": " << e.what() << std::endl;
}
}
}
}
return;
}
// No device found with matching IP in either collection, discard the data
std::cerr
<< __func__ << ": No device found for source IP "
<< sourceIP << ", discarding datagram" << std::endl;