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 17 #ifndef VTS_AGENT_DRIVER_COMM_BINDER // socket 18 19 #define LOG_TAG "VtsDriverHalSocketServer" 20 21 #include "SocketServer.h" 22 23 #include <netinet/in.h> 24 #include <sys/un.h> 25 #include <string> 26 27 #include <VtsDriverCommUtil.h> 28 #include <android-base/logging.h> 29 #include <google/protobuf/text_format.h> 30 31 #include "test/vts/proto/ComponentSpecificationMessage.pb.h" 32 #include "test/vts/proto/VtsDriverControlMessage.pb.h" 33 34 using namespace std; 35 36 namespace android { 37 namespace vts { 38 39 void VtsDriverHalSocketServer::Exit() { 40 LOG(INFO) << "VtsHalDriverServer::Exit"; 41 } 42 43 int32_t VtsDriverHalSocketServer::LoadHal(const string& path, int target_class, 44 int target_type, float target_version, 45 const string& target_package, 46 const string& target_component_name, 47 const string& hw_binder_service_name, 48 const string& /*module_name*/) { 49 LOG(DEBUG) << "LoadHal(" << path << ")"; 50 int32_t driver_id = driver_manager_->LoadTargetComponent( 51 path.c_str(), lib_path_, target_class, target_type, target_version, 52 target_package.c_str(), target_component_name.c_str(), 53 hw_binder_service_name.c_str()); 54 LOG(DEBUG) << "Result: " << driver_id; 55 return driver_id; 56 } 57 58 59 string VtsDriverHalSocketServer::ReadSpecification( 60 const string& name, int target_class, int target_type, float target_version, 61 const string& target_package) { 62 ComponentSpecificationMessage msg; 63 driver_manager_->FindComponentSpecification( 64 target_class, target_type, target_version, target_package, name, &msg); 65 string result; 66 google::protobuf::TextFormat::PrintToString(msg, &result); 67 LOG(DEBUG) << "Result: " << result; 68 return result; 69 } 70 71 string VtsDriverHalSocketServer::Call(const string& arg) { 72 FunctionCallMessage* call_msg = new FunctionCallMessage(); 73 google::protobuf::TextFormat::MergeFromString(arg, call_msg); 74 const string& result = driver_manager_->CallFunction(call_msg); 75 LOG(DEBUG) << "Result: " << result; 76 return result; 77 } 78 79 string VtsDriverHalSocketServer::GetAttribute(const string& arg) { 80 FunctionCallMessage* call_msg = new FunctionCallMessage(); 81 google::protobuf::TextFormat::MergeFromString(arg, call_msg); 82 const string& result = driver_manager_->GetAttribute(call_msg); 83 LOG(DEBUG) << "Result: " << result; 84 return result; 85 } 86 87 string VtsDriverHalSocketServer::ListFunctions() const { 88 vts::ComponentSpecificationMessage* spec = 89 driver_manager_->GetComponentSpecification(); 90 string output; 91 if (!spec) { 92 return output; 93 } 94 if (google::protobuf::TextFormat::PrintToString(*spec, &output)) { 95 LOG(DEBUG) << "Result: " << output; 96 return output; 97 } else { 98 LOG(ERROR) << "Can't serialize the interface spec message to a string."; 99 return output; 100 } 101 } 102 103 bool VtsDriverHalSocketServer::ProcessOneCommand() { 104 VtsDriverControlCommandMessage command_message; 105 if (!VtsSocketRecvMessage(&command_message)) return false; 106 // TODO: get the command type description. 107 LOG(DEBUG) << " command_type " << command_message.command_type(); 108 switch (command_message.command_type()) { 109 case EXIT: { 110 Exit(); 111 VtsDriverControlResponseMessage response_message; 112 response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS); 113 if (VtsSocketSendMessage(response_message)) { 114 LOG(INFO) << "process: " << getpid() << " exiting"; 115 return false; 116 } 117 break; 118 } 119 case LOAD_HAL: { 120 LOG(INFO) << "Process command LOAD_HAL"; 121 int32_t driver_id = LoadHal( 122 command_message.file_path(), command_message.target_class(), 123 command_message.target_type(), command_message.target_version(), 124 command_message.target_package(), 125 command_message.target_component_name(), 126 command_message.hw_binder_service_name(), 127 command_message.module_name()); 128 VtsDriverControlResponseMessage response_message; 129 if (driver_id == -1) { 130 response_message.set_response_code(VTS_DRIVER_RESPONSE_FAIL); 131 } else { 132 response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS); 133 } 134 response_message.set_return_value(driver_id); 135 if (VtsSocketSendMessage(response_message)) return true; 136 break; 137 } 138 case GET_STATUS: { 139 int32_t result = command_message.status_type(); 140 VtsDriverControlResponseMessage response_message; 141 response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS); 142 response_message.set_return_value(result); 143 if (VtsSocketSendMessage(response_message)) return true; 144 break; 145 } 146 case CALL_FUNCTION: { 147 LOG(INFO) << "Process command CALL_FUNCTION"; 148 if (command_message.has_driver_caller_uid()) { 149 setuid(atoi(command_message.driver_caller_uid().c_str())); 150 } 151 const string& result = Call(command_message.arg()); 152 VtsDriverControlResponseMessage response_message; 153 response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS); 154 response_message.set_return_message(result); 155 if (VtsSocketSendMessage(response_message)) return true; 156 break; 157 } 158 case VTS_DRIVER_COMMAND_READ_SPECIFICATION: { 159 LOG(INFO) << "Process command READ_SPECIFICATION"; 160 const string& result = ReadSpecification( 161 command_message.module_name(), command_message.target_class(), 162 command_message.target_type(), command_message.target_version(), 163 command_message.target_package()); 164 VtsDriverControlResponseMessage response_message; 165 response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS); 166 response_message.set_return_message(result); 167 if (VtsSocketSendMessage(response_message)) return true; 168 break; 169 } 170 case GET_ATTRIBUTE: { 171 LOG(INFO) << "Process command GET_ATTRIBUTE"; 172 const string& result = GetAttribute(command_message.arg()); 173 VtsDriverControlResponseMessage response_message; 174 response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS); 175 response_message.set_return_message(result); 176 if (VtsSocketSendMessage(response_message)) return true; 177 break; 178 } 179 case LIST_FUNCTIONS: { 180 LOG(INFO) << "Process command LIST_FUNCTIONS"; 181 string result = ListFunctions(); 182 VtsDriverControlResponseMessage response_message; 183 if (result.size() > 0) { 184 response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS); 185 response_message.set_return_message(result.c_str()); 186 } else { 187 response_message.set_response_code(VTS_DRIVER_RESPONSE_FAIL); 188 } 189 if (VtsSocketSendMessage(response_message)) return true; 190 break; 191 } 192 default: 193 break; 194 } 195 LOG(ERROR) << "Failed."; 196 return false; 197 } 198 199 // Starts to run a UNIX socket server (foreground). 200 int StartSocketServer(const string& socket_port_file, 201 VtsHalDriverManager* driver_manager, 202 const char* lib_path) { 203 int sockfd; 204 socklen_t clilen; 205 struct sockaddr_in cli_addr; 206 struct sockaddr_un serv_addr; 207 208 sockfd = socket(PF_UNIX, SOCK_STREAM, 0); 209 if (sockfd < 0) { 210 LOG(ERROR) << "Can't open the socket."; 211 return -1; 212 } 213 214 unlink(socket_port_file.c_str()); 215 bzero((char*)&serv_addr, sizeof(serv_addr)); 216 serv_addr.sun_family = AF_UNIX; 217 strcpy(serv_addr.sun_path, socket_port_file.c_str()); 218 219 LOG(DEBUG) << "Trying to bind (port file: " << socket_port_file << ")"; 220 221 if (::bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) { 222 int error_save = errno; 223 LOG(ERROR) << "ERROR binding failed. errno = " << error_save << " " 224 << strerror(error_save); 225 return -1; 226 } 227 228 listen(sockfd, 5); 229 clilen = sizeof(cli_addr); 230 231 while (true) { 232 LOG(DEBUG) << "Waiting for a new connection from the agent"; 233 int newsockfd = ::accept(sockfd, (struct sockaddr*)&cli_addr, &clilen); 234 if (newsockfd < 0) { 235 LOG(ERROR) << "ERROR accept failed."; 236 return -1; 237 } 238 239 LOG(DEBUG) << "New session"; 240 pid_t pid = fork(); 241 if (pid == 0) { // child 242 close(sockfd); 243 LOG(DEBUG) << "Process for an agent - pid = " << getpid(); 244 VtsDriverHalSocketServer* server = 245 new VtsDriverHalSocketServer(driver_manager, lib_path); 246 server->SetSockfd(newsockfd); 247 while (server->ProcessOneCommand()) 248 ; 249 delete server; 250 exit(0); 251 } else if (pid < 0) { 252 LOG(ERROR) << "Can't fork a child process to handle a session."; 253 return -1; 254 } 255 close(newsockfd); 256 } 257 LOG(ERROR) << "Exiting"; 258 return 0; 259 } 260 261 } // namespace vts 262 } // namespace android 263 264 #endif 265