livoxProto1: Open pcloudDataSocket in UdpCmdDemux
The pcloudData socket is now opened by UdpCommandDemuxer, when libLivoxProto1 is initialized. We can now just pick up the socket and be certain it'll be there if the lib is being executed.
This commit is contained in:
@@ -18,10 +18,11 @@ namespace comms {
|
||||
UdpCommandDemuxer::UdpCommandDemuxer(
|
||||
const std::shared_ptr<smo::ComponentThread> &componentThread,
|
||||
DeviceManager &deviceManager,
|
||||
uint16_t commandPort
|
||||
uint16_t commandPort,
|
||||
uint16_t dataPort
|
||||
)
|
||||
: componentThread(componentThread), deviceManager(deviceManager),
|
||||
commandPort(commandPort),
|
||||
commandPort(commandPort), dataPort(dataPort),
|
||||
senderAddrLen(sizeof(senderAddr))
|
||||
{
|
||||
}
|
||||
@@ -42,7 +43,7 @@ void UdpCommandDemuxer::start()
|
||||
|
||||
try
|
||||
{
|
||||
setupSocket();
|
||||
setupSockets();
|
||||
isActive.store(true);
|
||||
shouldStop.store(false);
|
||||
|
||||
@@ -77,13 +78,25 @@ void UdpCommandDemuxer::stop()
|
||||
cmdEndpointFdDesc.reset();
|
||||
}
|
||||
|
||||
if (pcloudDataSocketDesc)
|
||||
{
|
||||
pcloudDataSocketDesc->cancel();
|
||||
pcloudDataSocketDesc.reset();
|
||||
}
|
||||
|
||||
isActive.store(false);
|
||||
std::cout
|
||||
<< __func__ << ": UDP Command Demuxer stopped"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void UdpCommandDemuxer::setupSocket()
|
||||
void UdpCommandDemuxer::setupSockets()
|
||||
{
|
||||
setupCommandSocket();
|
||||
setupPcloudDataSocket();
|
||||
}
|
||||
|
||||
void UdpCommandDemuxer::setupCommandSocket()
|
||||
{
|
||||
// RAII class to manage socket file descriptor
|
||||
struct SocketRAII
|
||||
@@ -139,6 +152,62 @@ void UdpCommandDemuxer::setupSocket()
|
||||
socketGuard.commit();
|
||||
}
|
||||
|
||||
void UdpCommandDemuxer::setupPcloudDataSocket()
|
||||
{
|
||||
// RAII class to manage socket file descriptor
|
||||
struct SocketRAII
|
||||
{
|
||||
int fd;
|
||||
SocketRAII(int socketFd) : fd(socketFd) {}
|
||||
~SocketRAII() { if (fd >= 0) close(fd); }
|
||||
void commit() { fd = -1; } // Transfer 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())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__)
|
||||
+ ": Failed to create socket: " + strerror(errno));
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__)
|
||||
+ ": Failed to set non-blocking mode: " + strerror(errno));
|
||||
}
|
||||
|
||||
// Bind to the data port
|
||||
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(dataPort);
|
||||
|
||||
if (bind(
|
||||
socketGuard.getFd(), (struct sockaddr *)&localAddr,
|
||||
sizeof(localAddr)) < 0)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__) + ": Failed to bind to data port: "
|
||||
+ std::to_string(dataPort) + ": " + strerror(errno));
|
||||
}
|
||||
|
||||
// Create boost wrapper for async operations
|
||||
pcloudDataSocketDesc = std::make_shared<boost::asio::posix::stream_descriptor>(
|
||||
componentThread->getIoService(), socketGuard.getFd());
|
||||
|
||||
// Transfer ownership, prevent auto-close
|
||||
socketGuard.commit();
|
||||
}
|
||||
|
||||
void UdpCommandDemuxer::startAsyncReceive()
|
||||
{
|
||||
if (!isActive.load() || shouldStop.load())
|
||||
|
||||
Reference in New Issue
Block a user