Direct-BT v3.3.0-1-gc2d430c
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
35using namespace direct_bt;
36
39
40 static std::unordered_set<DeviceID> devicesProcessed;
41 static std::recursive_mutex mtx_devicesProcessed;
42
43 void addToWaitForDevices(const std::string& addrOrNameSub) noexcept {
44 EUI48Sub addr1;
45 std::string errmsg;
46 if( EUI48Sub::scanEUI48Sub(addrOrNameSub, addr1, errmsg) ) {
47 waitForDevices.emplace_back( addr1 );
48 } else {
49 addr1.clear();
50 waitForDevices.emplace_back( addrOrNameSub );
51 }
52 }
53 bool isWaitingForAnyDevice() noexcept {
54 return waitForDevices.empty();
55 }
56 size_t getWaitForDevicesCount() noexcept {
57 return waitForDevices.size();
58 }
59 std::string getWaitForDevicesString() noexcept {
60 std::string res;
61 jau::for_each(waitForDevices.cbegin(), waitForDevices.cend(), [&res](const DeviceQuery &q) {
62 if( res.length() > 0 ) {
63 res.append( ", " );
64 }
65 res.append( q.toString() );
66 });
67 return res;
68 }
69
71 return waitForDevices;
72 }
73 void clearWaitForDevices() noexcept {
74 waitForDevices.clear();
75 }
76
77 void addToProcessedDevices(const BDAddressAndType &a, const std::string& n) noexcept {
78 const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
79 devicesProcessed.emplace_hint(devicesProcessed.end(), a, n);
80 }
81 bool isDeviceProcessed(const BDAddressAndType & a) noexcept {
82 const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
83 return devicesProcessed.end() != devicesProcessed.find( DeviceID(a, "") );
84 }
85 size_t getProcessedDeviceCount() noexcept {
86 const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
87 return devicesProcessed.size();
88 }
89 std::string getProcessedDevicesString() noexcept {
90 const std::lock_guard<std::recursive_mutex> lock(mtx_devicesProcessed); // RAII-style acquire and relinquish via destructor
91 std::string res;
92 jau::for_each(devicesProcessed.cbegin(), devicesProcessed.cend(), [&res](const DeviceID &id) {
93 PRAGMA_DISABLE_WARNING_PUSH
94 PRAGMA_DISABLE_WARNING_RESTRICT
95 if( res.length() > 0 ) {
96 res.append( ", " ); // bogus gcc 12.2 'may overlap'
97 }
98 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 (const auto & q : waitForDevices) {
129 auto it2 = devicesProcessed.cbegin();
130 while ( it2 != devicesProcessed.cend() ) {
131 const DeviceID& id = *it2;
132 if( m(id.addressAndType.address, id.name, q) ) {
133 break;
134 }
135 ++it2;
136 }
137 if( it2 == devicesProcessed.cend() ) {
138 return false;
139 }
140 }
141 return true;
142 }
143} // namespace direct_bt::BTDeviceRegistry
Unique Bluetooth EUI48 address and BDAddressType tuple.
Definition: BTAddress.hpp:175
Implementation of a dynamic linear array storage, aka vector.
Definition: darray.hpp:148
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition: darray.hpp:1124
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
Like std::for_each() of 'algorithm'.
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
Like std::find_if() of 'algorithm'.
#define PRAGMA_DISABLE_WARNING_POP
Definition: cpp_pragma.hpp:77
Application toolkit providing BT device registration of processed and awaited devices.
void clearProcessedDevices() noexcept
Clears internal list.
std::string getProcessedDevicesString() noexcept
void addToWaitForDevices(const std::string &addrOrNameSub) noexcept
size_t getProcessedDeviceCount() 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
static std::unordered_set< DeviceID > devicesProcessed
bool areAllDevicesProcessed(DeviceQueryMatchFunc m) noexcept
Returns true if all addToWaitForDevices() awaited devices have been addToProcessedDevices() processed...
bool isWaitingForAnyDevice() noexcept
size_t getWaitForDevicesCount() noexcept
static std::recursive_mutex mtx_devicesProcessed
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
static jau::darray< DeviceQuery > waitForDevices
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...
Specifies unique device identities, using BDAddressAndType as key.
Specifies devices queries to act upon.
A 48 bit EUI-48 sub-identifier, see EUI48.
Definition: eui48.hpp:51
void clear()
Method clears the underlying byte array b and sets length to zero.
Definition: eui48.hpp:127
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition: eui48.hpp:324