Home | History | Annotate | Download | only in hal
      1 /*
      2  * Copyright 2016 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 #define LOG_TAG "VtsAgentSocketServer"
     17 
     18 #include "SocketServerForDriver.h"
     19 
     20 #include <netdb.h>
     21 #include <netinet/in.h>
     22 #include <sys/socket.h>
     23 #include <sys/un.h>
     24 #include <string>
     25 
     26 #include <android-base/logging.h>
     27 
     28 #include "test/vts/proto/AndroidSystemControlMessage.pb.h"
     29 
     30 namespace android {
     31 namespace vts {
     32 
     33 static const int kCallbackServerPort = 5010;
     34 
     35 void SocketServerForDriver::RpcCallToRunner(
     36     const AndroidSystemCallbackRequestMessage& message) {
     37   struct sockaddr_in serv_addr;
     38   struct hostent* server;
     39 
     40   int sockfd;
     41   sockfd = socket(AF_INET, SOCK_STREAM, 0);
     42   if (sockfd < 0) {
     43     LOG(ERROR) << "ERROR opening socket";
     44     exit(-1);
     45     return;
     46   }
     47   server = gethostbyname("127.0.0.1");
     48   if (server == NULL) {
     49     LOG(ERROR) << "Can't resolve the host name, localhost";
     50     exit(-1);
     51     return;
     52   }
     53   bzero((char*)&serv_addr, sizeof(serv_addr));
     54   serv_addr.sin_family = AF_INET;
     55   bcopy((char*)server->h_addr, (char*)&serv_addr.sin_addr.s_addr,
     56         server->h_length);
     57   serv_addr.sin_port = htons(runner_port_);
     58 
     59   if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
     60     LOG(ERROR) << "ERROR connecting";
     61     exit(-1);
     62     return;
     63   }
     64 
     65   VtsDriverCommUtil util(sockfd);
     66   if (!util.VtsSocketSendMessage(message)) return;
     67 }
     68 
     69 void SocketServerForDriver::Start() {
     70   AndroidSystemCallbackRequestMessage message;
     71   if (!VtsSocketRecvMessage(&message)) return;
     72   LOG(INFO) << "Start server for driver with callback ID: " << message.id();
     73   RpcCallToRunner(message);
     74   Close();
     75 }
     76 
     77 int StartSocketServerForDriver(const string& callback_socket_name,
     78                                int runner_port) {
     79   struct sockaddr_un serv_addr;
     80   int pid = fork();
     81   if (pid < 0) {
     82     LOG(ERROR) << "ERROR on fork";
     83     return -1;
     84   } else if (pid > 0) {
     85     return 0;
     86   }
     87 
     88   if (runner_port == -1) {
     89     runner_port = kCallbackServerPort;
     90   }
     91   // only child process continues;
     92   int sockfd;
     93   sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
     94   if (sockfd < 0) {
     95     LOG(ERROR) << "ERROR opening socket";
     96     return -1;
     97   }
     98 
     99   bzero((char*) &serv_addr, sizeof(serv_addr));
    100   serv_addr.sun_family = AF_UNIX;
    101   strcpy(serv_addr.sun_path, callback_socket_name.c_str());
    102   LOG(INFO) << "Callback server at " << callback_socket_name;
    103 
    104   if (::bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) {
    105     int error_save = errno;
    106     LOG(ERROR) << "ERROR on binding " << callback_socket_name
    107                << " errno = " << error_save << " " << strerror(error_save);
    108     return -1;
    109   }
    110 
    111   if (listen(sockfd, 5) < 0) {
    112     LOG(ERROR) << "ERROR on listening";
    113     return -1;
    114   }
    115 
    116   while (1) {
    117     int newsockfd;
    118     struct sockaddr_in cli_addr;
    119     socklen_t clilen;
    120 
    121     clilen = sizeof(cli_addr);
    122     newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &clilen);
    123     if (newsockfd < 0) {
    124       LOG(ERROR) << "ERROR on accept " << strerror(errno);
    125       break;
    126     }
    127     LOG(DEBUG) << "New callback connection.";
    128     pid = fork();
    129     if (pid == 0) {
    130       close(sockfd);
    131       SocketServerForDriver server(newsockfd, runner_port);
    132       server.Start();
    133       exit(0);
    134     } else if (pid > 0) {
    135       close(newsockfd);
    136     } else {
    137       LOG(ERROR) << "ERROR on fork";
    138       break;
    139     }
    140   }
    141   close(sockfd);
    142   exit(0);
    143 }
    144 
    145 }  // namespace vts
    146 }  // namespace android
    147