Merge "wifi(vts): Set the iface up as a part of setup"
diff --git a/automotive/can/1.0/default/Android.bp b/automotive/can/1.0/default/Android.bp
index 8aa1d6b..ee2e92b 100644
--- a/automotive/can/1.0/default/Android.bp
+++ b/automotive/can/1.0/default/Android.bp
@@ -39,6 +39,7 @@
         "CanBus.cpp",
         "CanBusNative.cpp",
         "CanBusVirtual.cpp",
+        "CanBusSlcan.cpp",
         "CanController.cpp",
         "CanSocket.cpp",
         "CloseHandle.cpp",
diff --git a/automotive/can/1.0/default/CanBus.cpp b/automotive/can/1.0/default/CanBus.cpp
index 38a9974..42d2e3c 100644
--- a/automotive/can/1.0/default/CanBus.cpp
+++ b/automotive/can/1.0/default/CanBus.cpp
@@ -30,9 +30,7 @@
 namespace V1_0 {
 namespace implementation {
 
-/**
- * Whether to log sent/received packets.
- */
+/** Whether to log sent/received packets. */
 static constexpr bool kSuperVerbose = false;
 
 Return<Result> CanBus::send(const CanMessage& message) {
@@ -85,6 +83,8 @@
     return {};
 }
 
+CanBus::CanBus() {}
+
 CanBus::CanBus(const std::string& ifname) : mIfname(ifname) {}
 
 CanBus::~CanBus() {
diff --git a/automotive/can/1.0/default/CanBus.h b/automotive/can/1.0/default/CanBus.h
index 30a2924..365e90c 100644
--- a/automotive/can/1.0/default/CanBus.h
+++ b/automotive/can/1.0/default/CanBus.h
@@ -48,12 +48,22 @@
     bool down();
 
   protected:
+    /**
+     * Blank constructor, since some interface types (such as SLCAN) don't get a name until after
+     * being initialized.
+     *
+     * If using this constructor, you MUST initialize mIfname prior to the completion of preUp().
+     */
+    CanBus();
+
     CanBus(const std::string& ifname);
 
     /**
      * Prepare the SocketCAN interface.
      *
      * After calling this method, mIfname network interface is available and ready to be brought up.
+     *
+     * \return OK on success, or an error state on failure. See ICanController::Result
      */
     virtual ICanController::Result preUp();
 
@@ -61,11 +71,13 @@
      * Cleanup after bringing the interface down.
      *
      * This is a counterpart to preUp().
+     *
+     * \return true upon success and false upon failure
      */
     virtual bool postDown();
 
     /** Network interface name. */
-    const std::string mIfname;
+    std::string mIfname;
 
   private:
     struct CanMessageListener {
diff --git a/automotive/can/1.0/default/CanBusSlcan.cpp b/automotive/can/1.0/default/CanBusSlcan.cpp
new file mode 100644
index 0000000..7dce838
--- /dev/null
+++ b/automotive/can/1.0/default/CanBusSlcan.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBusSlcan.h"
+
+#include <android-base/logging.h>
+#include <libnetdevice/can.h>
+#include <libnetdevice/libnetdevice.h>
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <termios.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace can {
+namespace V1_0 {
+namespace implementation {
+
+namespace slcanprotocol {
+static const std::string kOpenCommand = "O\r";
+static const std::string kCloseCommand = "C\r";
+static constexpr int kSlcanDiscipline = N_SLCAN;
+static constexpr int kDefaultDiscipline = N_TTY;
+
+static const std::map<uint32_t, std::string> kBitrateCommands = {
+        {10000, "C\rS0\r"},  {20000, "C\rS1\r"},  {50000, "C\rS2\r"},
+        {100000, "C\rS3\r"}, {125000, "C\rS4\r"}, {250000, "C\rS5\r"},
+        {500000, "C\rS6\r"}, {800000, "C\rS7\r"}, {1000000, "C\rS8\r"}};
+}  // namespace slcanprotocol
+
+/**
+ * Serial Line CAN constructor
+ * \param string uartName - name of slcan device (e.x. /dev/ttyUSB0)
+ * \param uint32_t bitrate - speed of the CAN bus (125k = MSCAN, 500k = HSCAN)
+ */
+CanBusSlcan::CanBusSlcan(const std::string& uartName, uint32_t bitrate)
+    : CanBus(), mUartName(uartName), kBitrate(bitrate) {}
+
+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;
+    }
+    const auto canBitrateCommand = lookupIt->second;
+
+    /* Attempt to open the uart in r/w without blocking or becoming the
+     * controlling terminal */
+    mFd = base::unique_fd(open(mUartName.c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY));
+    if (!mFd.ok()) {
+        LOG(ERROR) << "SLCAN Failed to open " << mUartName << ": " << strerror(errno);
+        return ICanController::Result::BAD_ADDRESS;
+    }
+
+    // blank terminal settings and pull them from the device
+    struct termios terminalSettings = {};
+    if (tcgetattr(mFd.get(), &terminalSettings) < 0) {
+        LOG(ERROR) << "Failed to read attrs of" << mUartName << ": " << strerror(errno);
+        return ICanController::Result::UNKNOWN_ERROR;
+    }
+
+    // change settings to raw mode
+    cfmakeraw(&terminalSettings);
+
+    // disable software flow control
+    terminalSettings.c_iflag &= ~IXOFF;
+    // enable hardware flow control
+    terminalSettings.c_cflag |= CRTSCTS;
+
+    struct serial_struct serialSettings;
+    // get serial settings
+    if (ioctl(mFd.get(), TIOCGSERIAL, &serialSettings) < 0) {
+        LOG(ERROR) << "Failed to read serial settings from " << mUartName << ": "
+                   << strerror(errno);
+        return ICanController::Result::UNKNOWN_ERROR;
+    }
+    // set low latency mode
+    serialSettings.flags |= ASYNC_LOW_LATENCY;
+    // apply serial settings
+    if (ioctl(mFd.get(), TIOCSSERIAL, &serialSettings) < 0) {
+        LOG(ERROR) << "Failed to set low latency mode on " << mUartName << ": " << strerror(errno);
+        return ICanController::Result::UNKNOWN_ERROR;
+    }
+
+    /* TCSADRAIN applies settings after we finish writing the rest of our
+     * changes (as opposed to TCSANOW, which changes immediately) */
+    if (tcsetattr(mFd.get(), TCSADRAIN, &terminalSettings) < 0) {
+        LOG(ERROR) << "Failed to apply terminal settings to " << mUartName << ": "
+                   << strerror(errno);
+        return ICanController::Result::UNKNOWN_ERROR;
+    }
+
+    // apply speed setting for CAN
+    if (write(mFd.get(), canBitrateCommand.c_str(), canBitrateCommand.length()) <= 0) {
+        LOG(ERROR) << "Failed to apply CAN bitrate: " << strerror(errno);
+        return ICanController::Result::UNKNOWN_ERROR;
+    }
+
+    // set open flag TODO: also support listen only
+    if (write(mFd.get(), slcanprotocol::kOpenCommand.c_str(),
+              slcanprotocol::kOpenCommand.length()) <= 0) {
+        LOG(ERROR) << "Failed to set open flag: " << strerror(errno);
+        return ICanController::Result::UNKNOWN_ERROR;
+    }
+
+    // set line discipline to slcan
+    if (ioctl(mFd.get(), TIOCSETD, &slcanprotocol::kSlcanDiscipline) < 0) {
+        LOG(ERROR) << "Failed to set line discipline to slcan: " << strerror(errno);
+        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;
+}
+
+bool CanBusSlcan::postDown() {
+    // reset the line discipline to TTY mode
+    if (ioctl(mFd.get(), TIOCSETD, &slcanprotocol::kDefaultDiscipline) < 0) {
+        LOG(ERROR) << "Failed to reset line discipline!";
+        return false;
+    }
+
+    // issue the close command
+    if (write(mFd.get(), slcanprotocol::kCloseCommand.c_str(),
+              slcanprotocol::kCloseCommand.length()) <= 0) {
+        LOG(ERROR) << "Failed to close tty!";
+        return false;
+    }
+
+    // close our unique_fd
+    mFd.reset();
+
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace can
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/can/1.0/default/CanBusSlcan.h b/automotive/can/1.0/default/CanBusSlcan.h
new file mode 100644
index 0000000..2713da8
--- /dev/null
+++ b/automotive/can/1.0/default/CanBusSlcan.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <net/if.h>
+#include <termios.h>
+#include "CanBus.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace can {
+namespace V1_0 {
+namespace implementation {
+
+struct CanBusSlcan : public CanBus {
+    CanBusSlcan(const std::string& uartName, uint32_t bitrate);
+
+  protected:
+    virtual ICanController::Result preUp() override;
+    virtual bool postDown() override;
+
+  private:
+    const std::string mUartName;
+    const uint32_t kBitrate;
+    base::unique_fd mFd;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace can
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/can/1.0/default/CanController.cpp b/automotive/can/1.0/default/CanController.cpp
index 3b63fe4..ffdc912 100644
--- a/automotive/can/1.0/default/CanController.cpp
+++ b/automotive/can/1.0/default/CanController.cpp
@@ -17,6 +17,7 @@
 #include "CanController.h"
 
 #include "CanBusNative.h"
+#include "CanBusSlcan.h"
 #include "CanBusVirtual.h"
 
 #include <android-base/logging.h>
@@ -34,10 +35,8 @@
 using IfaceIdDisc = ICanController::BusConfiguration::InterfaceIdentifier::hidl_discriminator;
 
 Return<void> CanController::getSupportedInterfaceTypes(getSupportedInterfaceTypes_cb _hidl_cb) {
-    _hidl_cb({
-            ICanController::InterfaceType::VIRTUAL,
-            ICanController::InterfaceType::SOCKETCAN,
-    });
+    _hidl_cb({ICanController::InterfaceType::VIRTUAL, ICanController::InterfaceType::SOCKETCAN,
+              ICanController::InterfaceType::SLCAN});
     return {};
 }
 
@@ -77,6 +76,12 @@
         } else {
             return ICanController::Result::BAD_ADDRESS;
         }
+    } else if (config.iftype == ICanController::InterfaceType::SLCAN) {
+        if (config.interfaceId.getDiscriminator() == IfaceIdDisc::address) {
+            busService = new CanBusSlcan(config.interfaceId.address(), config.baudrate);
+        } else {
+            return ICanController::Result::BAD_ADDRESS;
+        }
     } else {
         return ICanController::Result::NOT_SUPPORTED;
     }
diff --git a/automotive/can/1.0/default/CanSocket.cpp b/automotive/can/1.0/default/CanSocket.cpp
index ecf4044..86e12d1 100644
--- a/automotive/can/1.0/default/CanSocket.cpp
+++ b/automotive/can/1.0/default/CanSocket.cpp
@@ -33,12 +33,10 @@
 
 using namespace std::chrono_literals;
 
-/**
- * How frequently the read thread checks whether the interface was asked to be down.
+/* How frequently the read thread checks whether the interface was asked to be down.
  *
  * Note: This does *not* affect read timing or bandwidth, just CPU load vs time to
- *       down the interface.
- */
+ *       down the interface. */
 static constexpr auto kReadPooling = 100ms;
 
 std::unique_ptr<CanSocket> CanSocket::open(const std::string& ifname, ReadCallback rdcb,
@@ -105,8 +103,7 @@
 
     while (!mStopReaderThread) {
         /* The ideal would be to have a blocking read(3) call and interrupt it with shutdown(3).
-         * This is unfortunately not supported for SocketCAN, so we need to rely on select(3).
-         */
+         * This is unfortunately not supported for SocketCAN, so we need to rely on select(3). */
         const auto sel = selectRead(mSocket, kReadPooling);
         if (sel == 0) continue;  // timeout
         if (sel == -1) {
@@ -127,8 +124,7 @@
          * Apart from the added complexity, it's possible the added calculations and system calls
          * would add so much time to the processing pipeline so the precision of the reported time
          * was buried under the subsystem latency. Let's just use a local time since boot here and
-         * leave precise hardware timestamps for custom proprietary implementations (if needed).
-         */
+         * leave precise hardware timestamps for custom proprietary implementations (if needed). */
         const std::chrono::nanoseconds ts(elapsedRealtimeNano());
 
         if (nbytes != CAN_MTU) {
diff --git a/automotive/can/1.0/default/CanSocket.h b/automotive/can/1.0/default/CanSocket.h
index 284e1ea..c98330b 100644
--- a/automotive/can/1.0/default/CanSocket.h
+++ b/automotive/can/1.0/default/CanSocket.h
@@ -31,9 +31,7 @@
 namespace V1_0 {
 namespace implementation {
 
-/**
- * Wrapper around SocketCAN socket.
- */
+/** Wrapper around SocketCAN socket. */
 struct CanSocket {
     using ReadCallback = std::function<void(const struct canfd_frame&, std::chrono::nanoseconds)>;
     using ErrorCallback = std::function<void(int errnoVal)>;
diff --git a/automotive/can/1.0/default/CloseHandle.h b/automotive/can/1.0/default/CloseHandle.h
index 5191739..eade109 100644
--- a/automotive/can/1.0/default/CloseHandle.h
+++ b/automotive/can/1.0/default/CloseHandle.h
@@ -26,9 +26,7 @@
 namespace V1_0 {
 namespace implementation {
 
-/**
- * Generic ICloseHandle implementation ignoring double-close events.
- */
+/** Generic ICloseHandle implementation ignoring double-close events. */
 struct CloseHandle : public ICloseHandle {
     using Callback = std::function<void()>;
 
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
index 21202e3..ba9b65b 100644
--- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
+++ b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
@@ -27,9 +27,7 @@
 typedef unsigned short rtattrtype_t;  // as in rtnetlink.h
 typedef __u16 nlmsgtype_t;            // as in netlink.h
 
-/**
- * Implementation details, do not use outside NetlinkRequest template.
- */
+/** Implementation details, do not use outside NetlinkRequest template. */
 namespace impl {
 
 struct rtattr* addattr_l(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type, const void* data,
@@ -59,7 +57,7 @@
         mRequest.nlmsg.nlmsg_flags = flags;
     }
 
-    /** Returns pointer to raw netlink message header. */
+    /** \return pointer to raw netlink message header. */
     struct nlmsghdr* header() {
         return &mRequest.nlmsg;
     }
@@ -89,9 +87,7 @@
         if (ap == nullptr) mIsGood = false;
     }
 
-    /**
-     * Guard class to frame nested attributes. See nest(int).
-     */
+    /** Guard class to frame nested attributes. See nest(int). */
     struct Nest {
         Nest(NetlinkRequest& req, rtattrtype_t type) : mReq(req), mAttr(req.nestStart(type)) {}
         ~Nest() { mReq.nestEnd(mAttr); }
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
index 81d6224..90e1f3f 100644
--- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
+++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
@@ -38,8 +38,8 @@
     /**
      * Send Netlink message to Kernel.
      *
-     * @param msg Message to send, nlmsg_seq will be set to next sequence number
-     * @return true, if succeeded
+     * \param msg Message to send, nlmsg_seq will be set to next sequence number
+     * \return true, if succeeded
      */
     template <class T, unsigned int BUFSIZE>
     bool send(NetlinkRequest<T, BUFSIZE>& req) {
@@ -50,7 +50,7 @@
     /**
      * Receive Netlink ACK message from Kernel.
      *
-     * @return true if received ACK message, false in case of error
+     * \return true if received ACK message, false in case of error
      */
     bool receiveAck();
 
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
index ec3f962..d75361e 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
@@ -27,13 +27,16 @@
 /**
  * Opens and binds SocketCAN socket.
  *
- * @param ifname Interface to open a socket against
- * @return Socket's FD or -1 in case of failure
+ * \param ifname Interface to open a socket against
+ * \return Socket's FD or -1 in case of failure
  */
 base::unique_fd socket(const std::string& ifname);
 
 /**
  * Sets CAN interface bitrate.
+ *
+ * \param ifname Interface for which the bitrate is to be set
+ * \return true on success, false on failure
  */
 bool setBitrate(std::string ifname, uint32_t bitrate);
 
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
index 33d5de5..e22eafb 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
@@ -25,49 +25,49 @@
 /**
  * Checks, if the network interface exists.
  *
- * @param ifname Interface to check
- * @return true if it exists, false otherwise
+ * \param ifname Interface to check
+ * \return true if it exists, false otherwise
  */
 bool exists(std::string ifname);
 
 /**
  * Checks if network interface is up.
  *
- * @param ifname Interface to check
- * @return true/false if the check succeeded, nullopt otherwise
+ * \param ifname Interface to check
+ * \return true/false if the check succeeded, nullopt otherwise
  */
 std::optional<bool> isUp(std::string ifname);
 
 /**
  * Brings network interface up.
  *
- * @param ifname Interface to bring up
- * @return true in case of success, false otherwise
+ * \param ifname Interface to bring up
+ * \return true in case of success, false otherwise
  */
 bool up(std::string ifname);
 
 /**
  * Brings network interface down.
  *
- * @param ifname Interface to bring down
- * @return true in case of success, false otherwise
+ * \param ifname Interface to bring down
+ * \return true in case of success, false otherwise
  */
 bool down(std::string ifname);
 
 /**
  * Adds virtual link.
  *
- * @param dev the name of the new virtual device
- * @param type the type of the new device
- * @return true in case of success, false otherwise
+ * \param dev the name of the new virtual device
+ * \param type the type of the new device
+ * \return true in case of success, false otherwise
  */
 bool add(std::string dev, std::string type);
 
 /**
  * Deletes virtual link.
  *
- * @param dev the name of the device to remove
- * @return true in case of success, false otherwise
+ * \param dev the name of the device to remove
+ * \return true in case of success, false otherwise
  */
 bool del(std::string dev);
 
diff --git a/automotive/can/1.0/tools/canhaldump.cpp b/automotive/can/1.0/tools/canhaldump.cpp
index 5713d17..99fd14a 100644
--- a/automotive/can/1.0/tools/canhaldump.cpp
+++ b/automotive/can/1.0/tools/canhaldump.cpp
@@ -49,7 +49,7 @@
         } else {
             std::cout << "   [" << message.payload.size() << "] ";
             for (const auto byte : message.payload) {
-                std::cout << " " << unsigned(byte);
+                std::cout << " " << std::setfill('0') << std::setw(2) << unsigned(byte);
             }
         }
         std::cout << std::nouppercase << std::dec << std::endl;
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
index ba29c29..225984d 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
@@ -91,8 +91,7 @@
         EXPECT_EQ(ICanController::Result::OK, result);
 
         /* Not using ICanBus::getService here, since it ignores interfaces not in the manifest
-         * file -- this is a test, so we don't want to add dummy services to a device manifest.
-         */
+         * file -- this is a test, so we don't want to add dummy services to a device manifest. */
         auto manager = hidl::manager::V1_2::IServiceManager::getService();
         auto service = manager->get(ICanBus::descriptor, config.name);
         mBus = ICanBus::castFrom(service);
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
index 70f9fe4..64e7a96 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
@@ -95,8 +95,7 @@
 
 void CanControllerHalTest::assertRegistered(std::string srvname, bool expectRegistered) {
     /* Not using ICanBus::tryGetService here, since it ignores interfaces not in the manifest
-     * file -- this is a test, so we don't want to add dummy services to a device manifest.
-     */
+     * file -- this is a test, so we don't want to add dummy services to a device manifest. */
     auto manager = hidl::manager::V1_2::IServiceManager::getService();
     auto busService = manager->get(ICanBus::descriptor, srvname);
     ASSERT_EQ(expectRegistered, busService.withDefault(nullptr) != nullptr)
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
index 9eb8894..068333c 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
@@ -92,7 +92,10 @@
     }
 
     ALOGI("%s: Listening for connections on port %d", __FUNCTION__, DEBUG_SOCKET);
-    ::listen(mListenFd, 1);
+    if (::listen(mListenFd, 1) == -1) {
+        ALOGE("%s: Error on listening: errno: %d: %s", __FUNCTION__, errno, strerror(errno));
+        return false;
+    }
     return true;
 }