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