From 39187dbbffcec942107b28fa1f7214ca04ff2d5c Mon Sep 17 00:00:00 2001 From: chrisweir Date: Mon, 6 Jan 2020 15:21:07 -0800 Subject: [PATCH] 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 --- automotive/can/1.0/default/CanBusNative.cpp | 5 +++ automotive/can/1.0/default/CanBusSlcan.cpp | 47 ++++++++++++++------- automotive/can/1.0/default/CanBusSlcan.h | 2 + 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/automotive/can/1.0/default/CanBusNative.cpp b/automotive/can/1.0/default/CanBusNative.cpp index 88f9175f8b..047b09091b 100644 --- a/automotive/can/1.0/default/CanBusNative.cpp +++ b/automotive/can/1.0/default/CanBusNative.cpp @@ -31,6 +31,11 @@ ICanController::Result CanBusNative::preUp() { 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 29d9d3c238..e42005b6db 100644 --- a/automotive/can/1.0/default/CanBusSlcan.cpp +++ b/automotive/can/1.0/default/CanBusSlcan.cpp @@ -47,13 +47,34 @@ static const std::map kBitrateCommands = { 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 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 @@ ICanController::Result CanBusSlcan::preUp() { 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 @@ ICanController::Result CanBusSlcan::preUp() { } // 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 @@ ICanController::Result CanBusSlcan::preUp() { 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 3328a9f4ca..2328a2c65d 100644 --- a/automotive/can/1.0/default/CanBusSlcan.h +++ b/automotive/can/1.0/default/CanBusSlcan.h @@ -32,6 +32,8 @@ struct CanBusSlcan : public CanBus { virtual bool postDown() override; private: + ICanController::Result updateIfaceName(base::unique_fd& uartFd); + const std::string mUartName; const uint32_t kBitrate; base::unique_fd mFd;