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 bool IsExistAdvertiserCallback(T observer, int &handle);
39 void Clear(void);
40
41 private:
42 std::mutex lock_;
43 std::map<int, T> observers_;
44
45 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothObserverMap);
46 };
47
48 template<typename T>
Clear(void)49 void BluetoothObserverMap<T>::Clear(void)
50 {
51 std::lock_guard<std::mutex> lock(lock_);
52 observers_.clear();
53 }
54
55 template<typename T>
~BluetoothObserverMap()56 BluetoothObserverMap<T>::~BluetoothObserverMap()
57 {
58 std::lock_guard<std::mutex> lock(lock_);
59 observers_.clear();
60 }
61
62 template<typename T>
Register(int handle,T observer)63 bool 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
83 template<typename T>
Deregister(T observer)84 bool 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
100 template<typename T>
ForEach(const std::function<void (uint8_t,T)> & observer,int handle)101 void 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
111 template<typename T>
GetAdvertiserHandle(T observer)112 uint8_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
131 template<typename T>
PopAdvertiserObserver(uint8_t advHandle)132 T 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
147 template<typename T>
GetAdvertiserObserver(uint8_t advHandle)148 T 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
161 template<typename T>
IsExistAdvertiserCallback(T observer,int & handle)162 bool 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