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 
RpcCallToRunner(const AndroidSystemCallbackRequestMessage & message)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     PLOG(ERROR) << "ERROR opening socket";
44     exit(-1);
45     return;
46   }
47   server = gethostbyname("127.0.0.1");
48   if (server == NULL) {
49     PLOG(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     PLOG(ERROR) << "ERROR connecting";
61     exit(-1);
62     return;
63   }
64 
65   VtsDriverCommUtil util(sockfd);
66   if (!util.VtsSocketSendMessage(message)) return;
67 }
68 
Start()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 
StartSocketServerForDriver(const string & callback_socket_name,int runner_port)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     PLOG(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     PLOG(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     PLOG(ERROR) << "ERROR on binding " << callback_socket_name;
106     return -1;
107   }
108 
109   if (listen(sockfd, 5) < 0) {
110     PLOG(ERROR) << "ERROR on listening";
111     return -1;
112   }
113 
114   while (1) {
115     int newsockfd;
116     struct sockaddr_in cli_addr;
117     socklen_t clilen;
118 
119     clilen = sizeof(cli_addr);
120     newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &clilen);
121     if (newsockfd < 0) {
122       PLOG(ERROR) << "ERROR on accept";
123       break;
124     }
125     LOG(DEBUG) << "New callback connection.";
126     pid = fork();
127     if (pid == 0) {
128       close(sockfd);
129       SocketServerForDriver server(newsockfd, runner_port);
130       server.Start();
131       exit(0);
132     } else if (pid > 0) {
133       close(newsockfd);
134     } else {
135       PLOG(ERROR) << "ERROR on fork";
136       break;
137     }
138   }
139   close(sockfd);
140   exit(0);
141 }
142 
143 }  // namespace vts
144 }  // namespace android
145