Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
BTDeviceRegistry.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 * Copyright (c) 2020 ZAFENA AB
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef DBT_DEV_ACCOUNTING_HPP_
27#define DBT_DEV_ACCOUNTING_HPP_
28
29#include <string>
30#include <cstdio>
31
32#include "BTTypes0.hpp"
33
34namespace direct_bt {
35
36 /** \addtogroup DBTUserAPI
37 *
38 * @{
39 */
40
41 /**
42 * Application toolkit providing BT device registration of processed and awaited devices.
43 * The latter on a pattern matching basis, i.e. EUI48Sub or name-sub.
44 */
45 namespace BTDeviceRegistry {
46 /**
47 * Specifies devices queries to act upon.
48 */
49 struct DeviceQuery {
50 /**
51 * DeviceQuery type, i.e. EUI48Sub or a std::string name.
52 */
53 enum class Type : int {
54 /** DeviceQuery type, using a sensor device EUI48Sub. */
55 EUI48SUB,
56 /** DeviceQuery type, using a sensor device std::string name. */
57 NAME
58 };
59
62 std::string nameSub;
63
64 DeviceQuery(const EUI48Sub& as) : type(Type::EUI48SUB), addressSub(as), nameSub() {}
65
66 DeviceQuery(std::string ns) : type(Type::NAME), addressSub(EUI48Sub::ANY_DEVICE), nameSub(std::move(ns)) {}
67
68 bool isEUI48Sub() const noexcept { return Type::EUI48SUB == type; }
69
70 std::string toString() const {
71 if( Type::EUI48SUB == type ) {
72 return "[a: "+addressSub.toString()+"]";
73 } else {
74 return "[n: '"+nameSub+"']";
75 }
76 }
77 };
78
79 void addToWaitForDevices(const std::string& addrOrNameSub) noexcept;
80 bool isWaitingForAnyDevice() noexcept;
81 size_t getWaitForDevicesCount() noexcept;
82 std::string getWaitForDevicesString() noexcept;
83 /**
84 * Returns the reference of the current list of DeviceQuery, not a copy.
85 */
86 jau::darray<DeviceQuery>& getWaitForDevices() noexcept;
87 /**
88 * Clears internal list
89 */
90 void clearWaitForDevices() noexcept;
91
92 /**
93 * Specifies unique device identities,
94 * using {@link BDAddressAndType} as key.
95 */
96 struct DeviceID {
98 std::string name;
99
100 DeviceID(BDAddressAndType a, std::string n) : addressAndType(std::move(a)), name(std::move(n)) {}
101 DeviceID() : addressAndType(), name() {}
102
103 /**
104 * {@inheritDoc}
105 * <p>
106 * Implementation simply returns the BDAddressAndType hash code,
107 * `name` is ignored.
108 * </p>
109 */
110 std::size_t hash_code() const noexcept {
111 return addressAndType.hash_code();
112 }
113
114 std::string toString() const {
115 return "["+addressAndType.toString()+", '"+name+"']";
116 }
117 };
118 /**
119 * {@inheritDoc}
120 * <p>
121 * Implementation simply tests the {@link BDAddressAndType} fields for equality,
122 * `name` is ignored.
123 * </p>
124 */
125 inline bool operator==(const DeviceID& lhs, const DeviceID& rhs) noexcept {
126 if( &lhs == &rhs ) {
127 return true;
128 }
129 return lhs.addressAndType == rhs.addressAndType;
130 }
131 inline bool operator!=(const DeviceID& lhs, const DeviceID& rhs) noexcept
132 { return !(lhs == rhs); }
133
134 void addToProcessedDevices(const BDAddressAndType &a, const std::string& n) noexcept;
135 bool isDeviceProcessed(const BDAddressAndType & a) noexcept;
136 size_t getProcessedDeviceCount() noexcept;
137
138 std::string getProcessedDevicesString() noexcept;
139
140 /**
141 * Returns a copy of the current collection of processed DeviceID.
142 */
143 jau::darray<DeviceID> getProcessedDevices() noexcept;
144 /**
145 * Clears internal list
146 */
147 void clearProcessedDevices() noexcept;
148
149 /**
150 * Function for user defined BTDeviceRegistry::DeviceQuery matching criteria and algorithm.
151 * <p>
152 * Return {@code true} if the given {@code address} and/or {@code name} matches
153 * with the BTDeviceRegistry::DeviceQuery::addressSub and/or
154 * BTDeviceRegistry::DeviceQuery::nameSub.
155 * </p>
156 * <p>
157 * Example (lambda):
158 * <pre>
159 * [](const EUI48& a, const std::string& n, const DeviceQuery& q)->bool {
160 * return q.isEUI48Sub() ? a.contains(q.addressSub) : n.find(q.nameSub) != std::string::npos;
161 * });
162 * </pre>
163 * </p>
164 */
165 typedef bool (*DeviceQueryMatchFunc)(const EUI48& address, const std::string& name, const DeviceQuery& q);
166
167 /**
168 * Returns {@code true} if the given {@code address} and/or {@code name}
169 * matches any of the BTDeviceRegistry::addToWaitForDevices() awaited devices.
170 * <p>
171 * Matching criteria and algorithm is defined by the given BTDeviceRegistry::DeviceQueryMatchFunc.
172 * </p>
173 * @see BTDeviceRegistry::isWaitingForDevice()
174 */
175 bool isWaitingForDevice(const EUI48 &address, const std::string &name, DeviceQueryMatchFunc m) noexcept;
176
177 /**
178 * Returns {@code true} if the given {@code address} and/or {@code name}
179 * matches any of the BTDeviceRegistry::addToWaitForDevices() awaited devices.
180 * <p>
181 * Matching criteria is either the awaited device's BTDeviceRegistry::DeviceQuery::addressSub
182 * or BTDeviceRegistry::DeviceQuery::nameSub, whichever is set.
183 * </p>
184 * <p>
185 * Matching algorithm is a simple {@code contains} pattern match,
186 * i.e. the given {@code address} or {@code name} contains the corresponding BTDeviceRegistry::DeviceQuery element.
187 * </p>
188 * @see BTDeviceRegistry::isWaitingForDevice()
189 */
190 inline bool isWaitingForDevice(const EUI48 &address, const std::string &name) noexcept {
191 return isWaitingForDevice(address, name, [](const EUI48& a, const std::string& n, const DeviceQuery& q)->bool {
192 return q.isEUI48Sub() ? a.contains(q.addressSub) : n.find(q.nameSub) != std::string::npos;
193 });
194 }
195
196 /**
197 * Returns {@code true} if all addToWaitForDevices() awaited devices
198 * have been addToProcessedDevices() processed.
199 * <p>
200 * Matching criteria and algorithm is defined by the given BTDeviceRegistry::DeviceQueryMatchFunc.
201 * </p>
202 * @see BTDeviceRegistry::areAllDevicesProcessed()
203 */
205
206 /**
207 * Returns {@code true} if all addToWaitForDevices() awaited devices
208 * have been addToProcessedDevices() processed.
209 * <p>
210 * Matching criteria is either the awaited device's BTDeviceRegistry::DeviceQuery::addressSub
211 * or BTDeviceRegistry::DeviceQuery::nameSub, whichever is set.
212 * </p>
213 * <p>
214 * Matching algorithm is a simple {@code contains} pattern match,
215 * i.e. the processed BTDeviceRegistry::DeviceID contains one element of BTDeviceRegistry::DeviceQuery.
216 * </p>
217 * @see BTDeviceRegistry::areAllDevicesProcessed()
218 */
219 inline bool areAllDevicesProcessed() noexcept {
220 return areAllDevicesProcessed( [](const EUI48& a, const std::string& n, const DeviceQuery& q)->bool {
221 return q.isEUI48Sub() ? a.contains(q.addressSub) : n.find(q.nameSub) != std::string::npos;
222 });
223 }
224 }
225
226 /**@}*/
227
228} // namespace direct_bt
229
230// injecting specialization of std::hash to namespace std of our types above
231namespace std
232{
233 /** \addtogroup DBTUserAPI
234 *
235 * @{
236 */
237 template<> struct hash<direct_bt::BTDeviceRegistry::DeviceID> {
238 std::size_t operator()(direct_bt::BTDeviceRegistry::DeviceID const& a) const noexcept {
239 return a.hash_code();
240 }
241 };
242
243 /**@}*/
244}
245
246#endif /* DBT_DEV_ACCOUNTING_HPP_ */
Unique Bluetooth EUI48 address and BDAddressType tuple.
Definition: BTAddress.hpp:175
std::size_t hash_code() const noexcept
Implementation uses a lock-free volatile cache.
Definition: BTAddress.hpp:319
std::string toString() const noexcept
Definition: BTTypes0.cpp:186
void clearProcessedDevices() noexcept
Clears internal list.
std::string getProcessedDevicesString() noexcept
void addToWaitForDevices(const std::string &addrOrNameSub) noexcept
size_t getProcessedDeviceCount() noexcept
bool operator==(const DeviceID &lhs, const DeviceID &rhs) noexcept
void clearWaitForDevices() noexcept
Clears internal list.
std::string getWaitForDevicesString() noexcept
jau::darray< DeviceID > getProcessedDevices() noexcept
Returns a copy of the current collection of processed DeviceID.
bool isDeviceProcessed(const BDAddressAndType &a) noexcept
bool areAllDevicesProcessed(DeviceQueryMatchFunc m) noexcept
Returns true if all addToWaitForDevices() awaited devices have been addToProcessedDevices() processed...
bool isWaitingForAnyDevice() noexcept
size_t getWaitForDevicesCount() noexcept
jau::darray< DeviceQuery > & getWaitForDevices() noexcept
Returns the reference of the current list of DeviceQuery, not a copy.
void addToProcessedDevices(const BDAddressAndType &a, const std::string &n) noexcept
bool operator!=(const DeviceID &lhs, const DeviceID &rhs) noexcept
bool(* DeviceQueryMatchFunc)(const EUI48 &address, const std::string &name, const DeviceQuery &q)
Function for user defined BTDeviceRegistry::DeviceQuery matching criteria and algorithm.
bool isWaitingForDevice(const EUI48 &address, const std::string &name, DeviceQueryMatchFunc m) noexcept
Returns true if the given address and/or name matches any of the BTDeviceRegistry::addToWaitForDevice...
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
STL namespace.
Specifies unique device identities, using BDAddressAndType as key.
DeviceID(BDAddressAndType a, std::string n)
std::size_t hash_code() const noexcept
Specifies devices queries to act upon.
@ EUI48SUB
DeviceQuery type, using a sensor device EUI48Sub.
A 48 bit EUI-48 sub-identifier, see EUI48.
Definition: eui48.hpp:51
std::string toString() const noexcept
Returns the EUI48 sub-string representation with MSB first (lb_endian::big), less or equal 17 charact...
Definition: eui48.cpp:36
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition: eui48.hpp:324
bool contains(const EUI48Sub &needle) const noexcept
Definition: eui48.hpp:324
std::size_t operator()(direct_bt::BTDeviceRegistry::DeviceID const &a) const noexcept