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).
StartTcpServerForRunner(const char * spec_dir_path,const char * hal_driver_path32,const char * hal_driver_path64,const char * shell_driver_path32,const char * shell_driver_path64)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     PLOG(ERROR) << "bind failed";
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     PLOG(ERROR) << "getsockname failed";
64     return -1;
65   }
66 
67   LOG(DEBUG) << "TCP server port is " << (int)ntohs(serv_addr.sin_port);
68   FILE* fp = fopen("/data/local/tmp/vts_tcp_server_port", "wt");
69   if (!fp) {
70     LOG(ERROR) << "Can't write to "
71                << "/data/local/tmp/vts_tcp_server_port";
72     return -1;
73   }
74   fprintf(fp, "%d", (int) ntohs(serv_addr.sin_port));
75   fclose(fp);
76 
77   LOG(DEBUG) << "Listening";
78   if (listen(sockfd, 5) == -1) {
79     LOG(ERROR) << " listen failed.";
80     return -1;
81   }
82   clilen = sizeof(cli_addr);
83   while (true) {
84     LOG(DEBUG) << "Accepting";
85     int newsockfd = ::accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
86     if (newsockfd < 0) {
87       LOG(ERROR) << "accept failed";
88       return -1;
89     }
90 
91     LOG(DEBUG) << "[runner->agent] NEW SESSION";
92     LOG(DEBUG) << "[runner->agent] ===========";
93     pid_t pid = fork();
94     if (pid == 0) {  // child
95       close(sockfd);
96       LOG(DEBUG) << "Process for a runner - pid = " << getpid();
97       AgentRequestHandler handler(spec_dir_path, hal_driver_path32,
98                                   hal_driver_path64, shell_driver_path32,
99                                   shell_driver_path64);
100       handler.SetSockfd(newsockfd);
101       while (handler.ProcessOneCommand())
102         ;
103       exit(-1);
104     } else if (pid < 0) {
105       LOG(ERROR) << "Can't fork a child process to handle a session.";
106       return -1;
107     } else {
108       close(newsockfd);
109     }
110   }
111   return 0;
112 }
113 
114 }  // namespace vts
115 }  // namespace android
116