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 #include "test/vts/proto/VtsResourceControllerMessage.pb.h"
34 
35 using namespace std;
36 
37 namespace android {
38 namespace vts {
39 
Exit()40 void VtsDriverHalSocketServer::Exit() {
41   LOG(INFO) << "VtsHalDriverServer::Exit";
42 }
43 
LoadHal(const string & path,int target_class,int target_type,int target_version_major,int target_version_minor,const string & target_package,const string & target_component_name,const string & hw_binder_service_name,const string &)44 int32_t VtsDriverHalSocketServer::LoadHal(
45     const string& path, int target_class, int target_type,
46     int target_version_major, int target_version_minor,
47     const string& target_package, const string& target_component_name,
48     const string& hw_binder_service_name, 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_major,
52       target_version_minor, target_package.c_str(),
53       target_component_name.c_str(), hw_binder_service_name.c_str());
54   LOG(DEBUG) << "Result: " << driver_id;
55   return driver_id;
56 }
57 
ReadSpecification(const string & name,int target_class,int target_type,int target_version_major,int target_version_minor,const string & target_package)58 string VtsDriverHalSocketServer::ReadSpecification(
59     const string& name, int target_class, int target_type,
60     int target_version_major, int target_version_minor,
61     const string& target_package) {
62   ComponentSpecificationMessage msg;
63   driver_manager_->FindComponentSpecification(
64       target_class, target_type, target_version_major, target_version_minor,
65       target_package, name, &msg);
66   string result;
67   google::protobuf::TextFormat::PrintToString(msg, &result);
68   LOG(DEBUG) << "Result: " << result;
69   return result;
70 }
71 
Call(const string & arg)72 string VtsDriverHalSocketServer::Call(const string& arg) {
73   FunctionCallMessage* call_msg = new FunctionCallMessage();
74   google::protobuf::TextFormat::MergeFromString(arg, call_msg);
75   const string& result = driver_manager_->CallFunction(call_msg);
76   LOG(DEBUG) << "Result: " << result;
77   return result;
78 }
79 
GetAttribute(const string & arg)80 string VtsDriverHalSocketServer::GetAttribute(const string& arg) {
81   FunctionCallMessage* call_msg = new FunctionCallMessage();
82   google::protobuf::TextFormat::MergeFromString(arg, call_msg);
83   const string& result = driver_manager_->GetAttribute(call_msg);
84   LOG(DEBUG) << "Result: " << result;
85   return result;
86 }
87 
ListFunctions() const88 string VtsDriverHalSocketServer::ListFunctions() const {
89   vts::ComponentSpecificationMessage* spec =
90       driver_manager_->GetComponentSpecification();
91   string output;
92   if (!spec) {
93     return output;
94   }
95   if (google::protobuf::TextFormat::PrintToString(*spec, &output)) {
96     LOG(DEBUG) << "Result: " << output;
97     return output;
98   } else {
99     LOG(ERROR) << "Can't serialize the interface spec message to a string.";
100     return output;
101   }
102 }
103 
ProcessOneCommand()104 bool VtsDriverHalSocketServer::ProcessOneCommand() {
105   VtsDriverControlCommandMessage command_message;
106   if (!VtsSocketRecvMessage(&command_message)) return false;
107   // TODO: get the command type description.
108   LOG(DEBUG) << " command_type " << command_message.command_type();
109   switch (command_message.command_type()) {
110     case EXIT: {
111       Exit();
112       VtsDriverControlResponseMessage response_message;
113       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
114       if (VtsSocketSendMessage(response_message)) {
115         LOG(INFO) << "process: " << getpid() << " exiting";
116         return false;
117       }
118       break;
119     }
120     case LOAD_HAL: {
121       LOG(INFO) << "Process command LOAD_HAL";
122       int32_t driver_id = LoadHal(
123           command_message.file_path(), command_message.target_class(),
124           command_message.target_type(), command_message.target_version_major(),
125           command_message.target_version_minor(),
126           command_message.target_package(),
127           command_message.target_component_name(),
128           command_message.hw_binder_service_name(),
129           command_message.module_name());
130       VtsDriverControlResponseMessage response_message;
131       if (driver_id == -1) {
132         response_message.set_response_code(VTS_DRIVER_RESPONSE_FAIL);
133       } else {
134         response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
135       }
136       response_message.set_return_value(driver_id);
137       if (VtsSocketSendMessage(response_message)) return true;
138       break;
139     }
140     case GET_STATUS: {
141       int32_t result = command_message.status_type();
142       VtsDriverControlResponseMessage response_message;
143       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
144       response_message.set_return_value(result);
145       if (VtsSocketSendMessage(response_message)) return true;
146       break;
147     }
148     case CALL_FUNCTION: {
149       LOG(INFO) << "Process command CALL_FUNCTION";
150       if (command_message.has_driver_caller_uid()) {
151         setuid(atoi(command_message.driver_caller_uid().c_str()));
152       }
153       const string& result = Call(command_message.arg());
154       VtsDriverControlResponseMessage response_message;
155       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
156       response_message.set_return_message(result);
157       if (VtsSocketSendMessage(response_message)) return true;
158       break;
159     }
160     case VTS_DRIVER_COMMAND_READ_SPECIFICATION: {
161       LOG(INFO) << "Process command READ_SPECIFICATION";
162       const string& result = ReadSpecification(
163           command_message.module_name(), command_message.target_class(),
164           command_message.target_type(), command_message.target_version_major(),
165           command_message.target_version_minor(),
166           command_message.target_package());
167       VtsDriverControlResponseMessage response_message;
168       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
169       response_message.set_return_message(result);
170       if (VtsSocketSendMessage(response_message)) return true;
171       break;
172     }
173     case GET_ATTRIBUTE: {
174       LOG(INFO) << "Process command GET_ATTRIBUTE";
175       const string& result = GetAttribute(command_message.arg());
176       VtsDriverControlResponseMessage response_message;
177       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
178       response_message.set_return_message(result);
179       if (VtsSocketSendMessage(response_message)) return true;
180       break;
181     }
182     case LIST_FUNCTIONS: {
183       LOG(INFO) << "Process command LIST_FUNCTIONS";
184       string result = ListFunctions();
185       VtsDriverControlResponseMessage response_message;
186       if (result.size() > 0) {
187         response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
188         response_message.set_return_message(result.c_str());
189       } else {
190         response_message.set_response_code(VTS_DRIVER_RESPONSE_FAIL);
191       }
192       if (VtsSocketSendMessage(response_message)) return true;
193       break;
194     }
195     case FMQ_OPERATION: {
196       LOG(INFO) << "Process command FMQ_OPERATION";
197       VtsDriverControlResponseMessage response_message;
198       FmqResponseMessage* fmq_response =
199           response_message.mutable_fmq_response();
200       // call method on resource_manager to process the command
201       resource_manager_->ProcessFmqCommand(command_message.fmq_request(),
202                                            fmq_response);
203       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
204       if (VtsSocketSendMessage(response_message)) return true;
205       break;
206     }
207     case HIDL_MEMORY_OPERATION: {
208       LOG(INFO) << "Process command HIDL_MEMORY_OPERATION";
209       VtsDriverControlResponseMessage response_message;
210       HidlMemoryResponseMessage* hidl_memory_response =
211           response_message.mutable_hidl_memory_response();
212       // call method on resource_manager to process the command
213       resource_manager_->ProcessHidlMemoryCommand(
214           command_message.hidl_memory_request(), hidl_memory_response);
215       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
216       if (VtsSocketSendMessage(response_message)) return true;
217       break;
218     }
219     case HIDL_HANDLE_OPERATION: {
220       LOG(INFO) << "Process command HIDL_HANDLE_OPERATION";
221       VtsDriverControlResponseMessage response_message;
222       HidlHandleResponseMessage* hidl_handle_response =
223           response_message.mutable_hidl_handle_response();
224       // call method on resource manager to process the command
225       resource_manager_->ProcessHidlHandleCommand(
226           command_message.hidl_handle_request(), hidl_handle_response);
227       response_message.set_response_code(VTS_DRIVER_RESPONSE_SUCCESS);
228       if (VtsSocketSendMessage(response_message)) return true;
229       break;
230     }
231     default:
232       break;
233   }
234   LOG(ERROR) << "Failed.";
235   return false;
236 }
237 
238 // Starts to run a UNIX socket server (foreground).
StartSocketServer(const string & socket_port_file,VtsHalDriverManager * driver_manager,VtsResourceManager * resource_manager,const char * lib_path)239 int StartSocketServer(const string& socket_port_file,
240                       VtsHalDriverManager* driver_manager,
241                       VtsResourceManager* resource_manager,
242                       const char* lib_path) {
243   int sockfd;
244   socklen_t clilen;
245   struct sockaddr_in cli_addr;
246   struct sockaddr_un serv_addr;
247 
248   sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
249   if (sockfd < 0) {
250     LOG(ERROR) << "Can't open the socket.";
251     return -1;
252   }
253 
254   unlink(socket_port_file.c_str());
255   bzero((char*)&serv_addr, sizeof(serv_addr));
256   serv_addr.sun_family = AF_UNIX;
257   strcpy(serv_addr.sun_path, socket_port_file.c_str());
258 
259   LOG(DEBUG) << "Trying to bind (port file: " << socket_port_file << ")";
260 
261   if (::bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
262     int error_save = errno;
263     LOG(ERROR) << "ERROR binding failed. errno = " << error_save << " "
264                << strerror(error_save);
265     return -1;
266   }
267 
268   listen(sockfd, 5);
269   clilen = sizeof(cli_addr);
270 
271   while (true) {
272     LOG(DEBUG) << "Waiting for a new connection from the agent";
273     int newsockfd = ::accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
274     if (newsockfd < 0) {
275       LOG(ERROR) << "ERROR accept failed.";
276       return -1;
277     }
278 
279     LOG(DEBUG) << "New session";
280     pid_t pid = fork();
281     if (pid == 0) {  // child
282       close(sockfd);
283       LOG(DEBUG) << "Process for an agent - pid = " << getpid();
284       VtsDriverHalSocketServer* server = new VtsDriverHalSocketServer(
285           driver_manager, resource_manager, lib_path);
286       server->SetSockfd(newsockfd);
287       while (server->ProcessOneCommand())
288         ;
289       delete server;
290       exit(0);
291     } else if (pid < 0) {
292       LOG(ERROR) << "Can't fork a child process to handle a session.";
293       return -1;
294     }
295     close(newsockfd);
296   }
297   LOG(ERROR) << "Exiting";
298   return 0;
299 }
300 
301 }  // namespace vts
302 }  // namespace android
303 
304 #endif
305