diff --git a/commonLibs/livoxProto1/device.cpp b/commonLibs/livoxProto1/device.cpp index 2412286..251732b 100644 --- a/commonLibs/livoxProto1/device.cpp +++ b/commonLibs/livoxProto1/device.cpp @@ -204,7 +204,9 @@ bool Device::executeHandshake( boost::asio::ip::udp::socket socket(io_context); socket.open(boost::asio::ip::udp::v4()); - std::string smoIp = getSmoIp(); + // Get the IP addr of the SMO machine's iface that is facing the device. + std::string smoIp = getSmoIp(deviceIP); + comms::HandshakeRequest handshakeReq(smoIp, dataPort, cmdPort, imuPort); handshakeReq.swapContentsToProtocolEndianness(); handshakeReq.header.setCrc16FromRawBytes(); @@ -501,33 +503,40 @@ uint32_t Device::getSubnetMaskFor(uint8_t nbits) } } -std::optional Device::detectSmoIp() +std::optional Device::detectSmoIp(const std::string& deviceIP) { + /** EXPLANATION: + * This function detects the SMO IP address of the interface that's facing + * the device by iterating through all network interfaces and checking for + * the interface that has the IP address in the same subnet as the device's + * IP address. + */ try { - // Parse the smoIp to get the network prefix - auto smoIpOctets = comms::parseIPv4Address(smoIp); - if (!smoIpOctets.has_value()) { + // Parse the device IP to get the network prefix + auto deviceIpOctets = comms::parseIPv4Address(deviceIP); + if (!deviceIpOctets.has_value()) { return std::nullopt; } - // Convert smoIp octets to integers for bitwise operations - uint32_t smoIpAddr = (std::stoi(smoIpOctets->octet1) << 24) | - (std::stoi(smoIpOctets->octet2) << 16) | - (std::stoi(smoIpOctets->octet3) << 8) | - std::stoi(smoIpOctets->octet4); + // Convert device IP octets to integers for bitwise operations + uint32_t deviceIpAddr = (std::stoi(deviceIpOctets->octet1) << 24) | + (std::stoi(deviceIpOctets->octet2) << 16) | + (std::stoi(deviceIpOctets->octet3) << 8) | + std::stoi(deviceIpOctets->octet4); // Generate subnet mask based on nbits uint32_t subnetMask = getSubnetMaskFor(smoSubnetNbits); - // Get all network interfaces using getifaddrs (Linux/Unix specific) - // TODO: Add Windows support using GetAdaptersAddresses when porting + /* Get all network interfaces using getifaddrs (Linux/Unix specific) + * + * FIXME: Add Windows support using GetAdaptersAddresses when porting + */ struct ifaddrs *ifaddr; if (getifaddrs(&ifaddr) == -1) { return std::nullopt; } - // Use unique_ptr for automatic cleanup (RAII) - // This ensures freeifaddrs is called even if we break out of the loop or throw an exception + // Use unique_ptr for automatic cleanup (RAII) to free ifaddrs auto ifaddr_deleter = [](struct ifaddrs* ptr) { freeifaddrs(ptr); }; std::unique_ptr ifaddr_ptr( ifaddr, ifaddr_deleter); @@ -564,9 +573,12 @@ std::optional Device::detectSmoIp() (std::stoi(ipOctets->octet3) << 8) | std::stoi(ipOctets->octet4); - // Check if IP matches the subnet using the calculated mask - // Only compare the bits that are set in the subnet mask - if ((ipAddr & subnetMask) == (smoIpAddr & subnetMask)) { + /* Check if this iface's IP is in the same subnet as the device's IP + * using the calculated mask. Only compare the bits that are set in + * the subnet mask. + */ + if ((ipAddr & subnetMask) == (deviceIpAddr & subnetMask)) + { found_ip = ip; break; // Exit loop, let unique_ptr handle cleanup } @@ -584,23 +596,22 @@ std::optional Device::detectSmoIp() } } -std::string Device::getSmoIp() +std::string Device::getSmoIp(const std::string& deviceIP) { // If smo-ip was provided, return it if (!smoIp.empty()) { return smoIp; } - // Otherwise, try to detect it - auto detectedIp = detectSmoIp(); + auto detectedIp = detectSmoIp(deviceIP); if (detectedIp.has_value()) { return detectedIp.value(); } // If detection failed, throw an exception throw std::runtime_error( - std::string(__func__) + ": Failed to detect SMO IP address for smoIp " - + smoIp + " with subnet mask /" + std::to_string(smoSubnetNbits)); + std::string(__func__) + ": Failed to detect SMO IP address for device " + + deviceIP + " with subnet mask /" + std::to_string(smoSubnetNbits)); } } // namespace livoxProto1 diff --git a/commonLibs/livoxProto1/device.h b/commonLibs/livoxProto1/device.h index 02ed376..694aaae 100644 --- a/commonLibs/livoxProto1/device.h +++ b/commonLibs/livoxProto1/device.h @@ -83,8 +83,8 @@ private: const std::string& broadcastCode); // IP detection methods - std::optional detectSmoIp(); - std::string getSmoIp(); + std::optional detectSmoIp(const std::string& deviceIP); + std::string getSmoIp(const std::string& deviceIP); uint32_t getSubnetMaskFor(uint8_t nbits); // Heartbeat mechanism