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 <thread> 29 30 #include <vendor/google/wifi_ext/1.3/IWifiExt.h> 31 #include <vendor/google/wifi_ext/1.3/IWifiExtChreCallback.h> 32 33 #include "chre_host/log.h" 34 35 namespace android { 36 namespace chre { 37 38 /** 39 * Handles interactions with the Wifi Ext HAL, to issue configuration 40 * requests to enable or disable NAN (Neighbor-Aware Networking) functionality. 41 */ 42 class WifiExtHalHandler { 43 public: 44 using hidl_death_recipient = hardware::hidl_death_recipient; 45 using WifiStatus = hardware::wifi::V1_0::WifiStatus; 46 using WifiStatusCode = hardware::wifi::V1_0::WifiStatusCode; 47 using IBase = hidl::base::V1_0::IBase; 48 using IWifiExt = ::vendor::google::wifi_ext::V1_3::IWifiExt; 49 using IWifiExtChreNanCallback = 50 ::vendor::google::wifi_ext::V1_3::IWifiExtChreCallback; 51 using WifiChreNanRttState = 52 ::vendor::google::wifi_ext::V1_3::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 IWifiExtChreNanCallback { 77 public: WifiExtCallback(std::function<void (bool)> cb)78 WifiExtCallback(std::function<void(bool)> cb) : mCallback(cb) {} 79 onChreNanRttStateChanged(WifiChreNanRttState state)80 hardware::Return<void> onChreNanRttStateChanged(WifiChreNanRttState state) { 81 bool enabled = (state == WifiChreNanRttState::CHRE_AVAILABLE); 82 onStatusChanged(enabled); 83 return hardware::Void(); 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 //! Handler for when a connected Wifi ext HAL service dies. 95 class WifiExtHalDeathRecipient : public hidl_death_recipient { 96 public: 97 WifiExtHalDeathRecipient() = delete; WifiExtHalDeathRecipient(std::function<void ()> cb)98 explicit WifiExtHalDeathRecipient(std::function<void()> cb) 99 : mCallback(cb) {} 100 serviceDied(uint64_t,const wp<IBase> &)101 virtual void serviceDied(uint64_t /*cookie*/, 102 const wp<IBase> & /*who*/) override { 103 mCallback(); 104 } 105 106 private: 107 std::function<void()> mCallback; 108 }; 109 110 bool mThreadRunning = true; 111 std::thread mThread; 112 std::mutex mMutex; 113 std::condition_variable mCondVar; 114 115 //! Flag used to indicate the state of the configuration request ('enable' if 116 //! true, 'disable' otherwise) if it has a value. 117 std::optional<bool> mEnableConfig; 118 119 sp<WifiExtHalDeathRecipient> mDeathRecipient; 120 sp<IWifiExt> mService; 121 sp<WifiExtCallback> mCallback; 122 123 /** 124 * Entry point for the thread that handles all interactions with the WiFi ext 125 * HAL. This is required since a connection initiation can potentially block 126 * indefinitely. 127 */ 128 void wifiExtHandlerThreadEntry(); 129 130 /** 131 * Notifies the WifiExtHalHandler processing thread of a daemon shutdown. 132 */ 133 void notifyThreadToExit(); 134 135 /** 136 * Checks for a valid connection to the Wifi ext HAL service, reconnects if 137 * not already connected. 138 * 139 * @return true if connected or upon successful reconnection, false 140 * otherwise. 141 */ 142 bool checkWifiExtHalConnected(); 143 144 /** 145 * Invoked by the HAL service death callback. 146 */ 147 void onWifiExtHalServiceDeath(); 148 149 /** 150 * Dispatch a configuration request to the WiFi Ext HAL. 151 * 152 * @param enable true if the request is to enable NAN, false if 153 * to disable. 154 */ 155 void dispatchConfigurationRequest(bool enable); 156 }; 157 158 } // namespace chre 159 } // namespace android