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/CanBusNative.cpp b/automotive/can/1.0/default/CanBusNative.cpp
index 88f9175..047b090 100644
--- a/automotive/can/1.0/default/CanBusNative.cpp
+++ b/automotive/can/1.0/default/CanBusNative.cpp
@@ -31,6 +31,11 @@
return ICanController::Result::BAD_ADDRESS;
}
+ if (mBaudrate == 0) {
+ // interface is already up and we just want to register it
+ return ICanController::Result::OK;
+ }
+
if (!netdevice::down(mIfname)) {
LOG(ERROR) << "Can't bring " << mIfname << " down (to configure it)";
return ICanController::Result::UNKNOWN_ERROR;
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() {
diff --git a/automotive/can/1.0/default/CanBusSlcan.h b/automotive/can/1.0/default/CanBusSlcan.h
index 3328a9f..2328a2c 100644
--- a/automotive/can/1.0/default/CanBusSlcan.h
+++ b/automotive/can/1.0/default/CanBusSlcan.h
@@ -32,6 +32,8 @@
virtual bool postDown() override;
private:
+ ICanController::Result updateIfaceName(base::unique_fd& uartFd);
+
const std::string mUartName;
const uint32_t kBitrate;
base::unique_fd mFd;