Comments and formatting

This commit is contained in:
2025-09-06 20:46:02 -04:00
parent d2bf5aceee
commit 38b29ddfc0
2 changed files with 39 additions and 17 deletions
+35 -16
View File
@@ -17,7 +17,6 @@
namespace livoxProto1 { namespace livoxProto1 {
namespace comms { namespace comms {
// DiscoveredDevice constructors
DiscoveredDevice::DiscoveredDevice( DiscoveredDevice::DiscoveredDevice(
const std::string &deviceIdentifier, const std::string &deviceIdentifier,
DeviceType deviceType, DeviceType deviceType,
@@ -65,7 +64,6 @@ std::string DiscoveredDevice::getDeviceTypeName(void) const
} // namespace comms } // namespace comms
// Device implementation
Device::Device(const std::string &deviceIdentifier, Device::Device(const std::string &deviceIdentifier,
const std::shared_ptr<smo::ComponentThread>& componentThread, const std::shared_ptr<smo::ComponentThread>& componentThread,
int handshakeTimeoutMs, int retryDelayMs, int handshakeTimeoutMs, int retryDelayMs,
@@ -86,7 +84,6 @@ heartbeatActive(false)
Device::~Device() Device::~Device()
{ {
// Stop heartbeat if active
if (heartbeatActive.load()) { if (heartbeatActive.load()) {
heartbeatActive.store(false); heartbeatActive.store(false);
if (heartbeatTimer) { if (heartbeatTimer) {
@@ -94,7 +91,6 @@ Device::~Device()
} }
} }
// Clean up heartbeat resources
heartbeatTimer.reset(); heartbeatTimer.reset();
heartbeatSocket.reset(); heartbeatSocket.reset();
} }
@@ -199,7 +195,12 @@ bool Device::executeHandshake(
) )
{ {
try { try {
// Create boost::asio UDP socket /** EXPLANATION:
* This io_context queue here will allow us to async-bridge the
* handshake request and response without having to worry about
* re-enqueueing messages, as we would have to do if we used the
* io_context of a ComponentThread.
*/
boost::asio::io_context io_context; boost::asio::io_context io_context;
boost::asio::ip::udp::socket socket(io_context); boost::asio::ip::udp::socket socket(io_context);
socket.open(boost::asio::ip::udp::v4()); socket.open(boost::asio::ip::udp::v4());
@@ -328,7 +329,15 @@ std::string Device::generateClientDeviceIpFromSerialNumber(
const std::string& broadcastCode const std::string& broadcastCode
) )
{ {
// Determine if input is serial number (14 chars) or broadcast code (15 chars) /** EXPLANATION:
* The input string is either a serial number (14 chars) or a broadcast code
* (15 chars). We need to determine which one it is and extract the serial
* number from the broadcast code.
*
* To generate a default IP address, we use the device's subnet: X.X.X.1XX
* where XX = last two digits of serial. We use the smoIp and smoSubnetNbits
* to determine the network prefix.
*/
if (broadcastCode.empty()) if (broadcastCode.empty())
{ {
throw std::invalid_argument( throw std::invalid_argument(
@@ -383,7 +392,6 @@ std::string Device::generateClientDeviceIpFromSerialNumber(
// Generate subnet mask based on nbits // Generate subnet mask based on nbits
uint32_t subnetMask = getSubnetMaskFor(smoSubnetNbits); uint32_t subnetMask = getSubnetMaskFor(smoSubnetNbits);
// Convert smoIp to uint32_t for bitwise operations
uint32_t smoIpAddr = (std::stoi(smoIpOctets->octet1) << 24) | uint32_t smoIpAddr = (std::stoi(smoIpOctets->octet1) << 24) |
(std::stoi(smoIpOctets->octet2) << 16) | (std::stoi(smoIpOctets->octet2) << 16) |
(std::stoi(smoIpOctets->octet3) << 8) | (std::stoi(smoIpOctets->octet3) << 8) |
@@ -408,7 +416,10 @@ void Device::startHeartbeat()
return; // Can't start heartbeat without component thread or IP return; // Can't start heartbeat without component thread or IP
} }
// Create heartbeat socket using the component thread's io_service /** EXPLANATION:
* Create heartbeat socket using io_service of the componentThread that was
* given to us for use by this device.
*/
heartbeatSocket = std::make_unique<boost::asio::ip::udp::socket>( heartbeatSocket = std::make_unique<boost::asio::ip::udp::socket>(
componentThread->getIoService()); componentThread->getIoService());
heartbeatSocket->open(boost::asio::ip::udp::v4()); heartbeatSocket->open(boost::asio::ip::udp::v4());
@@ -432,7 +443,6 @@ void Device::sendHeartbeat()
} }
try { try {
// Create heartbeat message using the new HeartbeatMessage type
comms::HeartbeatMessage heartbeatMsg; comms::HeartbeatMessage heartbeatMsg;
heartbeatMsg.swapContentsToProtocolEndianness(); heartbeatMsg.swapContentsToProtocolEndianness();
@@ -440,15 +450,18 @@ void Device::sendHeartbeat()
heartbeatMsg.header.swapCrc16ToProtocolEndianness(); heartbeatMsg.header.swapCrc16ToProtocolEndianness();
heartbeatMsg.footer.crc_32 = heartbeatMsg.calculateCrc32(); heartbeatMsg.footer.crc_32 = heartbeatMsg.calculateCrc32();
heartbeatMsg.footer.swapCrc32ToProtocolEndianness(); heartbeatMsg.footer.swapCrc32ToProtocolEndianness();
// Send the heartbeat packet
boost::asio::ip::udp::endpoint deviceEndpoint( boost::asio::ip::udp::endpoint deviceEndpoint(
boost::asio::ip::address::from_string(discoveredDevice.ipAddr), cmdPort); boost::asio::ip::address::from_string(discoveredDevice.ipAddr),
cmdPort);
heartbeatSocket->send_to( heartbeatSocket->send_to(
boost::asio::buffer(&heartbeatMsg, sizeof(heartbeatMsg)), boost::asio::buffer(&heartbeatMsg, sizeof(heartbeatMsg)),
deviceEndpoint); deviceEndpoint);
// Schedule next heartbeat in 1 second /** EXPLANATION:
* Schedule next heartbeat in 1 second, per the spec.
*/
heartbeatTimer->expires_from_now(boost::posix_time::seconds(1)); heartbeatTimer->expires_from_now(boost::posix_time::seconds(1));
heartbeatTimer->async_wait( heartbeatTimer->async_wait(
[this](const boost::system::error_code& error) { [this](const boost::system::error_code& error) {
@@ -543,7 +556,10 @@ std::optional<std::string> Device::detectSmoIp(const std::string& deviceIP)
std::string found_ip; std::string found_ip;
// Iterate through all network interfaces /** EXPLANATION:
* Iterate through all network interfaces and check if the IP address is
* in the same subnet as the device's IP address.
*/
for (struct ifaddrs *ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) for (struct ifaddrs *ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
{ {
if (ifa->ifa_addr == nullptr) continue; if (ifa->ifa_addr == nullptr) continue;
@@ -580,7 +596,7 @@ std::optional<std::string> Device::detectSmoIp(const std::string& deviceIP)
if ((ipAddr & subnetMask) == (deviceIpAddr & subnetMask)) if ((ipAddr & subnetMask) == (deviceIpAddr & subnetMask))
{ {
found_ip = ip; found_ip = ip;
break; // Exit loop, let unique_ptr handle cleanup break;
} }
} }
@@ -598,7 +614,11 @@ std::optional<std::string> Device::detectSmoIp(const std::string& deviceIP)
std::string Device::getSmoIp(const std::string& deviceIP) std::string Device::getSmoIp(const std::string& deviceIP)
{ {
// If smo-ip was provided, return it /** EXPLANATION:
* If smo-ip was provided, return it.
* Otherwise, try to detect it based on the client device's IP address.
* If detection failed, throw an exception.
*/
if (!smoIp.empty()) { if (!smoIp.empty()) {
return smoIp; return smoIp;
} }
@@ -608,7 +628,6 @@ std::string Device::getSmoIp(const std::string& deviceIP)
return detectedIp.value(); return detectedIp.value();
} }
// If detection failed, throw an exception
throw std::runtime_error( throw std::runtime_error(
std::string(__func__) + ": Failed to detect SMO IP address for device " std::string(__func__) + ": Failed to detect SMO IP address for device "
+ deviceIP + " with subnet mask /" + std::to_string(smoSubnetNbits)); + deviceIP + " with subnet mask /" + std::to_string(smoSubnetNbits));
+4 -1
View File
@@ -13,7 +13,10 @@
namespace livoxProto1 { namespace livoxProto1 {
namespace comms { namespace comms {
// Livox SDK CRC constants /** EXPLANATION:
* Undocumented Livox SDK CRC seed constants. These were found in the Livox SDK
* source code.
*/
constexpr uint16_t LIVOX_CRC16_SEED = 0x4c49; constexpr uint16_t LIVOX_CRC16_SEED = 0x4c49;
constexpr uint32_t LIVOX_CRC32_SEED = 0x564f580a; constexpr uint32_t LIVOX_CRC32_SEED = 0x564f580a;