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