Add support for registering existing interfaces

This adds support for native and slcan interfaces which are already
configured up to be registered in the CAN bus HAL.

Bug: 142655647
Test: manual
Change-Id: Ifd129db14dbf473bb627ebc9b9d13f5cb945b611
diff --git a/automotive/can/1.0/default/CanBusSlcan.cpp b/automotive/can/1.0/default/CanBusSlcan.cpp
index 29d9d3c..e42005b 100644
--- a/automotive/can/1.0/default/CanBusSlcan.cpp
+++ b/automotive/can/1.0/default/CanBusSlcan.cpp
@@ -47,13 +47,34 @@
 CanBusSlcan::CanBusSlcan(const std::string& uartName, uint32_t bitrate)
     : CanBus(), mUartName(uartName), kBitrate(bitrate) {}
 
+/** helper function to update CanBusSlcan object's iface name */
+ICanController::Result CanBusSlcan::updateIfaceName(base::unique_fd& uartFd) {
+    struct ifreq ifrequest = {};
+    /*
+     * Fetching the iface name with an ioctl won't interfere with an open socketCAN iface attached
+     * to this tty. This is important in the event we are trying to register a SLCAN based iface
+     * that has already been configured and brought up.
+     */
+    if (ioctl(uartFd.get(), SIOCGIFNAME, ifrequest.ifr_name) < 0) {
+        LOG(ERROR) << "Failed to get the name of the created device: " << strerror(errno);
+        return ICanController::Result::UNKNOWN_ERROR;
+    }
+
+    // Update the CanBus object with name that was assigned to it
+    mIfname = ifrequest.ifr_name;
+    return ICanController::Result::OK;
+}
+
 ICanController::Result CanBusSlcan::preUp() {
     // verify valid bitrate and translate to serial command format
-    const auto lookupIt = slcanprotocol::kBitrateCommands.find(kBitrate);
-    if (lookupIt == slcanprotocol::kBitrateCommands.end()) {
-        return ICanController::Result::BAD_BAUDRATE;
+    std::optional<std::string> canBitrateCommand = std::nullopt;
+    if (kBitrate != 0) {
+        const auto lookupIt = slcanprotocol::kBitrateCommands.find(kBitrate);
+        if (lookupIt == slcanprotocol::kBitrateCommands.end()) {
+            return ICanController::Result::BAD_BAUDRATE;
+        }
+        canBitrateCommand = lookupIt->second;
     }
-    const auto canBitrateCommand = lookupIt->second;
 
     /* Attempt to open the uart in r/w without blocking or becoming the
      * controlling terminal */
@@ -63,6 +84,11 @@
         return ICanController::Result::BAD_ADDRESS;
     }
 
+    // If the device is already up, update the iface name in our CanBusSlcan object
+    if (kBitrate == 0) {
+        return updateIfaceName(mFd);
+    }
+
     // blank terminal settings and pull them from the device
     struct termios terminalSettings = {};
     if (tcgetattr(mFd.get(), &terminalSettings) < 0) {
@@ -102,7 +128,7 @@
     }
 
     // apply speed setting for CAN
-    if (write(mFd.get(), canBitrateCommand.c_str(), canBitrateCommand.length()) <= 0) {
+    if (write(mFd.get(), canBitrateCommand->c_str(), canBitrateCommand->length()) <= 0) {
         LOG(ERROR) << "Failed to apply CAN bitrate: " << strerror(errno);
         return ICanController::Result::UNKNOWN_ERROR;
     }
@@ -120,17 +146,8 @@
         return ICanController::Result::UNKNOWN_ERROR;
     }
 
-    // get the name of the device we created
-    struct ifreq ifrequest = {};
-    if (ioctl(mFd.get(), SIOCGIFNAME, ifrequest.ifr_name) < 0) {
-        LOG(ERROR) << "Failed to get the name of the created device: " << strerror(errno);
-        return ICanController::Result::UNKNOWN_ERROR;
-    }
-
     // Update the CanBus object with name that was assigned to it
-    mIfname = ifrequest.ifr_name;
-
-    return ICanController::Result::OK;
+    return updateIfaceName(mFd);
 }
 
 bool CanBusSlcan::postDown() {