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