nvmesensor: clean up extraction and checks

Refine the I2C extraction process in NVMeSensorMain.cpp to handle
mi_mctp devices correctly.

Extract protocol first, and only extract Bus/Address directly for
mi_basic and mi_i2c. For mi_mctp, extract Bus and Address from BusInfo
if the BusType is "I2C".

Remove redundant isI2cAccessible variable and check, as they are
covered by earlier strict checks.

Add I2C support to extractBusInfo in MctpUtil.cpp.

Google-Bug-Id: 490106522
Change-Id: Iaf53e6933899f3a38657bd8c45fd7abdf472951e
Signed-off-by: Hao Jiang <jianghao@google.com>
diff --git a/src/MctpUtil.cpp b/src/MctpUtil.cpp
index f82b32e..7530c97 100644
--- a/src/MctpUtil.cpp
+++ b/src/MctpUtil.cpp
@@ -529,6 +529,13 @@
 
                 busInfo["BusType"] = busType;
             }
+            else if (busType == "I2C")
+            {
+                extractProp(props, busInfo, "Bus");
+                extractProp(props, busInfo, "Address");
+
+                busInfo["BusType"] = busType;
+            }
             else if (!busType.empty())
             {
                 lg2::warning("Unsupported BusType {TYPE}", "TYPE", busType);
diff --git a/src/NVMeSensorMain.cpp b/src/NVMeSensorMain.cpp
index 76a584c..90bb362 100644
--- a/src/NVMeSensorMain.cpp
+++ b/src/NVMeSensorMain.cpp
@@ -219,14 +219,61 @@
         }
 
         const SensorBaseConfigMap& sensorConfig = sensorBase->second;
-        std::optional<int> busNumber = extractBusNumber(nvmeObjectPath,
-                                                        sensorConfig);
-        std::optional<int> address = extractAddress(nvmeObjectPath,
-                                                    sensorConfig);
-        std::optional<std::string> sensorName = extractName(nvmeObjectPath,
-                                                            sensorConfig);
         std::optional<std::string> nvmeProtocol =
             extractProtocol(nvmeObjectPath, sensorConfig);
+        if (!nvmeProtocol)
+        {
+            nvmeProtocol.emplace("mi_basic");
+        }
+
+        std::optional<int> busNumber;
+        std::optional<int> address;
+        BusInfo busInfo;
+
+        if (*nvmeProtocol == "mi_basic" || *nvmeProtocol == "mi_i2c")
+        {
+            busNumber = extractBusNumber(nvmeObjectPath, sensorConfig);
+            address = extractAddress(nvmeObjectPath, sensorConfig);
+            if (!busNumber)
+            {
+                continue;
+            }
+        }
+        else if (*nvmeProtocol == "mi_mctp")
+        {
+            busInfo = extractBusInfo(configData);
+            if (busInfo.empty())
+            {
+                lg2::error("Missing BusInfo for mi_mctp device {PATH}", "PATH",
+                           nvmeObjectPath.str);
+                continue;
+            }
+
+            auto itType = busInfo.find("BusType");
+            if (itType != busInfo.end() && itType->second == "I2C")
+            {
+                auto itBus = busInfo.find("Bus");
+                if (itBus != busInfo.end())
+                {
+                    busNumber = std::stoi(itBus->second);
+                }
+                auto itAddr = busInfo.find("Address");
+                if (itAddr != busInfo.end())
+                {
+                    address = std::stoi(itAddr->second, nullptr, 0);
+                }
+
+                if (!busNumber)
+                {
+                    lg2::error("Missing Bus in BusInfo for {PATH}", "PATH",
+                               nvmeObjectPath.str);
+                    continue;
+                }
+            }
+        }
+
+        std::optional<std::string> sensorName = extractName(nvmeObjectPath,
+                                                            sensorConfig);
         std::optional<std::string> mctpReactorConfigPath =
             extractMctpReactorConfigPath(sensorConfig);
 
@@ -238,23 +285,8 @@
             continue;
         }
 
-        const bool isMctpReactorDevice = mctpReactorConfigPath.has_value();
-
-        // Some NVMe devices are accessible over I2C because they're connected
-        // over SMBus directly to the BMC. In other cases, they might be
-        // connected to the BMC through a bridge (such as
-        // MCTP USB <-> I2C bridge).
-        const bool isI2cAccessible = busNumber.has_value();
-
-        // If a device is not an mctpreactor device, it must be accessible over
-        // I2C directly.
-        if (!isMctpReactorDevice && !isI2cAccessible)
-        {
-            lg2::info("Found an mctpd device that isn't I2C accessible,"
-                      "but it must be: {PATH}",
-                      "PATH", nvmeObjectPath.str);
-            continue;
-        }
+        const bool isMctpReactorDevice = mctpReactorConfigPath.has_value() ||
+                                         *nvmeProtocol == "mi_mctp";
 
         if (busNumber && bannedBuses.contains(*busNumber))
         {
@@ -262,21 +294,6 @@
             continue;
         }
 
-        // the default protocol is mi_basic
-        if (!nvmeProtocol)
-        {
-            nvmeProtocol.emplace("mi_basic");
-        }
-
-        // Support for non-I2C-accessible devices doesn't exist for mi_basic
-        // protocol because we don't need it for now.
-        if (*nvmeProtocol == "mi_basic" && !isI2cAccessible)
-        {
-            lg2::info("Skipping an mi_basic device that's not accessible "
-                      "over i2c bus.");
-            continue;
-        }
-
         if (*nvmeProtocol == "mi_basic")
         {
             // defualt i2c basic port is 0x6a
@@ -325,7 +342,7 @@
             PowerState powerState = getPowerState(sensorConfig);
 
             std::shared_ptr<NVMeMiWorker> worker;
-            if (singleWorkerFeature && isI2cAccessible)
+            if (singleWorkerFeature && busNumber.has_value())
             {
                 auto root = deriveRootBus(*busNumber);
 
@@ -355,15 +372,6 @@
                 std::shared_ptr<MctpDevice> mctpDev;
                 if (*nvmeProtocol == "mi_mctp")
                 {
-                    BusInfo busInfo;
-                    busInfo = extractBusInfo(configData);
-                    if (busInfo.empty())
-                    {
-                        lg2::error("Missing BusInfo for mi_mctp device {PATH}",
-                                   "PATH", nvmeObjectPath.str);
-                        continue;
-                    }
-
                     std::string endpointPath;
                     for (const auto& [epPath, epConfig] : mctpEndpointConfigMap)
                     {