LivoxProto1: Pcloud socket is set up transiently in contin
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -180,7 +180,6 @@ public:
|
||||
|
||||
private:
|
||||
// Point cloud data setup
|
||||
bool setupPcloudDataSocket();
|
||||
void cleanupPcloudDataSocket();
|
||||
|
||||
// Command handler map
|
||||
|
||||
Reference in New Issue
Block a user