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