Home | History | Annotate | Download | only in server
      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