LivoxProto1: Pcloud socket is set up transiently in contin

This commit is contained in:
2025-10-24 02:05:32 -04:00
parent 4bfcdf37da
commit bd0118531f
2 changed files with 80 additions and 63 deletions
+80 -62
View File
@@ -1370,6 +1370,9 @@ public:
// The timeout timer.
boost::asio::deadline_timer timeoutTimer;
// Temporary point cloud data socket descriptor (for enable operations)
boost::asio::posix::stream_descriptor tmpPcloudEnableFdDesc;
// Received data storage
uint8_t responseBuffer[1024]{};
ssize_t bytesReceived = -1;
@@ -1382,7 +1385,8 @@ protected:
smo::Callback<CallbackType> cb)
: smo::NonPostedAsynchronousContinuation<CallbackType>(std::move(cb)),
device(dev),
timeoutTimer(device.componentThread->getIoService())
timeoutTimer(device.componentThread->getIoService()),
tmpPcloudEnableFdDesc(device.componentThread->getIoService())
{}
public:
@@ -1556,6 +1560,10 @@ protected:
void cleanup()
{
timeoutTimer.cancel();
if (tmpPcloudEnableFdDesc.is_open()) {
tmpPcloudEnableFdDesc.cancel();
tmpPcloudEnableFdDesc.close();
}
}
// Pure virtual methods that derived classes must implement
@@ -1563,6 +1571,61 @@ protected:
virtual const char* getCommandName() const = 0;
virtual void setPcloudDataActiveState() = 0;
// Method to set up temporary point cloud data socket
bool setupTmpPcloudDataSocket()
{
// RAII class to manage socket file descriptor
struct SocketRAII
{
int fd;
SocketRAII(int socketFd) : fd(socketFd) {}
~SocketRAII() { if (fd >= 0) close(fd); }
void release() { fd = -1; } // Release ownership, prevent close
int getFd() const { return fd; }
bool isValid() const { return fd >= 0; }
};
// Create UDP socket for point cloud data reception
SocketRAII socketGuard(socket(AF_INET, SOCK_DGRAM, 0));
if (!socketGuard.isValid())
{
std::cerr << __func__ << ": Failed to create socket: "
<< strerror(errno) << std::endl;
return false;
}
// Set socket to non-blocking mode
int flags = fcntl(socketGuard.getFd(), F_GETFL, 0);
if (flags < 0 ||
fcntl(socketGuard.getFd(), F_SETFL, flags | O_NONBLOCK) < 0)
{
std::cerr << __func__ << ": Failed to set non-blocking mode: "
<< strerror(errno) << std::endl;
return false;
}
// Bind to the data port (65001)
struct sockaddr_in localAddr;
memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(65001); // Data port
if (bind(
socketGuard.getFd(), (struct sockaddr *)&localAddr,
sizeof(localAddr)) < 0)
{
std::cerr << __func__ << ": Failed to bind to data port: "
<< strerror(errno) << std::endl;
return false;
}
// Assign the file descriptor to the stream descriptor
tmpPcloudEnableFdDesc.assign(socketGuard.getFd());
socketGuard.release();
return true;
}
// Common sendCommand implementation
bool sendCommand()
{
@@ -1648,6 +1711,17 @@ private:
void setPcloudDataActiveState() override
{
// Transfer ownership of the socket from temporary to main descriptor
if (tmpPcloudEnableFdDesc.is_open())
{
int fd = tmpPcloudEnableFdDesc.native_handle();
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);
}
};
@@ -1662,7 +1736,8 @@ public:
DisablePcloudDataReq(
Device& dev,
smo::Callback<Device::disablePcloudDataReqCbFn> cb)
: EnDisablePcloudDataReq<Device::disablePcloudDataReqCbFn>(dev, std::move(cb))
: EnDisablePcloudDataReq<Device::disablePcloudDataReqCbFn>(
dev, std::move(cb))
{}
~DisablePcloudDataReq()
@@ -1703,10 +1778,10 @@ void Device::enablePcloudDataReq(
return;
}
// Set up the point cloud data socket for actual data reception
if (!setupPcloudDataSocket())
// Set up the temporary point cloud data socket for actual data reception
if (!request->setupTmpPcloudDataSocket())
{
std::cerr << __func__ << ": Failed to set up point cloud data socket"
std::cerr << __func__ << ": Failed to set up transient pcloud data FD."
<< std::endl;
request->callOriginalCallbackWithFailure();
return;
@@ -1756,63 +1831,6 @@ void Device::disablePcloudDataReq(
request->setupAsyncCallbacks(request);
}
bool Device::setupPcloudDataSocket()
{
// RAII class to manage socket file descriptor
struct SocketRAII
{
int fd;
SocketRAII(int socketFd) : fd(socketFd) {}
~SocketRAII() { if (fd >= 0) close(fd); }
void release() { fd = -1; } // Release ownership, prevent close
int getFd() const { return fd; }
bool isValid() const { return fd >= 0; }
};
// Create UDP socket for point cloud data reception
SocketRAII socketGuard(socket(AF_INET, SOCK_DGRAM, 0));
if (!socketGuard.isValid())
{
std::cerr << __func__ << ": Failed to create socket: "
<< strerror(errno) << std::endl;
return false;
}
// Set socket to non-blocking mode
int flags = fcntl(socketGuard.getFd(), F_GETFL, 0);
if (flags < 0 ||
fcntl(socketGuard.getFd(), F_SETFL, flags | O_NONBLOCK) < 0)
{
std::cerr << __func__ << ": Failed to set non-blocking mode: "
<< strerror(errno) << std::endl;
return false;
}
// Bind to the data port (65001)
struct sockaddr_in localAddr;
memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(65001); // Data port
if (bind(
socketGuard.getFd(), (struct sockaddr *)&localAddr,
sizeof(localAddr)) < 0)
{
std::cerr << __func__ << ": Failed to bind to data port: "
<< strerror(errno) << std::endl;
return false;
}
// Create boost wrapper for async operations
pcloudDataSocketDesc =
std::make_unique<boost::asio::posix::stream_descriptor>(
componentThread->getIoService(), socketGuard.getFd());
socketGuard.release();
return true;
}
void Device::cleanupPcloudDataSocket()
{
if (pcloudDataSocketDesc) {
-1
View File
@@ -180,7 +180,6 @@ public:
private:
// Point cloud data setup
bool setupPcloudDataSocket();
void cleanupPcloudDataSocket();
// Command handler map