Direct-BT  2.3.1
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 <direct_bt/DirectBT.hpp>
33 
34 namespace direct_bt {
35 
36  /**
37  * Application toolkit providing BT device registration of processed and awaited devices.
38  * The latter on a pattern matching basis, i.e. EUI48Sub or name-sub.
39  */
40  namespace BTDeviceRegistry {
41  /**
42  * Specifies devices queries to act upon.
43  */
44  struct DeviceQuery {
45  /**
46  * DeviceQuery type, i.e. EUI48Sub or a std::string name.
47  */
48  enum class Type : int {
49  /** DeviceQuery type, using a sensor device EUI48Sub. */
50  EUI48SUB,
51  /** DeviceQuery type, using a sensor device std::string name. */
52  NAME
53  };
54 
57  std::string nameSub;
58 
59  DeviceQuery(const EUI48Sub& as) : type(Type::EUI48SUB), addressSub(as), nameSub() {}
60 
61  DeviceQuery(const std::string& ns) : type(Type::NAME), addressSub(EUI48Sub::ANY_DEVICE), nameSub(ns) {}
62 
63  bool isEUI48Sub() const noexcept { return Type::EUI48SUB == type; }
64 
65  std::string toString() const {
66  if( Type::EUI48SUB == type ) {
67  return "[a: "+addressSub.toString()+"]";
68  } else {
69  return "[n: '"+nameSub+"']";
70  }
71  }
72  };
73 
74  void addToWaitForDevices(const std::string& addrOrNameSub) noexcept;
75  bool isWaitingForAnyDevice() noexcept;
76  size_t getWaitForDevicesCount() noexcept;
77  std::string getWaitForDevicesString() noexcept;
78  /**
79  * Returns the reference of the current list of DeviceQuery, not a copy.
80  */
81  jau::darray<DeviceQuery>& getWaitForDevices() noexcept;
82  /**
83  * Clears internal list
84  */
85  void clearWaitForDevices() noexcept;
86 
87  /**
88  * Specifies unique device identities,
89  * using {@link BDAddressAndType} as key.
90  */
91  struct DeviceID {
93  std::string name;
94 
95  DeviceID(const BDAddressAndType& a, const std::string& n) : addressAndType(a), name(n) {}
96  DeviceID() : addressAndType(), name() {}
97 
98  /**
99  * {@inheritDoc}
100  * <p>
101  * Implementation simply returns the BDAddressAndType hash code,
102  * `name` is ignored.
103  * </p>
104  */
105  std::size_t hash_code() const noexcept {
106  return addressAndType.hash_code();
107  }
108 
109  std::string toString() const {
110  return "["+addressAndType.toString()+", '"+name+"']";
111  }
112  };
113  /**
114  * {@inheritDoc}
115  * <p>
116  * Implementation simply tests the {@link BDAddressAndType} fields for equality,
117  * `name` is ignored.
118  * </p>
119  */
120  inline bool operator==(const DeviceID& lhs, const DeviceID& rhs) noexcept {
121  if( &lhs == &rhs ) {
122  return true;
123  }
124  return lhs.addressAndType == rhs.addressAndType;
125  }
126  inline bool operator!=(const DeviceID& lhs, const DeviceID& rhs) noexcept
127  { return !(lhs == rhs); }
128 
129  void addToProcessedDevices(const BDAddressAndType &a, const std::string& n) noexcept;
130  bool isDeviceProcessed(const BDAddressAndType & a) noexcept;
131  size_t getProcessedDeviceCount() noexcept;
132 
133  std::string getProcessedDevicesString() noexcept;
134 
135  /**
136  * Returns a copy of the current collection of processed DeviceID.
137  */
138  jau::darray<DeviceID> getProcessedDevices() noexcept;
139  /**
140  * Clears internal list
141  */
142  void clearProcessedDevices() noexcept;
143 
144  /**
145  * Function for user defined BTDeviceRegistry::DeviceQuery matching criteria and algorithm.
146  * <p>
147  * Return {@code true} if the given {@code address} and/or {@code name} matches
148  * with the BTDeviceRegistry::DeviceQuery::addressSub and/or
149  * BTDeviceRegistry::DeviceQuery::nameSub.
150  * </p>
151  * <p>
152  * Example (lambda):
153  * <pre>
154  * [](const EUI48& a, const std::string& n, const DeviceQuery& q)->bool {
155  * return q.isEUI48Sub() ? a.contains(q.addressSub) : n.find(q.nameSub) != std::string::npos;
156  * });
157  * </pre>
158  * </p>
159  */
160  typedef bool (*DeviceQueryMatchFunc)(const EUI48& address, const std::string& name, const DeviceQuery& q);
161 
162  /**
163  * Returns {@code true} if the given {@code address} and/or {@code name}
164  * matches any of the BTDeviceRegistry::addToWaitForDevices() awaited devices.
165  * <p>
166  * Matching criteria and algorithm is defined by the given BTDeviceRegistry::DeviceQueryMatchFunc.
167  * </p>
168  * @see BTDeviceRegistry::isWaitingForDevice()
169  */
170  bool isWaitingForDevice(const EUI48 &address, const std::string &name, DeviceQueryMatchFunc m) noexcept;
171 
172  /**
173  * Returns {@code true} if the given {@code address} and/or {@code name}
174  * matches any of the BTDeviceRegistry::addToWaitForDevices() awaited devices.
175  * <p>
176  * Matching criteria is either the awaited device's BTDeviceRegistry::DeviceQuery::addressSub
177  * or BTDeviceRegistry::DeviceQuery::nameSub, whichever is set.
178  * </p>
179  * <p>
180  * Matching algorithm is a simple {@code contains} pattern match,
181  * i.e. the given {@code address} or {@code name} contains the corresponding BTDeviceRegistry::DeviceQuery element.
182  * </p>
183  * @see BTDeviceRegistry::isWaitingForDevice()
184  */
185  inline bool isWaitingForDevice(const EUI48 &address, const std::string &name) noexcept {
186  return isWaitingForDevice(address, name, [](const EUI48& a, const std::string& n, const DeviceQuery& q)->bool {
187  return q.isEUI48Sub() ? a.contains(q.addressSub) : n.find(q.nameSub) != std::string::npos;
188  });
189  }
190 
191  /**
192  * Returns {@code true} if all addToWaitForDevices() awaited devices
193  * have been addToProcessedDevices() processed.
194  * <p>
195  * Matching criteria and algorithm is defined by the given BTDeviceRegistry::DeviceQueryMatchFunc.
196  * </p>
197  * @see BTDeviceRegistry::areAllDevicesProcessed()
198  */
200 
201  /**
202  * Returns {@code true} if all addToWaitForDevices() awaited devices
203  * have been addToProcessedDevices() processed.
204  * <p>
205  * Matching criteria is either the awaited device's BTDeviceRegistry::DeviceQuery::addressSub
206  * or BTDeviceRegistry::DeviceQuery::nameSub, whichever is set.
207  * </p>
208  * <p>
209  * Matching algorithm is a simple {@code contains} pattern match,
210  * i.e. the processed BTDeviceRegistry::DeviceID contains one element of BTDeviceRegistry::DeviceQuery.
211  * </p>
212  * @see BTDeviceRegistry::areAllDevicesProcessed()
213  */
214  inline bool areAllDevicesProcessed() noexcept {
215  return areAllDevicesProcessed( [](const EUI48& a, const std::string& n, const DeviceQuery& q)->bool {
216  return q.isEUI48Sub() ? a.contains(q.addressSub) : n.find(q.nameSub) != std::string::npos;
217  });
218  }
219 
220  void addToProcessingDevices(const BDAddressAndType &a, const std::string& n) noexcept;
221  bool removeFromProcessingDevices(const BDAddressAndType &a) noexcept;
222  bool isDeviceProcessing(const BDAddressAndType & a) noexcept;
223  size_t getProcessingDeviceCount() noexcept;
224  /**
225  * Returns a copy of the current collection of processing DeviceID.
226  */
227  jau::darray<DeviceID> getProcessingDevices() noexcept;
228  /**
229  * Clears internal list
230  */
231  void clearProcessingDevices() noexcept;
232  }
233 
234 } // namespace direct_bt
235 
236 // injecting specialization of std::hash to namespace std of our types above
237 namespace std
238 {
239  template<> struct hash<direct_bt::BTDeviceRegistry::DeviceID> {
240  std::size_t operator()(direct_bt::BTDeviceRegistry::DeviceID const& a) const noexcept {
241  return a.hash_code();
242  }
243  };
244 }
245 
246 #endif /* DBT_DEV_ACCOUNTING_HPP_ */
direct_bt::BTDeviceRegistry::getWaitForDevicesString
std::string getWaitForDevicesString() noexcept
Definition: BTDeviceRegistry.cpp:62
DirectBT.hpp
direct_bt::BTDeviceRegistry::areAllDevicesProcessed
bool areAllDevicesProcessed(DeviceQueryMatchFunc m) noexcept
Returns.
Definition: BTDeviceRegistry.cpp:126
direct_bt::BTDeviceRegistry::getProcessedDevicesString
std::string getProcessedDevicesString() noexcept
Definition: BTDeviceRegistry.cpp:92
direct_bt::BDAddressAndType::hash_code
std::size_t hash_code() const noexcept
Implementation uses a lock-free volatile cache.
Definition: BTAddress.hpp:500
direct_bt::BTDeviceRegistry::getProcessedDevices
jau::darray< DeviceID > getProcessedDevices() noexcept
Returns a copy of the current collection of processed DeviceID.
Definition: BTDeviceRegistry.cpp:103
direct_bt::EUI48::contains
bool contains(const EUI48Sub &needle) const noexcept
Definition: BTAddress.hpp:388
direct_bt::EUI48Sub::toString
std::string toString() const noexcept
Returns the EUI48 sub-string representation, less or equal 17 characters representing less or equal 6...
Definition: BTTypes0.cpp:166
direct_bt
Definition: ATTPDUTypes.hpp:171
direct_bt::BTDeviceRegistry::getProcessingDeviceCount
size_t getProcessingDeviceCount() noexcept
Definition: BTDeviceRegistry.cpp:162
direct_bt::BDAddressAndType::toString
std::string toString() const noexcept
Definition: BTTypes0.cpp:333
jau
Definition: basic_algos.hpp:34
direct_bt::BTDeviceRegistry::clearProcessingDevices
void clearProcessingDevices() noexcept
Clears internal list.
Definition: BTDeviceRegistry.cpp:178
direct_bt::BTDeviceRegistry::addToProcessingDevices
void addToProcessingDevices(const BDAddressAndType &a, const std::string &n) noexcept
Definition: BTDeviceRegistry.cpp:145
direct_bt::BTDeviceRegistry::clearProcessedDevices
void clearProcessedDevices() noexcept
Clears internal list.
Definition: BTDeviceRegistry.cpp:115
direct_bt::BTDeviceRegistry::clearWaitForDevices
void clearWaitForDevices() noexcept
Clears internal list.
Definition: BTDeviceRegistry.cpp:76
direct_bt::BTDeviceRegistry::isWaitingForDevice
bool isWaitingForDevice(const EUI48 &address, const std::string &name, DeviceQueryMatchFunc m) noexcept
Returns.
Definition: BTDeviceRegistry.cpp:120
direct_bt::EUI48Sub
A 48 bit EUI-48 sub-identifier, see EUI48.
Definition: BTAddress.hpp:154
direct_bt::BTDeviceRegistry::DeviceQuery::type
Type type
Definition: BTDeviceRegistry.hpp:55
direct_bt::BTDeviceRegistry::DeviceQuery::addressSub
EUI48Sub addressSub
Definition: BTDeviceRegistry.hpp:56
direct_bt::BTDeviceRegistry::DeviceID::DeviceID
DeviceID(const BDAddressAndType &a, const std::string &n)
Definition: BTDeviceRegistry.hpp:95
direct_bt::BTDeviceRegistry::DeviceID::DeviceID
DeviceID()
Definition: BTDeviceRegistry.hpp:96
direct_bt::BTDeviceRegistry::DeviceID::toString
std::string toString() const
Definition: BTDeviceRegistry.hpp:109
direct_bt::BTDeviceRegistry::DeviceQuery::Type::EUI48SUB
@ EUI48SUB
DeviceQuery type, using a sensor device EUI48Sub.
direct_bt::BTDeviceRegistry::DeviceQuery::toString
std::string toString() const
Definition: BTDeviceRegistry.hpp:65
direct_bt::BTDeviceRegistry::addToWaitForDevices
void addToWaitForDevices(const std::string &addrOrNameSub) noexcept
Definition: BTDeviceRegistry.cpp:46
direct_bt::BTDeviceRegistry::removeFromProcessingDevices
bool removeFromProcessingDevices(const BDAddressAndType &a) noexcept
Definition: BTDeviceRegistry.cpp:149
direct_bt::BTDeviceRegistry::DeviceQuery::Type::NAME
@ NAME
DeviceQuery type, using a sensor device std::string name.
direct_bt::BTDeviceRegistry::DeviceQuery::DeviceQuery
DeviceQuery(const EUI48Sub &as)
Definition: BTDeviceRegistry.hpp:59
direct_bt::BTDeviceRegistry::DeviceQuery::isEUI48Sub
bool isEUI48Sub() const noexcept
Definition: BTDeviceRegistry.hpp:63
direct_bt::BTDeviceRegistry::addToProcessedDevices
void addToProcessedDevices(const BDAddressAndType &a, const std::string &n) noexcept
Definition: BTDeviceRegistry.cpp:80
direct_bt::BTDeviceRegistry::isDeviceProcessing
bool isDeviceProcessing(const BDAddressAndType &a) noexcept
Definition: BTDeviceRegistry.cpp:158
direct_bt::BTDeviceRegistry::DeviceQuery::Type
Type
DeviceQuery type, i.e.
Definition: BTDeviceRegistry.hpp:48
std::hash< direct_bt::BTDeviceRegistry::DeviceID >::operator()
std::size_t operator()(direct_bt::BTDeviceRegistry::DeviceID const &a) const noexcept
Definition: BTDeviceRegistry.hpp:240
direct_bt::BTDeviceRegistry::DeviceID
Specifies unique device identities, using BDAddressAndType as key.
Definition: BTDeviceRegistry.hpp:91
direct_bt::BTDeviceRegistry::operator==
bool operator==(const DeviceID &lhs, const DeviceID &rhs) noexcept
Definition: BTDeviceRegistry.hpp:120
direct_bt::BTDeviceRegistry::DeviceID::name
std::string name
Definition: BTDeviceRegistry.hpp:93
direct_bt::EUI48
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition: BTAddress.hpp:388
direct_bt::BTDeviceRegistry::DeviceQuery::DeviceQuery
DeviceQuery(const std::string &ns)
Definition: BTDeviceRegistry.hpp:61
direct_bt::BTDeviceRegistry::getWaitForDevices
jau::darray< DeviceQuery > & getWaitForDevices() noexcept
Returns the reference of the current list of DeviceQuery, not a copy.
Definition: BTDeviceRegistry.cpp:73
direct_bt::EIRDataType::NAME
@ NAME
direct_bt::BTDeviceRegistry::DeviceQuery
Specifies devices queries to act upon.
Definition: BTDeviceRegistry.hpp:44
direct_bt::BTDeviceRegistry::isWaitingForAnyDevice
bool isWaitingForAnyDevice() noexcept
Definition: BTDeviceRegistry.cpp:56
direct_bt::BTDeviceRegistry::getProcessedDeviceCount
size_t getProcessedDeviceCount() noexcept
Definition: BTDeviceRegistry.cpp:88
direct_bt::BTDeviceRegistry::DeviceID::hash_code
std::size_t hash_code() const noexcept
Definition: BTDeviceRegistry.hpp:105
direct_bt::BTDeviceRegistry::operator!=
bool operator!=(const DeviceID &lhs, const DeviceID &rhs) noexcept
Definition: BTDeviceRegistry.hpp:126
direct_bt::BTDeviceRegistry::DeviceID::addressAndType
BDAddressAndType addressAndType
Definition: BTDeviceRegistry.hpp:92
direct_bt::BTDeviceRegistry::isDeviceProcessed
bool isDeviceProcessed(const BDAddressAndType &a) noexcept
Definition: BTDeviceRegistry.cpp:84
direct_bt::BTDeviceRegistry::getWaitForDevicesCount
size_t getWaitForDevicesCount() noexcept
Definition: BTDeviceRegistry.cpp:59
direct_bt::BTDeviceRegistry::DeviceQueryMatchFunc
bool(* DeviceQueryMatchFunc)(const EUI48 &address, const std::string &name, const DeviceQuery &q)
Function for user defined BTDeviceRegistry::DeviceQuery matching criteria and algorithm.
Definition: BTDeviceRegistry.hpp:160
direct_bt::BDAddressAndType
Unique Bluetooth EUI48 address and BDAddressType tuple.
Definition: BTAddress.hpp:417
direct_bt::BTDeviceRegistry::getProcessingDevices
jau::darray< DeviceID > getProcessingDevices() noexcept
Returns a copy of the current collection of processing DeviceID.
Definition: BTDeviceRegistry.cpp:166
direct_bt::BTDeviceRegistry::DeviceQuery::nameSub
std::string nameSub
Definition: BTDeviceRegistry.hpp:57