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