/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "wificond/ipc_constants.h" #include "wificond/looper_backed_event_loop.h" #include "wificond/net/netlink_manager.h" #include "wificond/net/netlink_utils.h" #include "wificond/scanning/scan_utils.h" #include "wificond/server.h" #include "wifi_keystore_hal_connector.h" using android::net::wifi::nl80211::IWificond; using android::wifi_system::InterfaceTool; using android::wificond::ipc_constants::kServiceName; using android::wificond::WifiKeystoreHalConnector; using std::unique_ptr; namespace { class ScopedSignalHandler final { public: ScopedSignalHandler(android::wificond::LooperBackedEventLoop* event_loop) { if (s_event_loop_ != nullptr) { LOG(FATAL) << "Only instantiate one signal handler per process!"; } s_event_loop_ = event_loop; std::signal(SIGINT, &ScopedSignalHandler::LeaveLoop); std::signal(SIGTERM, &ScopedSignalHandler::LeaveLoop); } ~ScopedSignalHandler() { std::signal(SIGINT, SIG_DFL); std::signal(SIGTERM, SIG_DFL); s_event_loop_ = nullptr; } private: static android::wificond::LooperBackedEventLoop* s_event_loop_; static void LeaveLoop(int signal) { if (s_event_loop_ != nullptr) { s_event_loop_->TriggerExit(); } } DISALLOW_COPY_AND_ASSIGN(ScopedSignalHandler); }; android::wificond::LooperBackedEventLoop* ScopedSignalHandler::s_event_loop_ = nullptr; // Setup our interface to the Binder driver or die trying. int SetupBinderOrCrash() { int binder_fd = -1; android::ProcessState::self()->setThreadPoolMaxThreadCount(0); android::IPCThreadState::self()->disableBackgroundScheduling(true); int err = android::IPCThreadState::self()->setupPolling(&binder_fd); CHECK_EQ(err, 0) << "Error setting up binder polling: " << strerror(-err); CHECK_GE(binder_fd, 0) << "Invalid binder FD: " << binder_fd; return binder_fd; } void RegisterServiceOrCrash(const android::sp& service) { android::sp sm = android::defaultServiceManager(); CHECK_EQ(sm != NULL, true) << "Could not obtain IServiceManager"; CHECK_EQ(sm->addService(android::String16(kServiceName), service), android::NO_ERROR); } } // namespace void OnBinderReadReady(int fd) { android::IPCThreadState::self()->handlePolledCommands(); } int main(int argc, char** argv) { android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM)); LOG(INFO) << "wificond is starting up..."; unique_ptr event_dispatcher( new android::wificond::LooperBackedEventLoop()); ScopedSignalHandler scoped_signal_handler(event_dispatcher.get()); int binder_fd = SetupBinderOrCrash(); CHECK(event_dispatcher->WatchFileDescriptor( binder_fd, android::wificond::EventLoop::kModeInput, &OnBinderReadReady)) << "Failed to watch binder FD"; android::wificond::NetlinkManager netlink_manager(event_dispatcher.get()); if (!netlink_manager.Start()) { LOG(ERROR) << "Failed to start netlink manager"; } android::wificond::NetlinkUtils netlink_utils(&netlink_manager); android::wificond::ScanUtils scan_utils(&netlink_manager); android::sp server(new android::wificond::Server( unique_ptr(new InterfaceTool), &netlink_utils, &scan_utils)); RegisterServiceOrCrash(server); WifiKeystoreHalConnector keystore_connector; keystore_connector.start(); event_dispatcher->Poll(); LOG(INFO) << "wificond is about to exit"; return 0; }