1/* 2 * Copyright (C) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef BLUETOOTH_OBSERVER_MAP_H 17#define BLUETOOTH_OBSERVER_MAP_H 18 19#include <functional> 20#include <map> 21#include <memory> 22#include <mutex> 23 24template <typename T> 25class BluetoothObserverMap final { 26public: 27 BluetoothObserverMap() = default; 28 ~BluetoothObserverMap(); 29 30 bool Register(int handle, T observer); 31 bool Deregister(T observer); 32 33 void ForEach(const std::function<void(uint8_t, T)> &observer, int handle); 34 35 uint8_t GetAdvertiserHandle(T observer); 36 T PopAdvertiserObserver(uint8_t advHandle); 37 T GetAdvertiserObserver(uint8_t advHandle); 38 bool IsExistAdvertiserCallback(T observer, int &handle); 39 void Clear(void); 40 41private: 42 std::mutex lock_; 43 std::map<int, T> observers_; 44 45 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothObserverMap); 46}; 47 48template<typename T> 49void BluetoothObserverMap<T>::Clear(void) 50{ 51 std::lock_guard<std::mutex> lock(lock_); 52 observers_.clear(); 53} 54 55template<typename T> 56BluetoothObserverMap<T>::~BluetoothObserverMap() 57{ 58 std::lock_guard<std::mutex> lock(lock_); 59 observers_.clear(); 60} 61 62template<typename T> 63bool BluetoothObserverMap<T>::Register(int handle, T observer) 64{ 65 std::lock_guard<std::mutex> lock(lock_); 66 67 auto it = observers_.begin(); 68 for (; it != observers_.end();) { 69 if (it->first == handle) { 70 observers_.erase(it++); 71 observers_.insert(std::make_pair(handle, observer)); 72 return true; 73 } else { 74 ++it; 75 } 76 } 77 if (it == observers_.end()) { 78 observers_.insert(std::make_pair(handle, observer)); 79 } 80 return true; 81} 82 83template<typename T> 84bool BluetoothObserverMap<T>::Deregister(T observer) 85{ 86 std::lock_guard<std::mutex> lock(lock_); 87 auto it = observers_.begin(); 88 for (; it != observers_.end();) { 89 if (it->second == observer) { 90 observers_.erase(it++); 91 return true; 92 } else { 93 ++it; 94 } 95 } 96 97 return false; 98} 99 100template<typename T> 101void BluetoothObserverMap<T>::ForEach(const std::function<void(uint8_t, T)> &observer, int handle) 102{ 103 std::lock_guard<std::mutex> lock(lock_); 104 for (const auto &it : observers_) { 105 if (handle == it.first) { 106 observer(it.first, it.second); 107 } 108 } 109} 110 111template<typename T> 112uint8_t BluetoothObserverMap<T>::GetAdvertiserHandle(T observer) 113{ 114 std::lock_guard<std::mutex> lock(lock_); 115 uint8_t advHandle = OHOS::bluetooth::BLE_INVALID_ADVERTISING_HANDLE; 116 if (observer == nullptr) { 117 return advHandle; 118 } 119 120 auto it = observers_.begin(); 121 for (; it != observers_.end(); it++) { 122 if (it->second == observer) { 123 advHandle = it->first; 124 break; 125 } 126 } 127 128 return advHandle; 129} 130 131template<typename T> 132T BluetoothObserverMap<T>::PopAdvertiserObserver(uint8_t advHandle) 133{ 134 std::lock_guard<std::mutex> lock(lock_); 135 T t = nullptr; 136 auto it = observers_.begin(); 137 for (; it != observers_.end(); it++) { 138 if (it->first == advHandle) { 139 t = it->second; 140 observers_.erase(it++); 141 break; 142 } 143 } 144 return t; 145} 146 147template<typename T> 148T BluetoothObserverMap<T>::GetAdvertiserObserver(uint8_t advHandle) 149{ 150 std::lock_guard<std::mutex> lock(lock_); 151 auto it = observers_.begin(); 152 for (; it != observers_.end(); it++) { 153 if (it->first == advHandle) { 154 return it->second; 155 } 156 } 157 158 return nullptr; 159} 160 161template<typename T> 162bool BluetoothObserverMap<T>::IsExistAdvertiserCallback(T observer, int &handle) 163{ 164 bool isExtist = false; 165 if (observer == nullptr) { 166 return isExtist; 167 } 168 169 std::lock_guard<std::mutex> lock(lock_); 170 auto it = observers_.begin(); 171 for (; it != observers_.end(); it++) { 172 if (it->second == observer) { 173 handle = it->first; 174 isExtist = true; 175 break; 176 } 177 } 178 179 return isExtist; 180} 181 182#endif // BLUETOOTH_OBSERVER_LIST_H