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