From 38b29ddfc0f5cd0c6c928cec5d082476bba866e2 Mon Sep 17 00:00:00 2001 From: Hayodea Hakol Date: Sat, 6 Sep 2025 20:46:02 -0400 Subject: [PATCH] Comments and formatting --- commonLibs/livoxProto1/device.cpp | 51 +++++++++++++++++++++---------- commonLibs/livoxProto1/protocol.h | 5 ++- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/commonLibs/livoxProto1/device.cpp b/commonLibs/livoxProto1/device.cpp index 251732b..6d2d5a2 100644 --- a/commonLibs/livoxProto1/device.cpp +++ b/commonLibs/livoxProto1/device.cpp @@ -17,7 +17,6 @@ namespace livoxProto1 { namespace comms { -// DiscoveredDevice constructors DiscoveredDevice::DiscoveredDevice( const std::string &deviceIdentifier, DeviceType deviceType, @@ -65,7 +64,6 @@ std::string DiscoveredDevice::getDeviceTypeName(void) const } // namespace comms -// Device implementation Device::Device(const std::string &deviceIdentifier, const std::shared_ptr& componentThread, int handshakeTimeoutMs, int retryDelayMs, @@ -86,7 +84,6 @@ heartbeatActive(false) Device::~Device() { - // Stop heartbeat if active if (heartbeatActive.load()) { heartbeatActive.store(false); if (heartbeatTimer) { @@ -94,7 +91,6 @@ Device::~Device() } } - // Clean up heartbeat resources heartbeatTimer.reset(); heartbeatSocket.reset(); } @@ -199,7 +195,12 @@ bool Device::executeHandshake( ) { 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::ip::udp::socket socket(io_context); socket.open(boost::asio::ip::udp::v4()); @@ -328,7 +329,15 @@ std::string Device::generateClientDeviceIpFromSerialNumber( 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()) { throw std::invalid_argument( @@ -383,7 +392,6 @@ std::string Device::generateClientDeviceIpFromSerialNumber( // Generate subnet mask based on nbits uint32_t subnetMask = getSubnetMaskFor(smoSubnetNbits); - // Convert smoIp to uint32_t for bitwise operations uint32_t smoIpAddr = (std::stoi(smoIpOctets->octet1) << 24) | (std::stoi(smoIpOctets->octet2) << 16) | (std::stoi(smoIpOctets->octet3) << 8) | @@ -408,7 +416,10 @@ void Device::startHeartbeat() 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( componentThread->getIoService()); heartbeatSocket->open(boost::asio::ip::udp::v4()); @@ -432,7 +443,6 @@ void Device::sendHeartbeat() } try { - // Create heartbeat message using the new HeartbeatMessage type comms::HeartbeatMessage heartbeatMsg; heartbeatMsg.swapContentsToProtocolEndianness(); @@ -440,15 +450,18 @@ void Device::sendHeartbeat() heartbeatMsg.header.swapCrc16ToProtocolEndianness(); heartbeatMsg.footer.crc_32 = heartbeatMsg.calculateCrc32(); heartbeatMsg.footer.swapCrc32ToProtocolEndianness(); - // Send the heartbeat packet + 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( boost::asio::buffer(&heartbeatMsg, sizeof(heartbeatMsg)), 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->async_wait( [this](const boost::system::error_code& error) { @@ -543,7 +556,10 @@ std::optional Device::detectSmoIp(const std::string& deviceIP) 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) { if (ifa->ifa_addr == nullptr) continue; @@ -580,7 +596,7 @@ std::optional Device::detectSmoIp(const std::string& deviceIP) if ((ipAddr & subnetMask) == (deviceIpAddr & subnetMask)) { found_ip = ip; - break; // Exit loop, let unique_ptr handle cleanup + break; } } @@ -598,7 +614,11 @@ std::optional Device::detectSmoIp(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()) { return smoIp; } @@ -608,7 +628,6 @@ std::string Device::getSmoIp(const std::string& deviceIP) return detectedIp.value(); } - // If detection failed, throw an exception throw std::runtime_error( std::string(__func__) + ": Failed to detect SMO IP address for device " + deviceIP + " with subnet mask /" + std::to_string(smoSubnetNbits)); diff --git a/commonLibs/livoxProto1/protocol.h b/commonLibs/livoxProto1/protocol.h index 0e9ea73..75e0c61 100644 --- a/commonLibs/livoxProto1/protocol.h +++ b/commonLibs/livoxProto1/protocol.h @@ -13,7 +13,10 @@ namespace livoxProto1 { 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 uint32_t LIVOX_CRC32_SEED = 0x564f580a;