Home | History | Annotate | Download | only in vhal_v2_0
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "SocketComm"
     18 
     19 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
     20 #include <android/log.h>
     21 #include <log/log.h>
     22 #include <netinet/in.h>
     23 #include <sys/socket.h>
     24 
     25 #include "SocketComm.h"
     26 
     27 // Socket to use when communicating with Host PC
     28 static constexpr int DEBUG_SOCKET = 33452;
     29 
     30 namespace android {
     31 namespace hardware {
     32 namespace automotive {
     33 namespace vehicle {
     34 namespace V2_0 {
     35 
     36 namespace impl {
     37 
     38 SocketComm::SocketComm() {
     39     // Initialize member vars
     40     mCurSockFd = -1;
     41     mExit      =  0;
     42     mSockFd    = -1;
     43 }
     44 
     45 
     46 SocketComm::~SocketComm() {
     47     stop();
     48 }
     49 
     50 int SocketComm::connect() {
     51     sockaddr_in cliAddr;
     52     socklen_t cliLen = sizeof(cliAddr);
     53     int cSockFd = accept(mSockFd, reinterpret_cast<struct sockaddr*>(&cliAddr), &cliLen);
     54 
     55     if (cSockFd >= 0) {
     56         {
     57             std::lock_guard<std::mutex> lock(mMutex);
     58             mCurSockFd = cSockFd;
     59         }
     60         ALOGD("%s: Incoming connection received on socket %d", __FUNCTION__, cSockFd);
     61     } else {
     62         cSockFd = -1;
     63     }
     64 
     65     return cSockFd;
     66 }
     67 
     68 int SocketComm::open() {
     69     int retVal;
     70     struct sockaddr_in servAddr;
     71 
     72     mSockFd = socket(AF_INET, SOCK_STREAM, 0);
     73     if (mSockFd < 0) {
     74         ALOGE("%s: socket() failed, mSockFd=%d, errno=%d", __FUNCTION__, mSockFd, errno);
     75         mSockFd = -1;
     76         return -errno;
     77     }
     78 
     79     memset(&servAddr, 0, sizeof(servAddr));
     80     servAddr.sin_family = AF_INET;
     81     servAddr.sin_addr.s_addr = INADDR_ANY;
     82     servAddr.sin_port = htons(DEBUG_SOCKET);
     83 
     84     retVal = bind(mSockFd, reinterpret_cast<struct sockaddr*>(&servAddr), sizeof(servAddr));
     85     if(retVal < 0) {
     86         ALOGE("%s: Error on binding: retVal=%d, errno=%d", __FUNCTION__, retVal, errno);
     87         close(mSockFd);
     88         mSockFd = -1;
     89         return -errno;
     90     }
     91 
     92     listen(mSockFd, 1);
     93 
     94     // Set the socket to be non-blocking so we can poll it continouously
     95     fcntl(mSockFd, F_SETFL, O_NONBLOCK);
     96 
     97     return 0;
     98 }
     99 
    100 std::vector<uint8_t> SocketComm::read() {
    101     int32_t msgSize;
    102     int numBytes = 0;
    103 
    104     // This is a variable length message.
    105     // Read the number of bytes to rx over the socket
    106     numBytes = ::read(mCurSockFd, &msgSize, sizeof(msgSize));
    107     msgSize = ntohl(msgSize);
    108 
    109     if (numBytes != sizeof(msgSize)) {
    110         // This happens when connection is closed
    111         ALOGD("%s: numBytes=%d, expected=4", __FUNCTION__, numBytes);
    112         ALOGD("%s: Connection terminated on socket %d", __FUNCTION__, mCurSockFd);
    113         {
    114             std::lock_guard<std::mutex> lock(mMutex);
    115             mCurSockFd = -1;
    116         }
    117 
    118         return std::vector<uint8_t>();
    119     }
    120 
    121     std::vector<uint8_t> msg = std::vector<uint8_t>(msgSize);
    122 
    123     numBytes = ::read(mCurSockFd, msg.data(), msgSize);
    124 
    125     if ((numBytes == msgSize) && (msgSize > 0)) {
    126         // Received a message.
    127         return msg;
    128     } else {
    129         // This happens when connection is closed
    130         ALOGD("%s: numBytes=%d, msgSize=%d", __FUNCTION__, numBytes, msgSize);
    131         ALOGD("%s: Connection terminated on socket %d", __FUNCTION__, mCurSockFd);
    132         {
    133             std::lock_guard<std::mutex> lock(mMutex);
    134             mCurSockFd = -1;
    135         }
    136 
    137         return std::vector<uint8_t>();
    138     }
    139 }
    140 
    141 void SocketComm::stop() {
    142     if (mExit == 0) {
    143         std::lock_guard<std::mutex> lock(mMutex);
    144         mExit = 1;
    145 
    146         // Close emulator socket if it is open
    147         if (mCurSockFd != -1) {
    148             close(mCurSockFd);
    149             mCurSockFd = -1;
    150         }
    151 
    152         if (mSockFd != -1) {
    153             close(mSockFd);
    154             mSockFd = -1;
    155         }
    156     }
    157 }
    158 
    159 int SocketComm::write(const std::vector<uint8_t>& data) {
    160     static constexpr int MSG_HEADER_LEN = 4;
    161     int retVal = 0;
    162     union {
    163         uint32_t msgLen;
    164         uint8_t msgLenBytes[MSG_HEADER_LEN];
    165     };
    166 
    167     // Prepare header for the message
    168     msgLen = static_cast<uint32_t>(data.size());
    169     msgLen = htonl(msgLen);
    170 
    171     std::lock_guard<std::mutex> lock(mMutex);
    172     if (mCurSockFd != -1) {
    173         retVal = ::write(mCurSockFd, msgLenBytes, MSG_HEADER_LEN);
    174 
    175         if (retVal == MSG_HEADER_LEN) {
    176             retVal = ::write(mCurSockFd, data.data(), data.size());
    177         }
    178     }
    179 
    180     return retVal;
    181 }
    182 
    183 
    184 }  // impl
    185 
    186 }  // namespace V2_0
    187 }  // namespace vehicle
    188 }  // namespace automotive
    189 }  // namespace hardware
    190 }  // namespace android
    191 
    192