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