Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
BTDeviceRegistry.cpp
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 #include "BTDeviceRegistry.hpp"
27 
28 #include <jau/cpp_lang_util.hpp>
29 #include <jau/basic_algos.hpp>
30 #include <jau/darray.hpp>
31 
32 #include <unordered_set>
33 #include <unordered_map>
34 
35 using namespace direct_bt;
36 
39 
40  static std::unordered_set<DeviceID> devicesInProcessing;
41  static std::recursive_mutex mtx_devicesProcessing;
42 
43  static std::unordered_set<DeviceID> devicesProcessed;
44  static std::recursive_mutex mtx_devicesProcessed;
45 
46  void addToWaitForDevices(const std::string& addrOrNameSub) noexcept {
47  EUI48Sub addr1;
48  std::string errmsg;
49  if( EUI48Sub::scanEUI48Sub(addrOrNameSub, addr1, errmsg) ) {
50  waitForDevices.emplace_back( addr1 );
51  } else {
52  addr1.clear();
53  waitForDevices.emplace_back( addrOrNameSub );
54  }
55  }
56  bool isWaitingForAnyDevice() noexcept {
57  return !waitForDevices.empty();
58  }
59  size_t getWaitForDevicesCount() noexcept {
60  return waitForDevices.size();
61  }
62  std::string getWaitForDevicesString() noexcept {
63  std::string res;
64  jau::for_each(waitForDevices.cbegin(), waitForDevices.cend(), [&res](const DeviceQuery &q) {
65  if( res.length() > 0 ) {
66  res.append( ", " );
67  }
68  res.append( q.toString() );
69  });
70  return res;
71  }
72 
74  return waitForDevices;
75  }
76  void clearWaitForDevices() noexcept {
77  waitForDevices.clear();
78  }
79 
80  void addToProcessedDevices(const BDAddressAndType &a, const std::string& n) noexcept {
81  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
82  devicesProcessed.emplace_hint(devicesProcessed.end(), a, n);
83  }
84  bool isDeviceProcessed(const BDAddressAndType & a) noexcept {
85  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
86  return devicesProcessed.end() != devicesProcessed.find( DeviceID(a, "") );
87  }
88  size_t getProcessedDeviceCount() noexcept {
89  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
90  return devicesProcessed.size();
91  }
92  std::string getProcessedDevicesString() noexcept {
93  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
94  std::string res;
95  jau::for_each(devicesProcessed.cbegin(), devicesProcessed.cend(), [&res](const DeviceID &id) {
96  if( res.length() > 0 ) {
97  res.append( ", " );
98  }
99  res.append( id.toString() );
100  });
101  return res;
102  }
104  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
105  // std::unordered_set<DeviceID>::iterator is not suitable for:
106  // return jau::darray<DeviceID>(devicesProcessed.size(), devicesProcessed.begin(), devicesProcessed.end());
108  auto first = devicesProcessed.cbegin();
109  auto last = devicesProcessed.cend();
110  for(; first != last; ++first) {
111  res.push_back(*first);
112  }
113  return res;
114  }
115  void clearProcessedDevices() noexcept {
116  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
117  devicesProcessed.clear();
118  }
119 
120  bool isWaitingForDevice(const EUI48 &address, const std::string &name, DeviceQueryMatchFunc m) noexcept {
121  return waitForDevices.cend() != jau::find_if(waitForDevices.cbegin(), waitForDevices.cend(), [&](const DeviceQuery & it)->bool {
122  return m(address, name, it);
123  });
124  }
125 
127  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
128  for (auto it1 = waitForDevices.cbegin(); it1 != waitForDevices.cend(); ++it1) {
129  const DeviceQuery& q = *it1;
130  auto it2 = devicesProcessed.cbegin();
131  while ( it2 != devicesProcessed.cend() ) {
132  const DeviceID& id = *it2;
133  if( m(id.addressAndType.address, id.name, q) ) {
134  break;
135  }
136  ++it2;
137  }
138  if( it2 == devicesProcessed.cend() ) {
139  return false;
140  }
141  }
142  return true;
143  }
144 
145  void addToProcessingDevices(const BDAddressAndType &a, const std::string& n) noexcept {
146  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessing); // RAII-style acquire and relinquish via destructor
147  devicesInProcessing.emplace_hint(devicesInProcessing.end(), a, n);
148  }
150  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessing); // RAII-style acquire and relinquish via destructor
151  auto it = devicesInProcessing.find( DeviceID(a, "") );
152  if( devicesInProcessing.end() != it ) {
153  devicesInProcessing.erase(it);
154  return true;
155  }
156  return false;
157  }
158  bool isDeviceProcessing(const BDAddressAndType & a) noexcept {
159  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessing); // RAII-style acquire and relinquish via destructor
160  return devicesInProcessing.end() != devicesInProcessing.find( DeviceID(a, "") );
161  }
162  size_t getProcessingDeviceCount() noexcept {
163  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessing); // RAII-style acquire and relinquish via destructor
164  return devicesInProcessing.size();
165  }
167  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessing); // RAII-style acquire and relinquish via destructor
168  // std::unordered_set<DeviceID>::iterator is not suitable for:
169  // return jau::darray<DeviceID>(devicesInProcessing.size(), devicesInProcessing.begin(), devicesInProcessing.end());
171  auto first = devicesInProcessing.cbegin();
172  auto last = devicesInProcessing.cend();
173  for(; first != last; ++first) {
174  res.push_back(*first);
175  }
176  return res;
177  }
178  void clearProcessingDevices() noexcept {
179  const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessing); // RAII-style acquire and relinquish via destructor
180  devicesInProcessing.clear();
181  }
182 
183 } // namespace direct_bt::BTDeviceRegistry
direct_bt::BTDeviceRegistry::getWaitForDevicesString
std::string getWaitForDevicesString() noexcept
Definition: BTDeviceRegistry.cpp:62
direct_bt::EUI48Sub::clear
void clear()
Method clears the underlying byte array b and sets length to zero.
Definition: BTAddress.hpp:220
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
darray.hpp
BTDeviceRegistry.hpp
direct_bt::BTDeviceRegistry::getProcessedDevices
jau::darray< DeviceID > getProcessedDevices() noexcept
Returns a copy of the current collection of processed DeviceID.
Definition: BTDeviceRegistry.cpp:103
basic_algos.hpp
direct_bt
Definition: ATTPDUTypes.hpp:171
direct_bt::BTDeviceRegistry::getProcessingDeviceCount
size_t getProcessingDeviceCount() noexcept
Definition: BTDeviceRegistry.cpp:162
direct_bt::EUI48Sub::scanEUI48Sub
static bool scanEUI48Sub(const std::string &str, EUI48Sub &dest, std::string &errmsg)
Fills given EUI48Sub instance via given string representation.
Definition: BTTypes0.cpp:186
jau::for_each
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
Like std::for_each() of 'algorithm'.
Definition: basic_algos.hpp:163
direct_bt::BTDeviceRegistry::waitForDevices
static jau::darray< DeviceQuery > waitForDevices
Definition: BTDeviceRegistry.cpp:38
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
jau::darray
Implementation of a dynamic linear array storage, aka vector.
Definition: darray.hpp:102
jau::darray::push_back
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition: darray.hpp:991
direct_bt::BTDeviceRegistry
Application toolkit providing BT device registration of processed and awaited devices.
Definition: BTDeviceRegistry.hpp:40
direct_bt::BTDeviceRegistry::devicesInProcessing
static std::unordered_set< DeviceID > devicesInProcessing
Definition: BTDeviceRegistry.cpp:40
direct_bt::BTDeviceRegistry::mtx_devicesProcessed
static std::recursive_mutex mtx_devicesProcessed
Definition: BTDeviceRegistry.cpp:44
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::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::devicesProcessed
static std::unordered_set< DeviceID > devicesProcessed
Definition: BTDeviceRegistry.cpp:43
direct_bt::BTDeviceRegistry::DeviceID
Specifies unique device identities, using BDAddressAndType as key.
Definition: BTDeviceRegistry.hpp:91
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
cpp_lang_util.hpp
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::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::mtx_devicesProcessing
static std::recursive_mutex mtx_devicesProcessing
Definition: BTDeviceRegistry.cpp:41
direct_bt::BTDeviceRegistry::isDeviceProcessed
bool isDeviceProcessed(const BDAddressAndType &a) noexcept
Definition: BTDeviceRegistry.cpp:84
jau::find_if
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
Like std::find_if() of 'algorithm'.
Definition: basic_algos.hpp:113
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