BlueToe
an alternative GATT/BLE implementation
Loading...
Searching...
No Matches
white_list.hpp
1#ifndef BLUETOE_LINK_LAYER_WHITE_LIST_HPP
2#define BLUETOE_LINK_LAYER_WHITE_LIST_HPP
3
4#include <bluetoe/address.hpp>
5#include <bluetoe/ll_meta_types.hpp>
6
7#include <iterator>
8#include <algorithm>
9
10namespace bluetoe {
11namespace link_layer {
12
13 namespace details {
14 struct white_list_meta_type {};
15
16 template < std::size_t RequiredSize, bool SoftwareRequired, typename Radio, typename LinkLayer >
17 class white_list_implementation;
18 }
19
29 template < std::size_t Size = 8 >
31 {
32 public:
34 // this functions are purly for documentation purpose, the used implementations is in details::white_list_implementation
40 static constexpr std::size_t maximum_white_list_entries = Size;
41
50 bool add_to_white_list( const device_address& addr );
51
59
63 bool is_in_white_list( const device_address& addr ) const;
64
69 std::size_t white_list_free_size() const;
70
75
89
94
107 void scan_request_filter( bool b );
108
113
118
122 bool is_scan_request_in_filter( const device_address& addr ) const;
123
125 struct meta_type :
126 details::white_list_meta_type,
127 details::valid_link_layer_option_meta_type {};
128
129 template < class Radio, class LinkLayer >
130 struct impl :
131 details::white_list_implementation<
132 Size,
133 ( Size > Radio::radio_maximum_white_list_entries ),
134 Radio,
135 LinkLayer
136 >
137 {
138 };
140 };
141
149 template < class Radio, class LinkLayer >
150 struct impl {
151 bool is_connection_request_in_filter( const device_address& ) const
152 {
153 return true;
154 }
155
156 bool is_scan_request_in_filter( const device_address& ) const
157 {
158 return true;
159 }
160 };
161
162 struct meta_type :
163 details::white_list_meta_type,
164 details::valid_link_layer_option_meta_type {};
166 };
167
168 namespace details {
169
173 template < std::size_t Size, typename Radio, typename LinkLayer >
174 class white_list_implementation< Size, true, Radio, LinkLayer >
175 {
176 public:
177 static constexpr std::size_t maximum_white_list_entries = Size;
178
179 white_list_implementation()
180 : active_( false )
181 , free_size_( Size )
182 , connection_filter_( false )
183 , scan_filter_( false )
184 {
185 }
186
187 std::size_t white_list_free_size() const
188 {
189 return free_size_;
190 }
191
192 void clear_white_list()
193 {
194 free_size_ = Size;
195 }
196
197 bool add_to_white_list( const device_address& addr )
198 {
199 if ( is_in_white_list( addr ) )
200 return true;
201
202 if ( free_size_ == 0 )
203 return false;
204
205 addresses_[ Size - free_size_ ] = addr;
206 --free_size_;
207 return true;
208 }
209
210 bool is_in_white_list( const device_address& addr ) const
211 {
212 const auto end = std::begin( addresses_ ) + ( Size - free_size_ );
213 return std::find( std::begin( addresses_ ), end, addr ) != end;
214 }
215
216 bool remove_from_white_list( const device_address& addr )
217 {
218 const auto end = std::begin( addresses_ ) + ( Size - free_size_ );
219 const auto pos = std::find( std::begin( addresses_ ), end, addr );
220
221 if ( pos == end )
222 return false;
223
224 *pos = *( end - 1 );
225 ++free_size_;
226
227 return true;
228 }
229
230 void connection_request_filter( bool b )
231 {
232 connection_filter_ = b;
233 }
234
235 bool connection_request_filter() const
236 {
237 return connection_filter_;
238 }
239
240 void scan_request_filter( bool b )
241 {
242 scan_filter_ = b;
243 }
244
245 bool scan_request_filter() const
246 {
247 return scan_filter_;
248 }
249
250 bool is_connection_request_in_filter( const device_address& addr ) const
251 {
252 return !connection_filter_ || is_in_white_list( addr );
253 }
254
255 bool is_scan_request_in_filter( const device_address& addr ) const
256 {
257 return !scan_filter_ || is_in_white_list( addr );
258 }
259
260 private:
261 bool active_;
262 std::size_t free_size_;
263 device_address addresses_[ Size ];
264 bool connection_filter_;
265 bool scan_filter_;
266 };
267
271 template < std::size_t Size, typename Radio, typename LinkLayer >
272 class white_list_implementation< Size, false, Radio, LinkLayer >
273 {
274 public:
275 static constexpr std::size_t maximum_white_list_entries = Size;
276
277 std::size_t white_list_free_size() const
278 {
279 return this_to_radio().radio_white_list_free_size();
280 }
281
282 void clear_white_list()
283 {
284 this_to_radio().radio_clear_white_list();
285 }
286
287 bool add_to_white_list( const device_address& addr )
288 {
289 return this_to_radio().radio_add_to_white_list( addr );
290 }
291
292 bool is_in_white_list( const device_address& addr ) const
293 {
294 return this_to_radio().radio_is_in_white_list( addr );
295 }
296
297 bool remove_from_white_list( const device_address& addr )
298 {
299 return this_to_radio().radio_remove_from_white_list( addr );
300 }
301
302 void connection_request_filter( bool b )
303 {
304 this_to_radio().radio_connection_request_filter( b );
305 }
306
307 bool connection_request_filter() const
308 {
309 return this_to_radio().radio_connection_request_filter();
310 }
311
312 void scan_request_filter( bool b )
313 {
314 this_to_radio().radio_scan_request_filter( b );
315 }
316
317 bool scan_request_filter() const
318 {
319 return this_to_radio().radio_scan_request_filter();
320 }
321
322 bool is_connection_request_in_filter( const device_address& addr ) const
323 {
324 return this_to_radio().radio_is_connection_request_in_filter( addr );
325 }
326
327 bool is_scan_request_in_filter( const device_address& addr ) const
328 {
329 return this_to_radio().radio_is_scan_request_in_filter( addr );
330 }
331 private:
332 Radio& this_to_radio()
333 {
334 return static_cast< Radio& >( static_cast< LinkLayer& >( *this ) );
335 }
336
337 const Radio& this_to_radio() const
338 {
339 return static_cast< const Radio& >( static_cast< const LinkLayer& >( *this ) );
340 }
341 };
342 }
343}
344}
345#endif