@stoprocent/noble 1.19.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +393 -650
- package/examples/advertisement-discovery.js +57 -48
- package/examples/connect-address.js +59 -34
- package/examples/echo.js +59 -69
- package/examples/enter-exit.js +55 -49
- package/examples/multiple-bindings.js +53 -0
- package/examples/peripheral-explorer-async.js +39 -21
- package/examples/peripheral-explorer.ts +52 -0
- package/index.d.ts +249 -209
- package/index.js +4 -1
- package/jest.config.js +4 -0
- package/lib/characteristic.js +153 -127
- package/lib/{win/src/callbacks.h → common/include/Emit.h} +17 -14
- package/lib/common/include/Peripheral.h +31 -0
- package/lib/common/include/ThreadSafeCallback.h +95 -0
- package/lib/{win/src/callbacks.cc → common/src/Emit.cc} +111 -68
- package/lib/descriptor.js +57 -54
- package/lib/hci-socket/acl-stream.js +2 -4
- package/lib/hci-socket/bindings.js +96 -73
- package/lib/hci-socket/gap.js +2 -3
- package/lib/hci-socket/gatt.js +2 -5
- package/lib/hci-socket/hci.js +19 -7
- package/lib/hci-socket/signaling.js +2 -3
- package/lib/hci-socket/smp.js +2 -3
- package/lib/hci-socket/vs.js +1 -0
- package/lib/mac/binding.gyp +5 -7
- package/lib/mac/bindings.js +1 -3
- package/lib/mac/src/ble_manager.h +1 -8
- package/lib/mac/src/ble_manager.mm +87 -44
- package/lib/mac/src/napi_objc.h +1 -0
- package/lib/mac/src/napi_objc.mm +0 -6
- package/lib/mac/src/noble_mac.h +5 -3
- package/lib/mac/src/noble_mac.mm +99 -57
- package/lib/mac/src/objc_cpp.h +3 -2
- package/lib/mac/src/objc_cpp.mm +0 -6
- package/lib/noble.js +579 -488
- package/lib/peripheral.js +171 -174
- package/lib/resolve-bindings.js +37 -30
- package/lib/service.js +58 -55
- package/lib/win/binding.gyp +4 -11
- package/lib/win/bindings.js +1 -3
- package/lib/win/src/ble_manager.cc +291 -166
- package/lib/win/src/ble_manager.h +11 -13
- package/lib/win/src/napi_winrt.cc +1 -7
- package/lib/win/src/napi_winrt.h +1 -1
- package/lib/win/src/noble_winrt.cc +88 -61
- package/lib/win/src/noble_winrt.h +5 -3
- package/lib/win/src/notify_map.cc +0 -7
- package/lib/win/src/notify_map.h +1 -8
- package/lib/win/src/peripheral_winrt.cc +29 -11
- package/lib/win/src/peripheral_winrt.h +1 -1
- package/lib/win/src/radio_watcher.cc +79 -69
- package/lib/win/src/radio_watcher.h +30 -11
- package/lib/win/src/winrt_cpp.cc +1 -1
- package/lib/win/src/winrt_cpp.h +3 -0
- package/package.json +14 -17
- package/prebuilds/darwin-x64+arm64/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-ia32/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-x64/@stoprocent+noble.node +0 -0
- package/test/lib/characteristic.test.js +202 -322
- package/test/lib/descriptor.test.js +62 -95
- package/test/lib/hci-socket/acl-stream.test.js +112 -108
- package/test/lib/hci-socket/bindings.test.js +576 -365
- package/test/lib/hci-socket/hci.test.js +442 -473
- package/test/lib/hci-socket/signaling.test.js +45 -48
- package/test/lib/hci-socket/smp.test.js +144 -142
- package/test/lib/hci-socket/vs.test.js +193 -18
- package/test/lib/peripheral.test.js +492 -322
- package/test/lib/resolve-bindings.test.js +207 -82
- package/test/lib/service.test.js +79 -88
- package/test/noble.test.js +381 -1085
- package/.editorconfig +0 -11
- package/.nycrc.json +0 -4
- package/codecov.yml +0 -5
- package/examples/cache-gatt-discovery.js +0 -198
- package/examples/cache-gatt-reconnect.js +0 -164
- package/examples/ext-advertisement-discovery.js +0 -65
- package/examples/peripheral-explorer.js +0 -225
- package/examples/pizza/central.js +0 -194
- package/examples/pizza/pizza.js +0 -60
- package/examples/test/test.custom.js +0 -131
- package/examples/uart-bind-params.js +0 -28
- package/lib/distributed/bindings.js +0 -326
- package/lib/mac/src/callbacks.cc +0 -222
- package/lib/mac/src/callbacks.h +0 -84
- package/lib/mac/src/peripheral.h +0 -23
- package/lib/resolve-bindings-web.js +0 -9
- package/lib/webbluetooth/bindings.js +0 -368
- package/lib/websocket/bindings.js +0 -321
- package/lib/win/src/peripheral.h +0 -23
- package/test/lib/distributed/bindings.test.js +0 -918
- package/test/lib/webbluetooth/bindings.test.js +0 -190
- package/test/lib/websocket/bindings.test.js +0 -456
- package/test/mocha.setup.js +0 -0
- package/with-bindings.js +0 -5
- package/with-custom-binding.js +0 -6
- package/ws-slave.js +0 -404
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ble_manager.cc
|
|
3
|
-
// noble-winrt-native
|
|
4
|
-
//
|
|
5
|
-
// Created by Georg Vienna on 03.09.18.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
1
|
#include "ble_manager.h"
|
|
9
2
|
#include "winrt_cpp.h"
|
|
10
3
|
|
|
11
4
|
#include <winrt/Windows.Foundation.Collections.h>
|
|
12
5
|
#include <winrt/Windows.Storage.Streams.h>
|
|
6
|
+
#include <winrt/Windows.Security.Cryptography.h>
|
|
7
|
+
#include <winrt/Windows.Devices.Bluetooth.h>
|
|
8
|
+
|
|
9
|
+
|
|
13
10
|
using winrt::Windows::Devices::Bluetooth::BluetoothCacheMode;
|
|
14
11
|
using winrt::Windows::Devices::Bluetooth::BluetoothConnectionStatus;
|
|
15
12
|
using winrt::Windows::Devices::Bluetooth::BluetoothLEDevice;
|
|
13
|
+
using winrt::Windows::Devices::Bluetooth::BluetoothUuidHelper;
|
|
16
14
|
using winrt::Windows::Storage::Streams::DataReader;
|
|
17
15
|
using winrt::Windows::Storage::Streams::DataWriter;
|
|
18
16
|
using winrt::Windows::Storage::Streams::IBuffer;
|
|
17
|
+
using winrt::Windows::Storage::Streams::ByteOrder;
|
|
18
|
+
using winrt::Windows::Security::Cryptography::CryptographicBuffer;
|
|
19
|
+
using winrt::Windows::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementBytePattern;
|
|
19
20
|
|
|
20
21
|
template <typename T> auto inFilter(std::vector<T> filter, T object)
|
|
21
22
|
{
|
|
@@ -45,18 +46,57 @@ template <typename O, typename M, class... Types> auto bind2(O* object, M method
|
|
|
45
46
|
} \
|
|
46
47
|
BluetoothLEDevice& _device = *peripheral.device;
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
std::string gattStatusToString(GattCommunicationStatus status) {
|
|
50
|
+
switch (status) {
|
|
51
|
+
case GattCommunicationStatus::Success:
|
|
52
|
+
return "Success";
|
|
53
|
+
case GattCommunicationStatus::Unreachable:
|
|
54
|
+
return "Device is unreachable";
|
|
55
|
+
case GattCommunicationStatus::ProtocolError:
|
|
56
|
+
return "Protocol error";
|
|
57
|
+
case GattCommunicationStatus::AccessDenied:
|
|
58
|
+
return "Access denied";
|
|
59
|
+
default:
|
|
60
|
+
return "Unknown error (" + std::to_string(static_cast<int>(status)) + ")";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
std::string asyncStatusToString(AsyncStatus status) {
|
|
65
|
+
switch (status) {
|
|
66
|
+
case AsyncStatus::Completed:
|
|
67
|
+
return "Completed";
|
|
68
|
+
case AsyncStatus::Started:
|
|
69
|
+
return "Operation still in progress";
|
|
70
|
+
case AsyncStatus::Canceled:
|
|
71
|
+
return "Operation was canceled";
|
|
72
|
+
case AsyncStatus::Error:
|
|
73
|
+
return "Operation failed with error";
|
|
74
|
+
default:
|
|
75
|
+
return "Unknown status (" + std::to_string(static_cast<int>(status)) + ")";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
#define CHECK_STATUS_AND_RESULT(_status, _result, _error_emit_func) \
|
|
80
|
+
do \
|
|
81
|
+
{ \
|
|
82
|
+
if ((_status) != AsyncStatus::Completed) \
|
|
83
|
+
{ \
|
|
84
|
+
_error_emit_func(asyncStatusToString(_status)); \
|
|
85
|
+
return; \
|
|
86
|
+
} \
|
|
87
|
+
if (!(_result)) \
|
|
88
|
+
{ \
|
|
89
|
+
_error_emit_func("Operation result is null"); \
|
|
90
|
+
return; \
|
|
91
|
+
} \
|
|
92
|
+
auto _commStatus = (_result).Status(); \
|
|
93
|
+
if ((_commStatus) != GattCommunicationStatus::Success) \
|
|
94
|
+
{ \
|
|
95
|
+
_error_emit_func(gattStatusToString(_commStatus)); \
|
|
96
|
+
return; \
|
|
97
|
+
} \
|
|
98
|
+
} while (0)
|
|
99
|
+
|
|
60
100
|
|
|
61
101
|
#define FOR(object, vector) \
|
|
62
102
|
auto _vector = vector; \
|
|
@@ -68,11 +108,31 @@ template <typename O, typename M, class... Types> auto bind2(O* object, M method
|
|
|
68
108
|
else \
|
|
69
109
|
for (auto&& object : _vector)
|
|
70
110
|
|
|
111
|
+
struct ServiceDataTypeInfo {
|
|
112
|
+
uint8_t dataType;
|
|
113
|
+
std::function<winrt::guid(DataReader&)> uuidConverter;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const std::vector<ServiceDataTypeInfo> serviceDataTypes = {
|
|
117
|
+
{
|
|
118
|
+
BluetoothLEAdvertisementDataTypes::ServiceData16BitUuids(),
|
|
119
|
+
[](DataReader& reader) { return BluetoothUuidHelper::FromShortId(reader.ReadUInt16()); }
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
BluetoothLEAdvertisementDataTypes::ServiceData32BitUuids(),
|
|
123
|
+
[](DataReader& reader) { return BluetoothUuidHelper::FromShortId(reader.ReadUInt32()); }
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
BluetoothLEAdvertisementDataTypes::ServiceData128BitUuids(),
|
|
127
|
+
[](DataReader& reader) { return reader.ReadGuid(); }
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
71
131
|
BLEManager::BLEManager(const Napi::Value& receiver, const Napi::Function& callback)
|
|
72
132
|
{
|
|
73
133
|
mRadioState = AdapterState::Initial;
|
|
74
134
|
mEmit.Wrap(receiver, callback);
|
|
75
|
-
auto onRadio = std::bind(&BLEManager::OnRadio, this, std::placeholders::_1);
|
|
135
|
+
auto onRadio = std::bind(&BLEManager::OnRadio, this, std::placeholders::_1, std::placeholders::_2);
|
|
76
136
|
mWatcher.Start(onRadio);
|
|
77
137
|
mAdvertismentWatcher.ScanningMode(BluetoothLEScanningMode::Active);
|
|
78
138
|
auto onReceived = bind2(this, &BLEManager::OnScanResult);
|
|
@@ -81,27 +141,7 @@ BLEManager::BLEManager(const Napi::Value& receiver, const Napi::Function& callba
|
|
|
81
141
|
mStoppedRevoker = mAdvertismentWatcher.Stopped(winrt::auto_revoke, onStopped);
|
|
82
142
|
}
|
|
83
143
|
|
|
84
|
-
const
|
|
85
|
-
{
|
|
86
|
-
switch (state)
|
|
87
|
-
{
|
|
88
|
-
case AdapterState::Unsupported:
|
|
89
|
-
return "unsupported";
|
|
90
|
-
case AdapterState::On:
|
|
91
|
-
return "poweredOn";
|
|
92
|
-
break;
|
|
93
|
-
case AdapterState::Off:
|
|
94
|
-
return "poweredOff";
|
|
95
|
-
break;
|
|
96
|
-
case AdapterState::Disabled:
|
|
97
|
-
return "poweredOff";
|
|
98
|
-
break;
|
|
99
|
-
default:
|
|
100
|
-
return "unknown";
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
void BLEManager::OnRadio(Radio& radio)
|
|
144
|
+
void BLEManager::OnRadio(Radio& radio, const AdapterCapabilities& capabilities)
|
|
105
145
|
{
|
|
106
146
|
auto state = AdapterState::Unsupported;
|
|
107
147
|
if (radio)
|
|
@@ -113,21 +153,29 @@ void BLEManager::OnRadio(Radio& radio)
|
|
|
113
153
|
mRadioState = state;
|
|
114
154
|
mEmit.RadioState(adapterStateToString(state));
|
|
115
155
|
}
|
|
156
|
+
if (capabilities.bluetoothAddress > 0)
|
|
157
|
+
{
|
|
158
|
+
mEmit.Address(formatBluetoothAddress(capabilities.bluetoothAddress));
|
|
159
|
+
}
|
|
116
160
|
}
|
|
117
161
|
|
|
118
162
|
void BLEManager::Scan(const std::vector<winrt::guid>& serviceUUIDs, bool allowDuplicates)
|
|
119
163
|
{
|
|
120
164
|
mAdvertismentMap.clear();
|
|
121
165
|
mAllowDuplicates = allowDuplicates;
|
|
166
|
+
mScanServiceUUIDs = serviceUUIDs;
|
|
167
|
+
|
|
122
168
|
BluetoothLEAdvertisementFilter filter = BluetoothLEAdvertisementFilter();
|
|
123
169
|
BluetoothLEAdvertisement advertisment = BluetoothLEAdvertisement();
|
|
124
170
|
auto services = advertisment.ServiceUuids();
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
171
|
+
// This was replaced by the filtering after the scan result
|
|
172
|
+
// for (auto uuid : serviceUUIDs)
|
|
173
|
+
// {
|
|
174
|
+
// services.Append(uuid);
|
|
175
|
+
// }
|
|
176
|
+
// filter.Advertisement(advertisment);
|
|
130
177
|
mAdvertismentWatcher.AdvertisementFilter(filter);
|
|
178
|
+
|
|
131
179
|
mAdvertismentWatcher.Start();
|
|
132
180
|
mEmit.ScanState(true);
|
|
133
181
|
}
|
|
@@ -139,7 +187,40 @@ void BLEManager::OnScanResult(BluetoothLEAdvertisementWatcher watcher,
|
|
|
139
187
|
std::string uuid = formatBluetoothUuid(bluetoothAddress);
|
|
140
188
|
int16_t rssi = args.RawSignalStrengthInDBm();
|
|
141
189
|
auto advertismentType = args.AdvertisementType();
|
|
190
|
+
auto advertisment = args.Advertisement();
|
|
191
|
+
|
|
192
|
+
if (!mScanServiceUUIDs.empty()) {
|
|
193
|
+
auto found = false;
|
|
194
|
+
std::vector<winrt::guid> serviceUUIDs;
|
|
195
|
+
|
|
196
|
+
for (const auto& typeInfo : serviceDataTypes) {
|
|
197
|
+
auto sections = advertisment.GetSectionsByType(typeInfo.dataType);
|
|
198
|
+
for (auto section : sections) {
|
|
199
|
+
auto reader = DataReader::FromBuffer(section.Data());
|
|
200
|
+
reader.ByteOrder(ByteOrder::LittleEndian);
|
|
201
|
+
auto uuid = typeInfo.uuidConverter(reader);
|
|
202
|
+
if (inFilter(mScanServiceUUIDs, uuid)) {
|
|
203
|
+
found = true;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (found) break;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
auto serviceUuids = advertisment.ServiceUuids();
|
|
211
|
+
for (auto uuid : serviceUuids) {
|
|
212
|
+
if (inFilter(mScanServiceUUIDs, uuid)) {
|
|
213
|
+
found = true;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
142
217
|
|
|
218
|
+
if (!found) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
143
224
|
if (mDeviceMap.find(uuid) == mDeviceMap.end())
|
|
144
225
|
{
|
|
145
226
|
mAdvertismentMap.insert(uuid);
|
|
@@ -163,6 +244,12 @@ void BLEManager::OnScanResult(BluetoothLEAdvertisementWatcher watcher,
|
|
|
163
244
|
void BLEManager::StopScan()
|
|
164
245
|
{
|
|
165
246
|
mAdvertismentWatcher.Stop();
|
|
247
|
+
|
|
248
|
+
auto status = mAdvertismentWatcher.Status();
|
|
249
|
+
if (status == BluetoothLEAdvertisementWatcherStatus::Stopped ||
|
|
250
|
+
status == BluetoothLEAdvertisementWatcherStatus::Aborted) {
|
|
251
|
+
mEmit.ScanState(false);
|
|
252
|
+
}
|
|
166
253
|
}
|
|
167
254
|
|
|
168
255
|
void BLEManager::OnScanStopped(BluetoothLEAdvertisementWatcher watcher,
|
|
@@ -175,9 +262,38 @@ bool BLEManager::Connect(const std::string& uuid)
|
|
|
175
262
|
{
|
|
176
263
|
if (mDeviceMap.find(uuid) == mDeviceMap.end())
|
|
177
264
|
{
|
|
178
|
-
|
|
179
|
-
|
|
265
|
+
// Convert UUID string to MAC address format
|
|
266
|
+
// Remove any colons if present and convert to uppercase
|
|
267
|
+
std::string cleanUuid = uuid;
|
|
268
|
+
cleanUuid.erase(std::remove(cleanUuid.begin(), cleanUuid.end(), ':'), cleanUuid.end());
|
|
269
|
+
|
|
270
|
+
// Basic validation
|
|
271
|
+
if (cleanUuid.length() != 12) {
|
|
272
|
+
mEmit.Connected(uuid, "invalid device address format");
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
try {
|
|
277
|
+
// Convert string to uint64_t bluetooth address
|
|
278
|
+
uint64_t bluetoothAddress = std::stoull(cleanUuid, nullptr, 16);
|
|
279
|
+
|
|
280
|
+
// Create a new peripheral entry as if it was scanned
|
|
281
|
+
auto peripheral = PeripheralWinrt(bluetoothAddress,
|
|
282
|
+
BluetoothLEAdvertisementType::ConnectableUndirected,
|
|
283
|
+
127, // default RSSI for direct connect
|
|
284
|
+
BluetoothLEAdvertisement()); // empty advertisement
|
|
285
|
+
|
|
286
|
+
// Emit scan event just like during normal scanning
|
|
287
|
+
mEmit.Scan(uuid, 127, peripheral);
|
|
288
|
+
|
|
289
|
+
// Add to device map
|
|
290
|
+
mDeviceMap.emplace(std::make_pair(uuid, std::move(peripheral)));
|
|
291
|
+
} catch (const std::exception& e) {
|
|
292
|
+
mEmit.Connected(uuid, "invalid device address format");
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
180
295
|
}
|
|
296
|
+
|
|
181
297
|
PeripheralWinrt& peripheral = mDeviceMap[uuid];
|
|
182
298
|
if (!peripheral.device.has_value())
|
|
183
299
|
{
|
|
@@ -230,6 +346,15 @@ bool BLEManager::Disconnect(const std::string& uuid)
|
|
|
230
346
|
return true;
|
|
231
347
|
}
|
|
232
348
|
|
|
349
|
+
bool BLEManager::CancelConnect(const std::string& uuid)
|
|
350
|
+
{
|
|
351
|
+
CHECK_DEVICE();
|
|
352
|
+
PeripheralWinrt& peripheral = mDeviceMap[uuid];
|
|
353
|
+
peripheral.Disconnect();
|
|
354
|
+
mNotifyMap.Remove(uuid);
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
|
|
233
358
|
void BLEManager::OnConnectionStatusChanged(BluetoothLEDevice device,
|
|
234
359
|
winrt::Windows::Foundation::IInspectable inspectable)
|
|
235
360
|
{
|
|
@@ -274,25 +399,25 @@ void BLEManager::OnServicesDiscovered(IAsyncOperation<GattDeviceServicesResult>
|
|
|
274
399
|
AsyncStatus status, const std::string uuid,
|
|
275
400
|
const std::vector<winrt::guid> serviceUUIDs)
|
|
276
401
|
{
|
|
277
|
-
|
|
402
|
+
auto result = asyncOp.GetResults();
|
|
403
|
+
std::vector<std::string> serviceUuids;
|
|
404
|
+
|
|
405
|
+
auto emit = [this, uuid, &serviceUuids](const std::string& err) {
|
|
406
|
+
auto error = err + " while discovering services";
|
|
407
|
+
mEmit.ServicesDiscovered(uuid, serviceUuids, error);
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
CHECK_STATUS_AND_RESULT(status, result, emit);
|
|
411
|
+
|
|
412
|
+
FOR(service, result.Services())
|
|
278
413
|
{
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
std::vector<std::string> serviceUuids;
|
|
282
|
-
FOR(service, result.Services())
|
|
414
|
+
auto id = service.Uuid();
|
|
415
|
+
if (inFilter(serviceUUIDs, id))
|
|
283
416
|
{
|
|
284
|
-
|
|
285
|
-
if (inFilter(serviceUUIDs, id))
|
|
286
|
-
{
|
|
287
|
-
serviceUuids.push_back(toStr(id));
|
|
288
|
-
}
|
|
417
|
+
serviceUuids.push_back(toStr(id));
|
|
289
418
|
}
|
|
290
|
-
mEmit.ServicesDiscovered(uuid, serviceUuids);
|
|
291
|
-
}
|
|
292
|
-
else
|
|
293
|
-
{
|
|
294
|
-
LOGE("status: %d", status);
|
|
295
419
|
}
|
|
420
|
+
mEmit.ServicesDiscovered(uuid, serviceUuids);
|
|
296
421
|
}
|
|
297
422
|
|
|
298
423
|
bool BLEManager::DiscoverIncludedServices(const std::string& uuid, const winrt::guid& serviceUuid,
|
|
@@ -323,25 +448,25 @@ void BLEManager::OnIncludedServicesDiscovered(IAsyncOperation<GattDeviceServices
|
|
|
323
448
|
const std::string serviceId,
|
|
324
449
|
const std::vector<winrt::guid> serviceUUIDs)
|
|
325
450
|
{
|
|
326
|
-
|
|
451
|
+
auto result = asyncOp.GetResults();
|
|
452
|
+
std::vector<std::string> servicesUuids;
|
|
453
|
+
|
|
454
|
+
auto emit = [this, uuid, serviceId, &servicesUuids](const std::string& err) {
|
|
455
|
+
auto error = err + " while discovering included services for service " + serviceId;
|
|
456
|
+
mEmit.IncludedServicesDiscovered(uuid, serviceId, servicesUuids, error);
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
CHECK_STATUS_AND_RESULT(status, result, emit);
|
|
460
|
+
|
|
461
|
+
FOR(service, result.Services())
|
|
327
462
|
{
|
|
328
|
-
auto
|
|
329
|
-
|
|
330
|
-
std::vector<std::string> servicesUuids;
|
|
331
|
-
FOR(service, result.Services())
|
|
463
|
+
auto id = service.Uuid();
|
|
464
|
+
if (inFilter(serviceUUIDs, id))
|
|
332
465
|
{
|
|
333
|
-
|
|
334
|
-
if (inFilter(serviceUUIDs, id))
|
|
335
|
-
{
|
|
336
|
-
servicesUuids.push_back(toStr(id));
|
|
337
|
-
}
|
|
466
|
+
servicesUuids.push_back(toStr(id));
|
|
338
467
|
}
|
|
339
|
-
mEmit.IncludedServicesDiscovered(uuid, serviceId, servicesUuids);
|
|
340
|
-
}
|
|
341
|
-
else
|
|
342
|
-
{
|
|
343
|
-
LOGE("status: %d", status);
|
|
344
468
|
}
|
|
469
|
+
mEmit.IncludedServicesDiscovered(uuid, serviceId, servicesUuids);
|
|
345
470
|
}
|
|
346
471
|
|
|
347
472
|
bool BLEManager::DiscoverCharacteristics(const std::string& uuid, const winrt::guid& serviceUuid,
|
|
@@ -372,27 +497,26 @@ void BLEManager::OnCharacteristicsDiscovered(IAsyncOperation<GattCharacteristics
|
|
|
372
497
|
const std::string serviceId,
|
|
373
498
|
const std::vector<winrt::guid> characteristicUUIDs)
|
|
374
499
|
{
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
auto result = asyncOp.GetResults();
|
|
378
|
-
CHECK_RESULT(result);
|
|
379
|
-
std::vector<std::pair<std::string, std::vector<std::string>>> characteristicsUuids;
|
|
500
|
+
auto result = asyncOp.GetResults();
|
|
501
|
+
std::vector<std::pair<std::string, std::vector<std::string>>> characteristicsUuids;
|
|
380
502
|
|
|
381
|
-
|
|
503
|
+
auto emit = [this, uuid, serviceId, &characteristicsUuids](const std::string& err) {
|
|
504
|
+
auto error = err + " while discovering characteristics for service " + serviceId;
|
|
505
|
+
mEmit.CharacteristicsDiscovered(uuid, serviceId, characteristicsUuids, error);
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
CHECK_STATUS_AND_RESULT(status, result, emit);
|
|
509
|
+
|
|
510
|
+
FOR(characteristic, result.Characteristics())
|
|
511
|
+
{
|
|
512
|
+
auto id = characteristic.Uuid();
|
|
513
|
+
if (inFilter(characteristicUUIDs, id))
|
|
382
514
|
{
|
|
383
|
-
auto
|
|
384
|
-
|
|
385
|
-
{
|
|
386
|
-
auto props = characteristic.CharacteristicProperties();
|
|
387
|
-
characteristicsUuids.push_back({ toStr(id), toPropertyArray(props) });
|
|
388
|
-
}
|
|
515
|
+
auto props = characteristic.CharacteristicProperties();
|
|
516
|
+
characteristicsUuids.push_back({ toStr(id), toPropertyArray(props) });
|
|
389
517
|
}
|
|
390
|
-
mEmit.CharacteristicsDiscovered(uuid, serviceId, characteristicsUuids);
|
|
391
|
-
}
|
|
392
|
-
else
|
|
393
|
-
{
|
|
394
|
-
LOGE("status: %d", status);
|
|
395
518
|
}
|
|
519
|
+
mEmit.CharacteristicsDiscovered(uuid, serviceId, characteristicsUuids);
|
|
396
520
|
}
|
|
397
521
|
|
|
398
522
|
bool BLEManager::Read(const std::string& uuid, const winrt::guid& serviceUuid,
|
|
@@ -424,26 +548,25 @@ void BLEManager::OnRead(IAsyncOperation<GattReadResult> asyncOp, AsyncStatus sta
|
|
|
424
548
|
const std::string uuid, const std::string serviceId,
|
|
425
549
|
const std::string characteristicId)
|
|
426
550
|
{
|
|
427
|
-
|
|
551
|
+
auto result = asyncOp.GetResults();
|
|
552
|
+
|
|
553
|
+
auto emit = [this, uuid, serviceId, characteristicId](const std::string& err) {
|
|
554
|
+
auto error = err + " while reading characteristic " + characteristicId;
|
|
555
|
+
mEmit.Read(uuid, serviceId, characteristicId, Data(), false, error);
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
CHECK_STATUS_AND_RESULT(status, result, emit);
|
|
559
|
+
|
|
560
|
+
auto value = result.Value();
|
|
561
|
+
if (value)
|
|
428
562
|
{
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
{
|
|
434
|
-
auto reader = DataReader::FromBuffer(value);
|
|
435
|
-
Data data(reader.UnconsumedBufferLength());
|
|
436
|
-
reader.ReadBytes(data);
|
|
437
|
-
mEmit.Read(uuid, serviceId, characteristicId, data, false);
|
|
438
|
-
}
|
|
439
|
-
else
|
|
440
|
-
{
|
|
441
|
-
LOGE("value is null");
|
|
442
|
-
}
|
|
563
|
+
auto reader = DataReader::FromBuffer(value);
|
|
564
|
+
Data data(reader.UnconsumedBufferLength());
|
|
565
|
+
reader.ReadBytes(data);
|
|
566
|
+
mEmit.Read(uuid, serviceId, characteristicId, data, false);
|
|
443
567
|
}
|
|
444
|
-
else
|
|
445
|
-
|
|
446
|
-
LOGE("status: %d", status);
|
|
568
|
+
else {
|
|
569
|
+
mEmit.Read(uuid, serviceId, characteristicId, Data(), false, "value is null");
|
|
447
570
|
}
|
|
448
571
|
}
|
|
449
572
|
|
|
@@ -488,7 +611,8 @@ void BLEManager::OnWrite(IAsyncOperation<GattWriteResult> asyncOp, AsyncStatus s
|
|
|
488
611
|
}
|
|
489
612
|
else
|
|
490
613
|
{
|
|
491
|
-
|
|
614
|
+
std::string error = "status: " + std::to_string((int)status);
|
|
615
|
+
mEmit.Write(uuid, serviceId, characteristicId, error);
|
|
492
616
|
}
|
|
493
617
|
}
|
|
494
618
|
|
|
@@ -584,7 +708,8 @@ void BLEManager::OnNotify(IAsyncOperation<GattWriteResult> asyncOp, AsyncStatus
|
|
|
584
708
|
}
|
|
585
709
|
else
|
|
586
710
|
{
|
|
587
|
-
|
|
711
|
+
std::string error = "status: " + std::to_string((int)status);
|
|
712
|
+
mEmit.Notify(uuid, serviceId, characteristicId, state, error);
|
|
588
713
|
}
|
|
589
714
|
}
|
|
590
715
|
|
|
@@ -630,21 +755,21 @@ void BLEManager::OnDescriptorsDiscovered(IAsyncOperation<GattDescriptorsResult>
|
|
|
630
755
|
const std::string serviceId,
|
|
631
756
|
const std::string characteristicId)
|
|
632
757
|
{
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
else
|
|
758
|
+
auto result = asyncOp.GetResults();
|
|
759
|
+
std::vector<std::string> descriptorUuids;
|
|
760
|
+
|
|
761
|
+
auto emit = [this, uuid, serviceId, characteristicId, &descriptorUuids](const std::string& err) {
|
|
762
|
+
auto error = err + " while discovering descriptors for characteristic " + characteristicId;
|
|
763
|
+
mEmit.DescriptorsDiscovered(uuid, serviceId, characteristicId, descriptorUuids, error);
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
CHECK_STATUS_AND_RESULT(status, result, emit);
|
|
767
|
+
|
|
768
|
+
FOR(descriptor, result.Descriptors())
|
|
645
769
|
{
|
|
646
|
-
|
|
770
|
+
descriptorUuids.push_back(toStr(descriptor.Uuid()));
|
|
647
771
|
}
|
|
772
|
+
mEmit.DescriptorsDiscovered(uuid, serviceId, characteristicId, descriptorUuids);
|
|
648
773
|
}
|
|
649
774
|
|
|
650
775
|
bool BLEManager::ReadValue(const std::string& uuid, const winrt::guid& serviceUuid,
|
|
@@ -678,26 +803,25 @@ void BLEManager::OnReadValue(IAsyncOperation<GattReadResult> asyncOp, AsyncStatu
|
|
|
678
803
|
const std::string uuid, const std::string serviceId,
|
|
679
804
|
const std::string characteristicId, const std::string descriptorId)
|
|
680
805
|
{
|
|
681
|
-
|
|
806
|
+
auto result = asyncOp.GetResults();
|
|
807
|
+
|
|
808
|
+
auto emit = [this, uuid, serviceId, characteristicId, descriptorId](const std::string& err) {
|
|
809
|
+
auto error = err + " while reading value of descriptor " + descriptorId;
|
|
810
|
+
mEmit.ReadValue(uuid, serviceId, characteristicId, descriptorId, Data(), error);
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
CHECK_STATUS_AND_RESULT(status, result, emit);
|
|
814
|
+
|
|
815
|
+
auto value = result.Value();
|
|
816
|
+
if (value)
|
|
682
817
|
{
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
{
|
|
688
|
-
auto reader = DataReader::FromBuffer(value);
|
|
689
|
-
Data data(reader.UnconsumedBufferLength());
|
|
690
|
-
reader.ReadBytes(data);
|
|
691
|
-
mEmit.ReadValue(uuid, serviceId, characteristicId, descriptorId, data);
|
|
692
|
-
}
|
|
693
|
-
else
|
|
694
|
-
{
|
|
695
|
-
LOGE("value is null");
|
|
696
|
-
}
|
|
818
|
+
auto reader = DataReader::FromBuffer(value);
|
|
819
|
+
Data data(reader.UnconsumedBufferLength());
|
|
820
|
+
reader.ReadBytes(data);
|
|
821
|
+
mEmit.ReadValue(uuid, serviceId, characteristicId, descriptorId, data);
|
|
697
822
|
}
|
|
698
|
-
else
|
|
699
|
-
|
|
700
|
-
LOGE("status: %d", status);
|
|
823
|
+
else {
|
|
824
|
+
mEmit.ReadValue(uuid, serviceId, characteristicId, descriptorId, Data(), "value is null");
|
|
701
825
|
}
|
|
702
826
|
}
|
|
703
827
|
|
|
@@ -741,7 +865,8 @@ void BLEManager::OnWriteValue(IAsyncOperation<GattWriteResult> asyncOp, AsyncSta
|
|
|
741
865
|
}
|
|
742
866
|
else
|
|
743
867
|
{
|
|
744
|
-
|
|
868
|
+
std::string error = "status: " + std::to_string((int)status);
|
|
869
|
+
mEmit.WriteValue(uuid, serviceId, characteristicId, descriptorId, error);
|
|
745
870
|
}
|
|
746
871
|
}
|
|
747
872
|
|
|
@@ -758,26 +883,25 @@ bool BLEManager::ReadHandle(const std::string& uuid, int handle)
|
|
|
758
883
|
void BLEManager::OnReadHandle(IAsyncOperation<GattReadResult> asyncOp, AsyncStatus status,
|
|
759
884
|
const std::string uuid, const int handle)
|
|
760
885
|
{
|
|
761
|
-
|
|
886
|
+
auto result = asyncOp.GetResults();
|
|
887
|
+
|
|
888
|
+
auto emit = [this, uuid, handle](const std::string& err) {
|
|
889
|
+
auto error = err + " while reading handle " + std::to_string(handle);
|
|
890
|
+
mEmit.ReadHandle(uuid, handle, Data(), error);
|
|
891
|
+
};
|
|
892
|
+
|
|
893
|
+
CHECK_STATUS_AND_RESULT(status, result, emit);
|
|
894
|
+
|
|
895
|
+
auto value = result.Value();
|
|
896
|
+
if (value)
|
|
762
897
|
{
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
{
|
|
768
|
-
auto reader = DataReader::FromBuffer(value);
|
|
769
|
-
Data data(reader.UnconsumedBufferLength());
|
|
770
|
-
reader.ReadBytes(data);
|
|
771
|
-
mEmit.ReadHandle(uuid, handle, data);
|
|
772
|
-
}
|
|
773
|
-
else
|
|
774
|
-
{
|
|
775
|
-
LOGE("value is null");
|
|
776
|
-
}
|
|
898
|
+
auto reader = DataReader::FromBuffer(value);
|
|
899
|
+
Data data(reader.UnconsumedBufferLength());
|
|
900
|
+
reader.ReadBytes(data);
|
|
901
|
+
mEmit.ReadHandle(uuid, handle, data);
|
|
777
902
|
}
|
|
778
|
-
else
|
|
779
|
-
|
|
780
|
-
LOGE("status: %d", status);
|
|
903
|
+
else {
|
|
904
|
+
mEmit.ReadHandle(uuid, handle, Data(), "value is null");
|
|
781
905
|
}
|
|
782
906
|
}
|
|
783
907
|
|
|
@@ -800,6 +924,7 @@ void BLEManager::OnWriteHandle(IAsyncOperation<GattWriteResult> asyncOp, AsyncSt
|
|
|
800
924
|
}
|
|
801
925
|
else
|
|
802
926
|
{
|
|
803
|
-
|
|
927
|
+
std::string error = "status: " + std::to_string((int)status);
|
|
928
|
+
mEmit.WriteHandle(uuid, handle, error);
|
|
804
929
|
}
|
|
805
930
|
}
|