@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,26 +1,20 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ble_manager.h
|
|
3
|
-
// noble-winrt-native
|
|
4
|
-
//
|
|
5
|
-
// Created by Georg Vienna on 03.09.18.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
1
|
#pragma once
|
|
9
2
|
|
|
10
3
|
#include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
|
|
11
4
|
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
|
12
5
|
|
|
13
|
-
#include "
|
|
6
|
+
#include "Emit.h"
|
|
7
|
+
#include "notify_map.h"
|
|
14
8
|
#include "peripheral_winrt.h"
|
|
15
9
|
#include "radio_watcher.h"
|
|
16
|
-
#include "notify_map.h"
|
|
17
10
|
|
|
18
11
|
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
|
|
19
12
|
using namespace winrt::Windows::Devices::Bluetooth::Advertisement;
|
|
20
13
|
using winrt::Windows::Foundation::AsyncStatus;
|
|
14
|
+
using winrt::Windows::Foundation::IAsyncOperation;
|
|
15
|
+
using winrt::Windows::Foundation::IInspectable;
|
|
21
16
|
|
|
22
|
-
class BLEManager
|
|
23
|
-
{
|
|
17
|
+
class BLEManager {
|
|
24
18
|
public:
|
|
25
19
|
// clang-format off
|
|
26
20
|
BLEManager(const Napi::Value& receiver, const Napi::Function& callback);
|
|
@@ -28,6 +22,7 @@ public:
|
|
|
28
22
|
void StopScan();
|
|
29
23
|
bool Connect(const std::string& uuid);
|
|
30
24
|
bool Disconnect(const std::string& uuid);
|
|
25
|
+
bool CancelConnect(const std::string& uuid);
|
|
31
26
|
bool UpdateRSSI(const std::string& uuid);
|
|
32
27
|
bool DiscoverServices(const std::string& uuid, const std::vector<winrt::guid>& serviceUUIDs);
|
|
33
28
|
bool DiscoverIncludedServices(const std::string& uuid, const winrt::guid& serviceUuid, const std::vector<winrt::guid>& serviceUUIDs);
|
|
@@ -44,7 +39,7 @@ public:
|
|
|
44
39
|
|
|
45
40
|
private:
|
|
46
41
|
// clang-format off
|
|
47
|
-
void OnRadio(Radio& radio);
|
|
42
|
+
void OnRadio(Radio& radio, const AdapterCapabilities& capabilities);
|
|
48
43
|
void OnScanResult(BluetoothLEAdvertisementWatcher watcher, const BluetoothLEAdvertisementReceivedEventArgs& args);
|
|
49
44
|
void OnScanStopped(BluetoothLEAdvertisementWatcher watcher, const BluetoothLEAdvertisementWatcherStoppedEventArgs& args);
|
|
50
45
|
void OnConnected(IAsyncOperation<BluetoothLEDevice> asyncOp, AsyncStatus status, std::string uuid);
|
|
@@ -62,16 +57,19 @@ private:
|
|
|
62
57
|
void OnReadHandle(IAsyncOperation<GattReadResult> asyncOp, AsyncStatus status, std::string uuid, int handle);
|
|
63
58
|
void OnWriteHandle(IAsyncOperation<GattWriteResult> asyncOp, AsyncStatus status, std::string uuid, int handle);
|
|
64
59
|
// clang-format on
|
|
60
|
+
|
|
61
|
+
bool mAllowDuplicates;
|
|
65
62
|
|
|
66
63
|
Emit mEmit;
|
|
67
64
|
RadioWatcher mWatcher;
|
|
68
65
|
AdapterState mRadioState;
|
|
69
66
|
BluetoothLEAdvertisementWatcher mAdvertismentWatcher;
|
|
67
|
+
|
|
70
68
|
winrt::event_revoker<IBluetoothLEAdvertisementWatcher> mReceivedRevoker;
|
|
71
69
|
winrt::event_revoker<IBluetoothLEAdvertisementWatcher> mStoppedRevoker;
|
|
72
|
-
bool mAllowDuplicates;
|
|
73
70
|
|
|
74
71
|
std::unordered_map<std::string, PeripheralWinrt> mDeviceMap;
|
|
72
|
+
std::vector<winrt::guid> mScanServiceUUIDs;
|
|
75
73
|
std::set<std::string> mAdvertismentMap;
|
|
76
74
|
NotifyMap mNotifyMap;
|
|
77
75
|
};
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
//
|
|
2
|
-
// napi_objc.mm
|
|
3
|
-
// noble-mac-native
|
|
4
|
-
//
|
|
5
|
-
// Created by Georg Vienna on 30.08.18.
|
|
6
|
-
//
|
|
7
1
|
#include "napi_winrt.h"
|
|
8
2
|
|
|
9
3
|
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
|
@@ -21,7 +15,7 @@ winrt::guid napiToUuid(Napi::String string)
|
|
|
21
15
|
str.insert(18, "-");
|
|
22
16
|
str.insert(23, "-");
|
|
23
17
|
}
|
|
24
|
-
if (str.size() == 4)
|
|
18
|
+
if (str.size() == 4 || str.size() == 8)
|
|
25
19
|
{
|
|
26
20
|
int id = std::stoi(str, 0, 16);
|
|
27
21
|
return BluetoothUuidHelper::FromShortId(id);
|
package/lib/win/src/napi_winrt.h
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
// noble_winrt.cc
|
|
3
|
-
// noble-winrt-native
|
|
4
|
-
//
|
|
5
|
-
// Created by Georg Vienna on 03.09.18.
|
|
6
|
-
//
|
|
7
1
|
#include "noble_winrt.h"
|
|
8
|
-
|
|
9
2
|
#include "napi_winrt.h"
|
|
3
|
+
#include "winrt_cpp.h"
|
|
10
4
|
|
|
11
5
|
#define THROW(msg) \
|
|
12
6
|
Napi::TypeError::New(info.Env(), msg).ThrowAsJavaScriptException(); \
|
|
@@ -48,18 +42,26 @@
|
|
|
48
42
|
#define CHECK_MANAGER() \
|
|
49
43
|
if (!manager) \
|
|
50
44
|
{ \
|
|
51
|
-
THROW("BLEManager has already been cleaned up"); \
|
|
45
|
+
THROW(__FUNCTION__ ": BLEManager has already been cleaned up"); \
|
|
52
46
|
}
|
|
53
47
|
|
|
54
48
|
NobleWinrt::NobleWinrt(const Napi::CallbackInfo& info) : ObjectWrap(info)
|
|
55
49
|
{
|
|
56
50
|
}
|
|
57
51
|
|
|
58
|
-
Napi::Value NobleWinrt::
|
|
52
|
+
Napi::Value NobleWinrt::Start(const Napi::CallbackInfo& info)
|
|
59
53
|
{
|
|
60
54
|
Napi::Function emit = info.This().As<Napi::Object>().Get("emit").As<Napi::Function>();
|
|
61
55
|
manager = new BLEManager(info.This(), emit);
|
|
62
|
-
return
|
|
56
|
+
return info.Env().Undefined();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Napi::Value NobleWinrt::Stop(const Napi::CallbackInfo& info)
|
|
60
|
+
{
|
|
61
|
+
CHECK_MANAGER()
|
|
62
|
+
delete manager;
|
|
63
|
+
manager = nullptr;
|
|
64
|
+
return info.Env().Undefined();
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
// startScanning(serviceUuids, allowDuplicates)
|
|
@@ -70,7 +72,7 @@ Napi::Value NobleWinrt::Scan(const Napi::CallbackInfo& info)
|
|
|
70
72
|
// default value false
|
|
71
73
|
auto duplicates = getBool(info[1], false);
|
|
72
74
|
manager->Scan(vector, duplicates);
|
|
73
|
-
return
|
|
75
|
+
return info.Env().Undefined();
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
// stopScanning()
|
|
@@ -78,7 +80,7 @@ Napi::Value NobleWinrt::StopScan(const Napi::CallbackInfo& info)
|
|
|
78
80
|
{
|
|
79
81
|
CHECK_MANAGER()
|
|
80
82
|
manager->StopScan();
|
|
81
|
-
return
|
|
83
|
+
return info.Env().Undefined();
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
// connect(deviceUuid)
|
|
@@ -88,7 +90,7 @@ Napi::Value NobleWinrt::Connect(const Napi::CallbackInfo& info)
|
|
|
88
90
|
ARG1(String)
|
|
89
91
|
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
90
92
|
manager->Connect(uuid);
|
|
91
|
-
return
|
|
93
|
+
return info.Env().Undefined();
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
// disconnect(deviceUuid)
|
|
@@ -98,7 +100,17 @@ Napi::Value NobleWinrt::Disconnect(const Napi::CallbackInfo& info)
|
|
|
98
100
|
ARG1(String)
|
|
99
101
|
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
100
102
|
manager->Disconnect(uuid);
|
|
101
|
-
return
|
|
103
|
+
return info.Env().Undefined();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// cancelConnect(deviceUuid)
|
|
107
|
+
Napi::Value NobleWinrt::CancelConnect(const Napi::CallbackInfo& info)
|
|
108
|
+
{
|
|
109
|
+
CHECK_MANAGER()
|
|
110
|
+
ARG1(String)
|
|
111
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
112
|
+
manager->CancelConnect(uuid);
|
|
113
|
+
return info.Env().Undefined();
|
|
102
114
|
}
|
|
103
115
|
|
|
104
116
|
// updateRssi(deviceUuid)
|
|
@@ -108,7 +120,7 @@ Napi::Value NobleWinrt::UpdateRSSI(const Napi::CallbackInfo& info)
|
|
|
108
120
|
ARG1(String)
|
|
109
121
|
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
110
122
|
manager->UpdateRSSI(uuid);
|
|
111
|
-
return
|
|
123
|
+
return info.Env().Undefined();
|
|
112
124
|
}
|
|
113
125
|
|
|
114
126
|
// discoverServices(deviceUuid, uuids)
|
|
@@ -119,7 +131,7 @@ Napi::Value NobleWinrt::DiscoverServices(const Napi::CallbackInfo& info)
|
|
|
119
131
|
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
120
132
|
std::vector<winrt::guid> uuids = getUuidArray(info[1]);
|
|
121
133
|
manager->DiscoverServices(uuid, uuids);
|
|
122
|
-
return
|
|
134
|
+
return info.Env().Undefined();
|
|
123
135
|
}
|
|
124
136
|
|
|
125
137
|
// discoverIncludedServices(deviceUuid, serviceUuid, serviceUuids)
|
|
@@ -131,7 +143,7 @@ Napi::Value NobleWinrt::DiscoverIncludedServices(const Napi::CallbackInfo& info)
|
|
|
131
143
|
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
132
144
|
std::vector<winrt::guid> uuids = getUuidArray(info[2]);
|
|
133
145
|
manager->DiscoverIncludedServices(uuid, service, uuids);
|
|
134
|
-
return
|
|
146
|
+
return info.Env().Undefined();
|
|
135
147
|
}
|
|
136
148
|
|
|
137
149
|
// discoverCharacteristics(deviceUuid, serviceUuid, characteristicUuids)
|
|
@@ -143,7 +155,7 @@ Napi::Value NobleWinrt::DiscoverCharacteristics(const Napi::CallbackInfo& info)
|
|
|
143
155
|
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
144
156
|
std::vector<winrt::guid> characteristics = getUuidArray(info[2]);
|
|
145
157
|
manager->DiscoverCharacteristics(uuid, service, characteristics);
|
|
146
|
-
return
|
|
158
|
+
return info.Env().Undefined();
|
|
147
159
|
}
|
|
148
160
|
|
|
149
161
|
// read(deviceUuid, serviceUuid, characteristicUuid)
|
|
@@ -155,7 +167,7 @@ Napi::Value NobleWinrt::Read(const Napi::CallbackInfo& info)
|
|
|
155
167
|
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
156
168
|
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
157
169
|
manager->Read(uuid, service, characteristic);
|
|
158
|
-
return
|
|
170
|
+
return info.Env().Undefined();
|
|
159
171
|
}
|
|
160
172
|
|
|
161
173
|
// write(deviceUuid, serviceUuid, characteristicUuid, data, withoutResponse)
|
|
@@ -169,7 +181,7 @@ Napi::Value NobleWinrt::Write(const Napi::CallbackInfo& info)
|
|
|
169
181
|
auto data = napiToData(info[3].As<Napi::Buffer<unsigned char>>());
|
|
170
182
|
auto withoutResponse = info[4].As<Napi::Boolean>().Value();
|
|
171
183
|
manager->Write(uuid, service, characteristic, data, withoutResponse);
|
|
172
|
-
return
|
|
184
|
+
return info.Env().Undefined();
|
|
173
185
|
}
|
|
174
186
|
|
|
175
187
|
// notify(deviceUuid, serviceUuid, characteristicUuid, notify)
|
|
@@ -182,7 +194,7 @@ Napi::Value NobleWinrt::Notify(const Napi::CallbackInfo& info)
|
|
|
182
194
|
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
183
195
|
auto on = info[3].As<Napi::Boolean>().Value();
|
|
184
196
|
manager->Notify(uuid, service, characteristic, on);
|
|
185
|
-
return
|
|
197
|
+
return info.Env().Undefined();
|
|
186
198
|
}
|
|
187
199
|
|
|
188
200
|
// discoverDescriptors(deviceUuid, serviceUuid, characteristicUuid)
|
|
@@ -194,7 +206,7 @@ Napi::Value NobleWinrt::DiscoverDescriptors(const Napi::CallbackInfo& info)
|
|
|
194
206
|
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
195
207
|
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
196
208
|
manager->DiscoverDescriptors(uuid, service, characteristic);
|
|
197
|
-
return
|
|
209
|
+
return info.Env().Undefined();
|
|
198
210
|
}
|
|
199
211
|
|
|
200
212
|
// readValue(deviceUuid, serviceUuid, characteristicUuid, descriptorUuid)
|
|
@@ -207,7 +219,7 @@ Napi::Value NobleWinrt::ReadValue(const Napi::CallbackInfo& info)
|
|
|
207
219
|
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
208
220
|
auto descriptor = napiToUuid(info[3].As<Napi::String>());
|
|
209
221
|
manager->ReadValue(uuid, service, characteristic, descriptor);
|
|
210
|
-
return
|
|
222
|
+
return info.Env().Undefined();
|
|
211
223
|
}
|
|
212
224
|
|
|
213
225
|
// writeValue(deviceUuid, serviceUuid, characteristicUuid, descriptorUuid, data)
|
|
@@ -221,7 +233,7 @@ Napi::Value NobleWinrt::WriteValue(const Napi::CallbackInfo& info)
|
|
|
221
233
|
auto descriptor = napiToUuid(info[3].As<Napi::String>());
|
|
222
234
|
auto data = napiToData(info[4].As<Napi::Buffer<unsigned char>>());
|
|
223
235
|
manager->WriteValue(uuid, service, characteristic, descriptor, data);
|
|
224
|
-
return
|
|
236
|
+
return info.Env().Undefined();
|
|
225
237
|
}
|
|
226
238
|
|
|
227
239
|
// readHandle(deviceUuid, handle)
|
|
@@ -232,7 +244,7 @@ Napi::Value NobleWinrt::ReadHandle(const Napi::CallbackInfo& info)
|
|
|
232
244
|
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
233
245
|
auto handle = napiToNumber(info[1].As<Napi::Number>());
|
|
234
246
|
manager->ReadHandle(uuid, handle);
|
|
235
|
-
return
|
|
247
|
+
return info.Env().Undefined();
|
|
236
248
|
}
|
|
237
249
|
|
|
238
250
|
// writeHandle(deviceUuid, handle, data, (unused)withoutResponse)
|
|
@@ -244,26 +256,59 @@ Napi::Value NobleWinrt::WriteHandle(const Napi::CallbackInfo& info)
|
|
|
244
256
|
auto handle = napiToNumber(info[1].As<Napi::Number>());
|
|
245
257
|
auto data = napiToData(info[2].As<Napi::Buffer<unsigned char>>());
|
|
246
258
|
manager->WriteHandle(uuid, handle, data);
|
|
247
|
-
return
|
|
259
|
+
return info.Env().Undefined();
|
|
248
260
|
}
|
|
249
261
|
|
|
250
|
-
|
|
262
|
+
// addressToId(address)
|
|
263
|
+
Napi::Value NobleWinrt::AddressToId(const Napi::CallbackInfo& info)
|
|
251
264
|
{
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
265
|
+
ARG1(String)
|
|
266
|
+
try {
|
|
267
|
+
auto address = info[0].As<Napi::String>().Utf8Value();
|
|
268
|
+
std::string cleanUuid = address;
|
|
269
|
+
cleanUuid.erase(std::remove(cleanUuid.begin(), cleanUuid.end(), ':'), cleanUuid.end());
|
|
270
|
+
|
|
271
|
+
if (cleanUuid.length() != 12) {
|
|
272
|
+
return info.Env().Null();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (cleanUuid.find_first_not_of("0123456789ABCDEFabcdef") != std::string::npos) {
|
|
276
|
+
return info.Env().Null();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return Napi::String::New(info.Env(), cleanUuid.c_str());
|
|
280
|
+
} catch (const std::exception& e) {
|
|
281
|
+
return info.Env().Null();
|
|
282
|
+
}
|
|
256
283
|
}
|
|
257
284
|
|
|
258
|
-
|
|
259
|
-
{
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
285
|
+
#pragma comment(lib, "windowsapp")
|
|
286
|
+
Napi::Object NobleWinrt::Init(Napi::Env env, Napi::Object exports) {
|
|
287
|
+
Napi::HandleScope scope(env);
|
|
288
|
+
|
|
289
|
+
try
|
|
290
|
+
{
|
|
291
|
+
winrt::init_apartment();
|
|
292
|
+
}
|
|
293
|
+
catch (winrt::hresult_error hresult)
|
|
294
|
+
{
|
|
295
|
+
if (hresult.code() != RPC_E_CHANGED_MODE)
|
|
296
|
+
{
|
|
297
|
+
wprintf(L"Failed initializing apartment: %d %s", hresult.code().value,
|
|
298
|
+
hresult.message().c_str());
|
|
299
|
+
Napi::TypeError::New(env, "Failed initializing apartment").ThrowAsJavaScriptException();
|
|
300
|
+
return exports;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
Napi::Function func = DefineClass(env, "NobleWinrt", {
|
|
305
|
+
NobleWinrt::InstanceMethod("start", &NobleWinrt::Start),
|
|
306
|
+
NobleWinrt::InstanceMethod("stop", &NobleWinrt::Stop),
|
|
263
307
|
NobleWinrt::InstanceMethod("startScanning", &NobleWinrt::Scan),
|
|
264
308
|
NobleWinrt::InstanceMethod("stopScanning", &NobleWinrt::StopScan),
|
|
265
309
|
NobleWinrt::InstanceMethod("connect", &NobleWinrt::Connect),
|
|
266
310
|
NobleWinrt::InstanceMethod("disconnect", &NobleWinrt::Disconnect),
|
|
311
|
+
NobleWinrt::InstanceMethod("cancelConnect", &NobleWinrt::CancelConnect),
|
|
267
312
|
NobleWinrt::InstanceMethod("updateRssi", &NobleWinrt::UpdateRSSI),
|
|
268
313
|
NobleWinrt::InstanceMethod("discoverServices", &NobleWinrt::DiscoverServices),
|
|
269
314
|
NobleWinrt::InstanceMethod("discoverIncludedServices", &NobleWinrt::DiscoverIncludedServices),
|
|
@@ -276,33 +321,15 @@ Napi::Function NobleWinrt::GetClass(Napi::Env env)
|
|
|
276
321
|
NobleWinrt::InstanceMethod("writeValue", &NobleWinrt::WriteValue),
|
|
277
322
|
NobleWinrt::InstanceMethod("readHandle", &NobleWinrt::ReadHandle),
|
|
278
323
|
NobleWinrt::InstanceMethod("writeHandle", &NobleWinrt::WriteHandle),
|
|
279
|
-
NobleWinrt::InstanceMethod("
|
|
280
|
-
|
|
281
|
-
// clang-format on
|
|
282
|
-
}
|
|
324
|
+
NobleWinrt::InstanceMethod("addressToId", &NobleWinrt::AddressToId),
|
|
325
|
+
});
|
|
283
326
|
|
|
284
|
-
|
|
327
|
+
Napi::FunctionReference* constructor = new Napi::FunctionReference();
|
|
328
|
+
*constructor = Napi::Persistent(func);
|
|
329
|
+
env.SetInstanceData(constructor);
|
|
285
330
|
|
|
286
|
-
|
|
287
|
-
{
|
|
288
|
-
try
|
|
289
|
-
{
|
|
290
|
-
winrt::init_apartment();
|
|
291
|
-
}
|
|
292
|
-
catch (winrt::hresult_error hresult)
|
|
293
|
-
{
|
|
294
|
-
// electron already initialized the COM library
|
|
295
|
-
if (hresult.code() != RPC_E_CHANGED_MODE)
|
|
296
|
-
{
|
|
297
|
-
wprintf(L"Failed initializing apartment: %d %s", hresult.code().value,
|
|
298
|
-
hresult.message().c_str());
|
|
299
|
-
Napi::TypeError::New(env, "Failed initializing apartment").ThrowAsJavaScriptException();
|
|
300
|
-
return exports;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
Napi::String name = Napi::String::New(env, "NobleWinrt");
|
|
304
|
-
exports.Set(name, NobleWinrt::GetClass(env));
|
|
331
|
+
exports.Set("NobleWinrt", func);
|
|
305
332
|
return exports;
|
|
306
333
|
}
|
|
307
334
|
|
|
308
|
-
|
|
335
|
+
NODE_API_NAMED_ADDON(addon, NobleWinrt);
|
|
@@ -8,12 +8,13 @@ class NobleWinrt : public Napi::ObjectWrap<NobleWinrt>
|
|
|
8
8
|
{
|
|
9
9
|
public:
|
|
10
10
|
NobleWinrt(const Napi::CallbackInfo&);
|
|
11
|
-
Napi::Value
|
|
12
|
-
Napi::Value
|
|
11
|
+
Napi::Value Start(const Napi::CallbackInfo&);
|
|
12
|
+
Napi::Value Stop(const Napi::CallbackInfo&);
|
|
13
13
|
Napi::Value Scan(const Napi::CallbackInfo&);
|
|
14
14
|
Napi::Value StopScan(const Napi::CallbackInfo&);
|
|
15
15
|
Napi::Value Connect(const Napi::CallbackInfo&);
|
|
16
16
|
Napi::Value Disconnect(const Napi::CallbackInfo&);
|
|
17
|
+
Napi::Value CancelConnect(const Napi::CallbackInfo&);
|
|
17
18
|
Napi::Value UpdateRSSI(const Napi::CallbackInfo&);
|
|
18
19
|
Napi::Value DiscoverServices(const Napi::CallbackInfo&);
|
|
19
20
|
Napi::Value DiscoverIncludedServices(const Napi::CallbackInfo& info);
|
|
@@ -26,8 +27,9 @@ public:
|
|
|
26
27
|
Napi::Value WriteValue(const Napi::CallbackInfo& info);
|
|
27
28
|
Napi::Value ReadHandle(const Napi::CallbackInfo& info);
|
|
28
29
|
Napi::Value WriteHandle(const Napi::CallbackInfo& info);
|
|
30
|
+
Napi::Value AddressToId(const Napi::CallbackInfo& info);
|
|
29
31
|
|
|
30
|
-
static Napi::
|
|
32
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
31
33
|
|
|
32
34
|
private:
|
|
33
35
|
BLEManager* manager;
|
package/lib/win/src/notify_map.h
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
//
|
|
2
|
-
// notify_map.h
|
|
3
|
-
// noble-winrt-native
|
|
4
|
-
//
|
|
5
|
-
// Created by Georg Vienna on 07.09.18.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
1
|
#pragma once
|
|
9
2
|
|
|
10
|
-
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
|
11
3
|
#include "winrt_guid.h"
|
|
4
|
+
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
|
12
5
|
|
|
13
6
|
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
|
|
14
7
|
|
|
@@ -70,9 +70,14 @@ void PeripheralWinrt::ProcessServiceData(const BluetoothLEAdvertisementDataSecti
|
|
|
70
70
|
data.resize(d.Length() - uuidSize);
|
|
71
71
|
dr.ReadBytes(data);
|
|
72
72
|
|
|
73
|
+
// Initialize serviceData if it doesn't exist
|
|
74
|
+
if (!serviceData.has_value()) {
|
|
75
|
+
serviceData = std::vector<std::pair<std::string, Data>>();
|
|
76
|
+
}
|
|
77
|
+
|
|
73
78
|
// Find and update existing entry or add new one
|
|
74
79
|
bool found = false;
|
|
75
|
-
for (auto& pair : serviceData) {
|
|
80
|
+
for (auto& pair : serviceData.value()) {
|
|
76
81
|
if (pair.first == uuidStr) {
|
|
77
82
|
pair.second = data;
|
|
78
83
|
found = true;
|
|
@@ -81,7 +86,7 @@ void PeripheralWinrt::ProcessServiceData(const BluetoothLEAdvertisementDataSecti
|
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
if (!found) {
|
|
84
|
-
serviceData.push_back(std::make_pair(uuidStr, data));
|
|
89
|
+
serviceData.value().push_back(std::make_pair(uuidStr, data));
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
dr.Close();
|
|
@@ -90,16 +95,20 @@ void PeripheralWinrt::ProcessServiceData(const BluetoothLEAdvertisementDataSecti
|
|
|
90
95
|
void PeripheralWinrt::Update(const int rssiValue, const BluetoothLEAdvertisement& advertisment,
|
|
91
96
|
const BluetoothLEAdvertisementType& advertismentType)
|
|
92
97
|
{
|
|
98
|
+
// Handle name
|
|
93
99
|
std::string localName = ws2s(advertisment.LocalName().c_str());
|
|
94
100
|
if (!localName.empty())
|
|
95
101
|
{
|
|
96
|
-
name = localName;
|
|
102
|
+
name = std::optional<std::string>(localName);
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
connectable = advertismentType == BluetoothLEAdvertisementType::ConnectableUndirected ||
|
|
100
106
|
advertismentType == BluetoothLEAdvertisementType::ConnectableDirected;
|
|
101
107
|
|
|
102
|
-
|
|
108
|
+
// Reset optional values
|
|
109
|
+
manufacturerData = std::nullopt;
|
|
110
|
+
serviceData = std::nullopt;
|
|
111
|
+
serviceUuids = std::nullopt;
|
|
103
112
|
|
|
104
113
|
for (auto ds : advertisment.DataSections())
|
|
105
114
|
{
|
|
@@ -107,17 +116,20 @@ void PeripheralWinrt::Update(const int rssiValue, const BluetoothLEAdvertisement
|
|
|
107
116
|
{
|
|
108
117
|
auto d = ds.Data();
|
|
109
118
|
auto dr = DataReader::FromBuffer(d);
|
|
110
|
-
|
|
111
|
-
if (
|
|
112
|
-
|
|
119
|
+
int power = dr.ReadByte();
|
|
120
|
+
if (power >= 128)
|
|
121
|
+
power -= 256;
|
|
122
|
+
txPowerLevel = std::optional<int>(power);
|
|
113
123
|
dr.Close();
|
|
114
124
|
}
|
|
115
125
|
else if (ds.DataType() == BluetoothLEAdvertisementDataTypes::ManufacturerSpecificData())
|
|
116
126
|
{
|
|
117
127
|
auto d = ds.Data();
|
|
118
128
|
auto dr = DataReader::FromBuffer(d);
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
Data mData;
|
|
130
|
+
mData.resize(d.Length());
|
|
131
|
+
dr.ReadBytes(mData);
|
|
132
|
+
manufacturerData = std::optional<Data>(mData);
|
|
121
133
|
dr.Close();
|
|
122
134
|
}
|
|
123
135
|
else if (ds.DataType() == BluetoothLEAdvertisementDataTypes::ServiceData16BitUuids())
|
|
@@ -134,10 +146,15 @@ void PeripheralWinrt::Update(const int rssiValue, const BluetoothLEAdvertisement
|
|
|
134
146
|
}
|
|
135
147
|
}
|
|
136
148
|
|
|
137
|
-
|
|
149
|
+
// Handle service UUIDs
|
|
150
|
+
std::vector<std::string> uuids;
|
|
138
151
|
for (auto uuid : advertisment.ServiceUuids())
|
|
139
152
|
{
|
|
140
|
-
|
|
153
|
+
uuids.push_back(toStr(uuid));
|
|
154
|
+
}
|
|
155
|
+
if (!uuids.empty())
|
|
156
|
+
{
|
|
157
|
+
serviceUuids = std::optional<std::vector<std::string>>(uuids);
|
|
141
158
|
}
|
|
142
159
|
|
|
143
160
|
rssi = rssiValue;
|
|
@@ -148,6 +165,7 @@ void PeripheralWinrt::Disconnect()
|
|
|
148
165
|
cachedServices.clear();
|
|
149
166
|
if (device.has_value() && connectionToken)
|
|
150
167
|
{
|
|
168
|
+
device->Close();
|
|
151
169
|
device->ConnectionStatusChanged(connectionToken);
|
|
152
170
|
}
|
|
153
171
|
device = std::nullopt;
|