1 /* 2 * Copyright (C) 2022 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 // Undefine the NAN macro (similar to how it's done in the wifi utils library) 18 // to avoid symbol clashes between the NAN (Not-A-Number) macro in the bionic 19 // library headers, and the NAN (Neighbor-Aware-Networking) enum value in the 20 // WiFi ext interface. 21 #ifdef NAN 22 #undef NAN 23 #endif 24 25 #include <condition_variable> 26 #include <cstdint> 27 #include <mutex> 28 #include <string> 29 #include <thread> 30 31 #include <aidl/android/hardware/wifi/WifiStatusCode.h> 32 #include <aidl/vendor/google/wifi_ext/BnWifiExtChreCallback.h> 33 #include <aidl/vendor/google/wifi_ext/IWifiExt.h> 34 #include <android/binder_manager.h> 35 36 #include "chre_host/log.h" 37 38 namespace android { 39 namespace chre { 40 41 /** 42 * Handles interactions with the Wifi Ext HAL, to issue configuration 43 * requests to enable or disable NAN (Neighbor-Aware Networking) functionality. 44 */ 45 class WifiExtHalHandler { 46 public: 47 using WifiStatusCode = aidl::android::hardware::wifi::WifiStatusCode; 48 using IWifiExt = aidl::vendor::google::wifi_ext::IWifiExt; 49 using BnWifiExtChreNanCallback = 50 aidl::vendor::google::wifi_ext::BnWifiExtChreCallback; 51 using WifiChreNanRttState = 52 aidl::vendor::google::wifi_ext::WifiChreNanRttState; 53 54 ~WifiExtHalHandler(); 55 56 /** 57 * Construct a new Wifi Ext Hal Handler object, initiate a connection to 58 * the Wifi ext HAL service. 59 * 60 * @param statusChangeCallback Callback set by the daemon to be invoked on a 61 * status change to NAN's enablement. 62 */ 63 WifiExtHalHandler(const std::function<void(bool)> &statusChangeCallback); 64 65 /** 66 * Invoked by the CHRE daemon when it receives a request to enable or disable 67 * NAN from CHRE. 68 * 69 * @param enable true if CHRE is requesting NAN to be enabled, false if the 70 * request is for a disable. 71 */ 72 void handleConfigurationRequest(bool enable); 73 74 private: 75 //! CHRE NAN availability status change handler. 76 class WifiExtCallback : public BnWifiExtChreNanCallback { 77 public: WifiExtCallback(std::function<void (bool)> cb)78 WifiExtCallback(std::function<void(bool)> cb) : mCallback(cb) {} 79 onChreNanRttStateChanged(WifiChreNanRttState state)80 ndk::ScopedAStatus onChreNanRttStateChanged(WifiChreNanRttState state) { 81 bool enabled = (state == WifiChreNanRttState::CHRE_AVAILABLE); 82 onStatusChanged(enabled); 83 return ndk::ScopedAStatus::ok(); 84 } 85 onStatusChanged(bool enabled)86 void onStatusChanged(bool enabled) { 87 mCallback(enabled); 88 } 89 90 private: 91 std::function<void(bool)> mCallback; 92 }; 93 94 bool mThreadRunning = true; 95 std::thread mThread; 96 std::mutex mMutex; 97 std::condition_variable mCondVar; 98 99 //! Flag used to indicate the state of the configuration request ('enable' if 100 //! true, 'disable' otherwise) if it has a value. 101 std::optional<bool> mEnableConfig; 102 103 AIBinder_DeathRecipient *mDeathRecipient; 104 std::shared_ptr<IWifiExt> mService; 105 std::shared_ptr<WifiExtCallback> mCallback; 106 107 /** 108 * Entry point for the thread that handles all interactions with the WiFi ext 109 * HAL. This is required since a connection initiation can potentially block 110 * indefinitely. 111 */ 112 void wifiExtHandlerThreadEntry(); 113 114 /** 115 * Notifies the WifiExtHalHandler processing thread of a daemon shutdown. 116 */ 117 void notifyThreadToExit(); 118 119 /** 120 * Checks for a valid connection to the Wifi ext HAL service, reconnects if 121 * not already connected. 122 * 123 * @return true if connected or upon successful reconnection, false 124 * otherwise. 125 */ 126 bool checkWifiExtHalConnected(); 127 128 /** 129 * Invoked by the HAL service death callback. 130 */ 131 static void onWifiExtHalServiceDeath(void *cookie); 132 133 /** 134 * Dispatch a configuration request to the WiFi Ext HAL. 135 * 136 * @param enable true if the request is to enable NAN, false if 137 * to disable. 138 */ 139 void dispatchConfigurationRequest(bool enable); 140 }; 141 142 } // namespace chre 143 } // namespace android 144