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