Home | History | Annotate | Download | only in wificond
      1 /*
      2  * Copyright (C) 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 #include <unistd.h>
     18 #include <sys/capability.h>
     19 
     20 #include <csignal>
     21 #include <memory>
     22 
     23 #include <android-base/logging.h>
     24 #include <android-base/macros.h>
     25 #include <binder/IPCThreadState.h>
     26 #include <binder/IServiceManager.h>
     27 #include <binder/ProcessState.h>
     28 #include <cutils/properties.h>
     29 #include <hidl/HidlTransportSupport.h>
     30 #include <libminijail.h>
     31 #include <utils/String16.h>
     32 #include <wifi_system/interface_tool.h>
     33 
     34 #include "wificond/ipc_constants.h"
     35 #include "wificond/looper_backed_event_loop.h"
     36 #include "wificond/net/netlink_manager.h"
     37 #include "wificond/net/netlink_utils.h"
     38 #include "wificond/scanning/scan_utils.h"
     39 #include "wificond/server.h"
     40 
     41 using android::net::wifi::IWificond;
     42 using android::wifi_system::HostapdManager;
     43 using android::wifi_system::InterfaceTool;
     44 using android::wifi_system::SupplicantManager;
     45 using android::wificond::ipc_constants::kServiceName;
     46 using std::unique_ptr;
     47 
     48 namespace {
     49 
     50 class ScopedSignalHandler final {
     51  public:
     52   ScopedSignalHandler(android::wificond::LooperBackedEventLoop* event_loop) {
     53     if (s_event_loop_ != nullptr) {
     54       LOG(FATAL) << "Only instantiate one signal handler per process!";
     55     }
     56     s_event_loop_ = event_loop;
     57     std::signal(SIGINT, &ScopedSignalHandler::LeaveLoop);
     58     std::signal(SIGTERM, &ScopedSignalHandler::LeaveLoop);
     59   }
     60 
     61   ~ScopedSignalHandler() {
     62     std::signal(SIGINT, SIG_DFL);
     63     std::signal(SIGTERM, SIG_DFL);
     64     s_event_loop_ = nullptr;
     65   }
     66 
     67  private:
     68   static android::wificond::LooperBackedEventLoop* s_event_loop_;
     69   static void LeaveLoop(int signal) {
     70     if (s_event_loop_ != nullptr) {
     71       s_event_loop_->TriggerExit();
     72     }
     73   }
     74 
     75   DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler);
     76 };
     77 
     78 android::wificond::LooperBackedEventLoop*
     79     ScopedSignalHandler::s_event_loop_ = nullptr;
     80 
     81 
     82 // Setup our interface to the Binder driver or die trying.
     83 int SetupBinderOrCrash() {
     84   int binder_fd = -1;
     85   android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
     86   android::IPCThreadState::self()->disableBackgroundScheduling(true);
     87   int err = android::IPCThreadState::self()->setupPolling(&binder_fd);
     88   CHECK_EQ(err, 0) << "Error setting up binder polling: " << strerror(-err);
     89   CHECK_GE(binder_fd, 0) << "Invalid binder FD: " << binder_fd;
     90   return binder_fd;
     91 }
     92 
     93 // Setup our interface to the hw Binder driver or die trying.
     94 int SetupHwBinderOrCrash() {
     95   android::hardware::configureRpcThreadpool(1, true /* callerWillJoin */);
     96   int binder_fd  = android::hardware::setupTransportPolling();
     97   CHECK_GE(binder_fd, 0) << "Invalid hw binder FD: " << binder_fd;
     98   return binder_fd;
     99 }
    100 
    101 void RegisterServiceOrCrash(const android::sp<android::IBinder>& service) {
    102   android::sp<android::IServiceManager> sm = android::defaultServiceManager();
    103   CHECK_EQ(sm != NULL, true) << "Could not obtain IServiceManager";
    104 
    105   CHECK_EQ(sm->addService(android::String16(kServiceName), service),
    106            android::NO_ERROR);
    107 }
    108 
    109 }  // namespace
    110 
    111 void OnBinderReadReady(int fd) {
    112   android::IPCThreadState::self()->handlePolledCommands();
    113 }
    114 
    115 void OnHwBinderReadReady(int fd) {
    116   android::hardware::handleTransportPoll(fd);
    117 }
    118 
    119 int main(int argc, char** argv) {
    120   android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
    121   LOG(INFO) << "wificond is starting up...";
    122 
    123   unique_ptr<android::wificond::LooperBackedEventLoop> event_dispatcher(
    124       new android::wificond::LooperBackedEventLoop());
    125   ScopedSignalHandler scoped_signal_handler(event_dispatcher.get());
    126 
    127   int binder_fd = SetupBinderOrCrash();
    128   CHECK(event_dispatcher->WatchFileDescriptor(
    129       binder_fd,
    130       android::wificond::EventLoop::kModeInput,
    131       &OnBinderReadReady)) << "Failed to watch binder FD";
    132 
    133   int hw_binder_fd = SetupHwBinderOrCrash();
    134   CHECK(event_dispatcher->WatchFileDescriptor(
    135       hw_binder_fd, android::wificond::EventLoop::kModeInput,
    136       &OnHwBinderReadReady)) << "Failed to watch Hw Binder FD";
    137 
    138   android::wificond::NetlinkManager netlink_manager(event_dispatcher.get());
    139   if (!netlink_manager.Start()) {
    140     LOG(ERROR) << "Failed to start netlink manager";
    141   }
    142   android::wificond::NetlinkUtils netlink_utils(&netlink_manager);
    143   android::wificond::ScanUtils scan_utils(&netlink_manager);
    144 
    145   unique_ptr<android::wificond::Server> server(new android::wificond::Server(
    146       unique_ptr<InterfaceTool>(new InterfaceTool),
    147       unique_ptr<SupplicantManager>(new SupplicantManager()),
    148       unique_ptr<HostapdManager>(new HostapdManager()),
    149       &netlink_utils,
    150       &scan_utils));
    151   RegisterServiceOrCrash(server.get());
    152 
    153   event_dispatcher->Poll();
    154   LOG(INFO) << "wificond is about to exit";
    155   return 0;
    156 }
    157