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
24 template <typename T>
25 class BluetoothObserverMap final {
26 public:
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 std::vector<T> GetAdvertiserObservers();
39 bool IsExistAdvertiserCallback(T observer, int &handle);
40 void Clear(void);
41
42 private:
43 std::mutex lock_;
44 std::map<int, T> observers_;
45
46 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothObserverMap);
47 };
48
49 template<typename T>
Clear(void)50 void BluetoothObserverMap<T>::Clear(void)
51 {
52 std::lock_guard<std::mutex> lock(lock_);
53 observers_.clear();
54 }
55
56 template<typename T>
~BluetoothObserverMap()57 BluetoothObserverMap<T>::~BluetoothObserverMap()
58 {
59 std::lock_guard<std::mutex> lock(lock_);
60 observers_.clear();
61 }
62
63 template<typename T>
Register(int handle,T observer)64 bool BluetoothObserverMap<T>::Register(int handle, T observer)
65 {
66 std::lock_guard<std::mutex> lock(lock_);
67
68 auto it = observers_.begin();
69 for (; it != observers_.end();) {
70 if (it->first == handle) {
71 observers_.erase(it++);
72 observers_.insert(std::make_pair(handle, observer));
73 return true;
74 } else {
75 ++it;
76 }
77 }
78 if (it == observers_.end()) {
79 observers_.insert(std::make_pair(handle, observer));
80 }
81 return true;
82 }
83
84 template<typename T>
Deregister(T observer)85 bool BluetoothObserverMap<T>::Deregister(T observer)
86 {
87 std::lock_guard<std::mutex> lock(lock_);
88 auto it = observers_.begin();
89 for (; it != observers_.end();) {
90 if (it->second == observer) {
91 observers_.erase(it++);
92 return true;
93 } else {
94 ++it;
95 }
96 }
97
98 return false;
99 }
100
101 template<typename T>
ForEach(const std::function<void (uint8_t,T)> & observer,int handle)102 void BluetoothObserverMap<T>::ForEach(const std::function<void(uint8_t, T)> &observer, int handle)
103 {
104 std::lock_guard<std::mutex> lock(lock_);
105 for (const auto &it : observers_) {
106 if (handle == it.first) {
107 observer(it.first, it.second);
108 }
109 }
110 }
111
112 template<typename T>
GetAdvertiserHandle(T observer)113 uint8_t BluetoothObserverMap<T>::GetAdvertiserHandle(T observer)
114 {
115 std::lock_guard<std::mutex> lock(lock_);
116 uint8_t advHandle = OHOS::bluetooth::BLE_INVALID_ADVERTISING_HANDLE;
117 if (observer == nullptr) {
118 return advHandle;
119 }
120
121 auto it = observers_.begin();
122 for (; it != observers_.end(); it++) {
123 if (it->second == observer) {
124 advHandle = it->first;
125 break;
126 }
127 }
128
129 return advHandle;
130 }
131
132 template<typename T>
PopAdvertiserObserver(uint8_t advHandle)133 T BluetoothObserverMap<T>::PopAdvertiserObserver(uint8_t advHandle)
134 {
135 std::lock_guard<std::mutex> lock(lock_);
136 T t = nullptr;
137 auto it = observers_.begin();
138 for (; it != observers_.end(); it++) {
139 if (it->first == advHandle) {
140 t = it->second;
141 observers_.erase(it++);
142 break;
143 }
144 }
145 return t;
146 }
147
148 template<typename T>
GetAdvertiserObserver(uint8_t advHandle)149 T BluetoothObserverMap<T>::GetAdvertiserObserver(uint8_t advHandle)
150 {
151 std::lock_guard<std::mutex> lock(lock_);
152 auto it = observers_.begin();
153 for (; it != observers_.end(); it++) {
154 if (it->first == advHandle) {
155 return it->second;
156 }
157 }
158
159 return nullptr;
160 }
161
162 template<typename T>
GetAdvertiserObservers()163 std::vector<T> BluetoothObserverMap<T>::GetAdvertiserObservers()
164 {
165 std::lock_guard<std::mutex> lock(lock_);
166 std::vector<T> values;
167 auto it = observers_.begin();
168 for (; it != observers_.end(); it++) {
169 values.push_back(it->second);
170 }
171 return values;
172 }
173
174 template<typename T>
IsExistAdvertiserCallback(T observer,int & handle)175 bool BluetoothObserverMap<T>::IsExistAdvertiserCallback(T observer, int &handle)
176 {
177 bool isExtist = false;
178 if (observer == nullptr) {
179 return isExtist;
180 }
181
182 std::lock_guard<std::mutex> lock(lock_);
183 auto it = observers_.begin();
184 for (; it != observers_.end(); it++) {
185 if (it->second == observer) {
186 handle = it->first;
187 isExtist = true;
188 break;
189 }
190 }
191
192 return isExtist;
193 }
194
195 #endif // BLUETOOTH_OBSERVER_LIST_H