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 "VtsAgentTcpServer"
     17 
     18 #include "TcpServerForRunner.h"
     19 
     20 #include <netdb.h>
     21 #include <netinet/in.h>
     22 #include <sys/socket.h>
     23 #include <sys/types.h>
     24 
     25 #include <android-base/logging.h>
     26 
     27 #include "AgentRequestHandler.h"
     28 #include "BinderClientToDriver.h"
     29 #include "test/vts/proto/AndroidSystemControlMessage.pb.h"
     30 
     31 namespace android {
     32 namespace vts {
     33 
     34 // Starts to run a TCP server (foreground).
     35 int StartTcpServerForRunner(const char* spec_dir_path,
     36                             const char* hal_driver_path32,
     37                             const char* hal_driver_path64,
     38                             const char* shell_driver_path32,
     39                             const char* shell_driver_path64) {
     40   int sockfd;
     41   socklen_t clilen;
     42   struct sockaddr_in serv_addr;
     43   struct sockaddr_in cli_addr;
     44 
     45   sockfd = socket(AF_INET, SOCK_STREAM, 0);
     46   if (sockfd < 0) {
     47     LOG(ERROR) << "Can't open the socket.";
     48     return -1;
     49   }
     50 
     51   bzero((char*)&serv_addr, sizeof(serv_addr));
     52   serv_addr.sin_family = AF_INET;
     53   serv_addr.sin_addr.s_addr = INADDR_ANY;
     54   serv_addr.sin_port = htons(0);
     55 
     56   if (::bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
     57     LOG(ERROR) << "bind failed. errno = " << errno << " " << strerror(errno);
     58     return -1;
     59   }
     60 
     61   socklen_t sa_len = sizeof(serv_addr);
     62   if (getsockname(sockfd, (struct sockaddr*) &serv_addr, &sa_len) == -1) {
     63     LOG(ERROR) << "getsockname failed. errno = " << errno << " "
     64                << strerror(errno);
     65     return -1;
     66   }
     67 
     68   LOG(DEBUG) << "TCP server port is " << (int)ntohs(serv_addr.sin_port);
     69   FILE* fp = fopen("/data/local/tmp/vts_tcp_server_port", "wt");
     70   if (!fp) {
     71     LOG(ERROR) << "Can't write to "
     72                << "/data/local/tmp/vts_tcp_server_port";
     73     return -1;
     74   }
     75   fprintf(fp, "%d", (int) ntohs(serv_addr.sin_port));
     76   fclose(fp);
     77 
     78   LOG(DEBUG) << "Listening";
     79   if (listen(sockfd, 5) == -1) {
     80     LOG(ERROR) << " listen failed.";
     81     return -1;
     82   }
     83   clilen = sizeof(cli_addr);
     84   while (true) {
     85     LOG(DEBUG) << "Accepting";
     86     int newsockfd = ::accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
     87     if (newsockfd < 0) {
     88       LOG(ERROR) << "accept failed";
     89       return -1;
     90     }
     91 
     92     LOG(DEBUG) << "[runner->agent] NEW SESSION";
     93     LOG(DEBUG) << "[runner->agent] ===========";
     94     pid_t pid = fork();
     95     if (pid == 0) {  // child
     96       close(sockfd);
     97       LOG(DEBUG) << "Process for a runner - pid = " << getpid();
     98       AgentRequestHandler handler(spec_dir_path, hal_driver_path32,
     99                                   hal_driver_path64, shell_driver_path32,
    100                                   shell_driver_path64);
    101       handler.SetSockfd(newsockfd);
    102       while (handler.ProcessOneCommand())
    103         ;
    104       exit(-1);
    105     } else if (pid < 0) {
    106       LOG(ERROR) << "Can't fork a child process to handle a session.";
    107       return -1;
    108     } else {
    109       close(newsockfd);
    110     }
    111   }
    112   return 0;
    113 }
    114 
    115 }  // namespace vts
    116 }  // namespace android
    117