OSDN Git Service

Use mockable supplicant delegate
[android-x86/system-connectivity-wificond.git] / main.cpp
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 <private/android_filesystem_config.h>
31 #include <utils/String16.h>
32 #include <wifi_hal/driver_tool.h>
33 #include <wifi_system/hal_tool.h>
34 #include <wifi_system/interface_tool.h>
35
36 #include "wificond/ipc_constants.h"
37 #include "wificond/looper_backed_event_loop.h"
38 #include "wificond/net/netlink_manager.h"
39 #include "wificond/net/netlink_utils.h"
40 #include "wificond/scanning/scan_utils.h"
41 #include "wificond/server.h"
42
43 using android::net::wifi::IWificond;
44 using android::wifi_hal::DriverTool;
45 using android::wifi_system::HalTool;
46 using android::wifi_system::HostapdManager;
47 using android::wifi_system::InterfaceTool;
48 using android::wifi_system::SupplicantManager;
49 using android::wificond::ipc_constants::kDevModePropertyKey;
50 using android::wificond::ipc_constants::kDevModeServiceName;
51 using android::wificond::ipc_constants::kServiceName;
52 using std::unique_ptr;
53
54 namespace {
55
56 class ScopedSignalHandler final {
57  public:
58   ScopedSignalHandler(android::wificond::LooperBackedEventLoop* event_loop) {
59     if (s_event_loop_ != nullptr) {
60       LOG(FATAL) << "Only instantiate one signal handler per process!";
61     }
62     s_event_loop_ = event_loop;
63     std::signal(SIGINT, &ScopedSignalHandler::LeaveLoop);
64     std::signal(SIGTERM, &ScopedSignalHandler::LeaveLoop);
65   }
66
67   ~ScopedSignalHandler() {
68     std::signal(SIGINT, SIG_DFL);
69     std::signal(SIGTERM, SIG_DFL);
70     s_event_loop_ = nullptr;
71   }
72
73  private:
74   static android::wificond::LooperBackedEventLoop* s_event_loop_;
75   static void LeaveLoop(int signal) {
76     if (s_event_loop_ != nullptr) {
77       s_event_loop_->TriggerExit();
78     }
79   }
80
81   DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler);
82 };
83
84 android::wificond::LooperBackedEventLoop*
85     ScopedSignalHandler::s_event_loop_ = nullptr;
86
87
88 // Setup our interface to the Binder driver or die trying.
89 int SetupBinderOrCrash() {
90   int binder_fd = -1;
91   android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
92   android::IPCThreadState::self()->disableBackgroundScheduling(true);
93   int err = android::IPCThreadState::self()->setupPolling(&binder_fd);
94   CHECK_EQ(err, 0) << "Error setting up binder polling: " << strerror(-err);
95   CHECK_GE(binder_fd, 0) << "Invalid binder FD: " << binder_fd;
96   return binder_fd;
97 }
98
99 void RegisterServiceOrCrash(const android::sp<android::IBinder>& service) {
100   android::sp<android::IServiceManager> sm = android::defaultServiceManager();
101   CHECK_EQ(sm != NULL, true) << "Could not obtain IServiceManager";
102
103   const int8_t dev_mode_on = property_get_bool(kDevModePropertyKey, 0);
104   const char* service_name = (dev_mode_on) ? kDevModeServiceName : kServiceName;
105   CHECK_EQ(sm->addService(android::String16(service_name), service),
106            android::NO_ERROR);
107 }
108
109 void DoPrivilegedSetupOrCrash() {
110   // take ownership of the magic firmware change path
111   CHECK(chown(DriverTool::kFirmwareReloadPath, AID_WIFI, AID_WIFI) == 0)
112       << "Error changing ownership of '" << DriverTool::kFirmwareReloadPath
113       << "' to wifi:wifi, (" << strerror(errno) << ")";
114 }
115
116 void DropPrivilegesOrCrash() {
117   minijail* j = minijail_new();
118   CHECK(minijail_change_user(j, "wifi") == 0);
119   CHECK(minijail_change_group(j, "wifi") == 0);
120   minijail_use_caps(j,
121                     CAP_TO_MASK(CAP_NET_ADMIN) |
122                     CAP_TO_MASK(CAP_NET_RAW));
123   minijail_enter(j);
124   minijail_destroy(j);
125 }
126
127 }  // namespace
128
129 void OnBinderReadReady(int fd) {
130   android::IPCThreadState::self()->handlePolledCommands();
131 }
132
133 int main(int argc, char** argv) {
134   android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
135   LOG(INFO) << "wificond is starting up...";
136
137   DoPrivilegedSetupOrCrash();
138   DropPrivilegesOrCrash();
139
140   unique_ptr<android::wificond::LooperBackedEventLoop> event_dispatcher(
141       new android::wificond::LooperBackedEventLoop());
142   ScopedSignalHandler scoped_signal_handler(event_dispatcher.get());
143
144   int binder_fd = SetupBinderOrCrash();
145   CHECK(event_dispatcher->WatchFileDescriptor(
146       binder_fd,
147       android::wificond::EventLoop::kModeInput,
148       &OnBinderReadReady)) << "Failed to watch binder FD";
149
150   android::wificond::NetlinkManager netlink_manager(event_dispatcher.get());
151   CHECK(netlink_manager.Start()) << "Failed to start netlink manager";
152   android::wificond::NetlinkUtils netlink_utils(&netlink_manager);
153   android::wificond::ScanUtils scan_utils(&netlink_manager);
154
155   unique_ptr<android::wificond::Server> server(new android::wificond::Server(
156       unique_ptr<HalTool>(new HalTool),
157       unique_ptr<InterfaceTool>(new InterfaceTool),
158       unique_ptr<DriverTool>(new DriverTool),
159       unique_ptr<SupplicantManager>(new SupplicantManager()),
160       unique_ptr<HostapdManager>(new HostapdManager()),
161       &netlink_utils,
162       &scan_utils));
163   RegisterServiceOrCrash(server.get());
164
165   event_dispatcher->Poll();
166   LOG(INFO) << "wificond is about to exit";
167   return 0;
168 }