LivoxProto1: port to sscl::co framework

Code now actually looks a lot cleaner, tbh.
This commit is contained in:
2026-05-28 20:13:12 -04:00
parent bbc16dc4c4
commit 25efccf6c5
20 changed files with 1275 additions and 2145 deletions
+89 -6
View File
@@ -3,10 +3,16 @@
#include <boostAsioLinkageFix.h>
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <unordered_map>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <componentThread.h>
#include <spinscale/spinLock.h>
#include <spinscale/sharedResourceGroup.h>
#include <spinscale/co/invokers.h>
namespace livoxProto1 {
@@ -15,6 +21,45 @@ class DeviceManager;
namespace comms {
struct UdpCommandResponseResult
{
enum class Outcome
{
Timeout,
Response,
RecvError
};
Outcome outcome = Outcome::Timeout;
uint8_t buffer[1024]{};
ssize_t bytesReceived = -1;
};
struct CommandWaitKey
{
std::string deviceIp;
uint8_t cmdSet;
uint8_t cmdId;
bool operator==(const CommandWaitKey &other) const
{
return deviceIp == other.deviceIp
&& cmdSet == other.cmdSet
&& cmdId == other.cmdId;
}
};
struct CommandWaitKeyHash
{
std::size_t operator()(const CommandWaitKey &key) const
{
std::size_t hash = std::hash<std::string>{}(key.deviceIp);
hash ^= (static_cast<std::size_t>(key.cmdSet) << 8)
| static_cast<std::size_t>(key.cmdId);
return hash;
}
};
/**
* UdpCommandDemuxer - Routes UDP command datagrams to appropriate devices
*
@@ -62,13 +107,20 @@ public:
return pcloudDataFdDesc;
}
private:
// Socket and async objects
std::shared_ptr<boost::asio::posix::stream_descriptor> pcloudDataFdDesc;
// Socket and async objects
std::shared_ptr<boost::asio::posix::stream_descriptor> cmdEndpointFdDesc;
sscl::co::ViralNonPostingInvoker<UdpCommandResponseResult>
waitForCommandResponseCReq(
uint8_t cmdSet, uint8_t cmdId,
const std::string &deviceIp,
int timeoutMs);
private:
struct PendingCommandWaitDesc;
sscl::co::ViralNonPostingInvoker<UdpCommandResponseResult>
waitForCommandResponseCReq(
uint8_t cmdSet, uint8_t cmdId,
const std::string &deviceIp);
void setupSockets();
void setupCommandSocket();
void setupPcloudDataSocket();
@@ -76,6 +128,23 @@ private:
void onDataReady(const boost::system::error_code& error);
void processIncomingData();
bool tryCompletePendingCommandWait(
const char *sourceIp,
uint8_t cmdSet, uint8_t cmdId,
const uint8_t *data, ssize_t bytesReceived);
void cancelPendingCommandWait(
uint8_t cmdSet, uint8_t cmdId,
const std::string &deviceIp);
std::shared_ptr<PendingCommandWaitDesc> findAndRemovePendingCommandWait(
const CommandWaitKey &key);
void settlePendingCommandWait(
const std::shared_ptr<PendingCommandWaitDesc> &wait,
UdpCommandResponseResult::Outcome outcome,
const uint8_t *data, ssize_t bytesReceived);
std::shared_ptr<sscl::ComponentThread> componentThread;
DeviceManager& deviceManager;
uint16_t commandPort;
@@ -86,7 +155,21 @@ private:
std::atomic<bool> isActive{false};
std::atomic<bool> shouldStop{false};
// Receive buffer
struct PendingWaitsResources
{
std::unordered_map<
CommandWaitKey,
std::shared_ptr<PendingCommandWaitDesc>,
CommandWaitKeyHash>
pendingWaits;
};
sscl::SharedResourceGroup<sscl::SpinLock, PendingWaitsResources>
pendingWaits;
std::shared_ptr<boost::asio::posix::stream_descriptor> pcloudDataFdDesc;
std::shared_ptr<boost::asio::posix::stream_descriptor> cmdEndpointFdDesc;
uint8_t receiveBuffer[1024];
struct sockaddr_in senderAddr;
socklen_t senderAddrLen;