@stoprocent/noble 1.9.2-16
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/.editorconfig +11 -0
- package/.eslintrc.js +25 -0
- package/.github/FUNDING.yml +2 -0
- package/.github/workflows/fediverse-action.yml +16 -0
- package/.github/workflows/nodepackage.yml +77 -0
- package/.github/workflows/npm-publish.yml +26 -0
- package/.github/workflows/prebuild.yml +65 -0
- package/.nycrc.json +4 -0
- package/CHANGELOG.md +119 -0
- package/LICENSE +20 -0
- package/MAINTAINERS.md +1 -0
- package/README.md +833 -0
- package/assets/noble-logo.png +0 -0
- package/assets/noble-logo.svg +13 -0
- package/binding.gyp +19 -0
- package/codecov.yml +5 -0
- package/examples/advertisement-discovery.js +65 -0
- package/examples/cache-gatt-discovery.js +198 -0
- package/examples/cache-gatt-reconnect.js +164 -0
- package/examples/echo.js +104 -0
- package/examples/enter-exit.js +78 -0
- package/examples/peripheral-explorer-async.js +133 -0
- package/examples/peripheral-explorer.js +225 -0
- package/examples/pizza/README.md +15 -0
- package/examples/pizza/central.js +194 -0
- package/examples/pizza/pizza.js +60 -0
- package/index.d.ts +203 -0
- package/index.js +6 -0
- package/lib/characteristic.js +161 -0
- package/lib/characteristics.json +449 -0
- package/lib/descriptor.js +72 -0
- package/lib/descriptors.json +47 -0
- package/lib/distributed/bindings.js +326 -0
- package/lib/hci-socket/acl-stream.js +60 -0
- package/lib/hci-socket/bindings.js +788 -0
- package/lib/hci-socket/crypto.js +74 -0
- package/lib/hci-socket/gap.js +432 -0
- package/lib/hci-socket/gatt.js +809 -0
- package/lib/hci-socket/hci-status.json +71 -0
- package/lib/hci-socket/hci.js +1264 -0
- package/lib/hci-socket/signaling.js +76 -0
- package/lib/hci-socket/smp.js +140 -0
- package/lib/hci-uart/bindings.js +569 -0
- package/lib/hci-uart/hci-serial-parser.js +70 -0
- package/lib/hci-uart/hci.js +1336 -0
- package/lib/mac/binding.gyp +26 -0
- package/lib/mac/bindings.js +11 -0
- package/lib/mac/src/ble_manager.h +41 -0
- package/lib/mac/src/ble_manager.mm +435 -0
- package/lib/mac/src/callbacks.cc +222 -0
- package/lib/mac/src/callbacks.h +84 -0
- package/lib/mac/src/napi_objc.h +12 -0
- package/lib/mac/src/napi_objc.mm +50 -0
- package/lib/mac/src/noble_mac.h +34 -0
- package/lib/mac/src/noble_mac.mm +264 -0
- package/lib/mac/src/objc_cpp.h +26 -0
- package/lib/mac/src/objc_cpp.mm +126 -0
- package/lib/mac/src/peripheral.h +23 -0
- package/lib/manufacture.js +48 -0
- package/lib/noble.js +593 -0
- package/lib/peripheral.js +219 -0
- package/lib/resolve-bindings-web.js +9 -0
- package/lib/resolve-bindings.js +44 -0
- package/lib/service.js +72 -0
- package/lib/services.json +92 -0
- package/lib/webbluetooth/bindings.js +368 -0
- package/lib/websocket/bindings.js +321 -0
- package/lib/win/binding.gyp +23 -0
- package/lib/win/bindings.js +11 -0
- package/lib/win/src/ble_manager.cc +802 -0
- package/lib/win/src/ble_manager.h +77 -0
- package/lib/win/src/callbacks.cc +274 -0
- package/lib/win/src/callbacks.h +33 -0
- package/lib/win/src/napi_winrt.cc +76 -0
- package/lib/win/src/napi_winrt.h +12 -0
- package/lib/win/src/noble_winrt.cc +308 -0
- package/lib/win/src/noble_winrt.h +34 -0
- package/lib/win/src/notify_map.cc +62 -0
- package/lib/win/src/notify_map.h +50 -0
- package/lib/win/src/peripheral.h +23 -0
- package/lib/win/src/peripheral_winrt.cc +296 -0
- package/lib/win/src/peripheral_winrt.h +82 -0
- package/lib/win/src/radio_watcher.cc +125 -0
- package/lib/win/src/radio_watcher.h +61 -0
- package/lib/win/src/winrt_cpp.cc +82 -0
- package/lib/win/src/winrt_cpp.h +11 -0
- package/lib/win/src/winrt_guid.cc +12 -0
- package/lib/win/src/winrt_guid.h +13 -0
- package/misc/nrf52840dk.hex +6921 -0
- package/misc/prj.conf +43 -0
- package/package.json +96 -0
- package/test/lib/characteristic.test.js +791 -0
- package/test/lib/descriptor.test.js +249 -0
- package/test/lib/distributed/bindings.test.js +918 -0
- package/test/lib/hci-socket/acl-stream.test.js +188 -0
- package/test/lib/hci-socket/bindings.test.js +1756 -0
- package/test/lib/hci-socket/crypto.test.js +55 -0
- package/test/lib/hci-socket/gap.test.js +1089 -0
- package/test/lib/hci-socket/gatt.test.js +2392 -0
- package/test/lib/hci-socket/hci.test.js +1891 -0
- package/test/lib/hci-socket/signaling.test.js +94 -0
- package/test/lib/hci-socket/smp.test.js +268 -0
- package/test/lib/manufacture.test.js +77 -0
- package/test/lib/peripheral.test.js +623 -0
- package/test/lib/resolve-bindings.test.js +102 -0
- package/test/lib/service.test.js +195 -0
- package/test/lib/webbluetooth/bindings.test.js +190 -0
- package/test/lib/websocket/bindings.test.js +456 -0
- package/test/noble.test.js +1565 -0
- package/test.js +131 -0
- package/with-bindings.js +5 -0
- package/ws-slave.js +404 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
//
|
|
2
|
+
// noble_winrt.cc
|
|
3
|
+
// noble-winrt-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Georg Vienna on 03.09.18.
|
|
6
|
+
//
|
|
7
|
+
#include "noble_winrt.h"
|
|
8
|
+
|
|
9
|
+
#include "napi_winrt.h"
|
|
10
|
+
|
|
11
|
+
#define THROW(msg) \
|
|
12
|
+
Napi::TypeError::New(info.Env(), msg).ThrowAsJavaScriptException(); \
|
|
13
|
+
return Napi::Value();
|
|
14
|
+
|
|
15
|
+
#define ARG1(type1) \
|
|
16
|
+
if (!info[0].Is##type1()) \
|
|
17
|
+
{ \
|
|
18
|
+
THROW("There should be one argument: (" #type1 ")") \
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#define ARG2(type1, type2) \
|
|
22
|
+
if (!info[0].Is##type1() || !info[1].Is##type2()) \
|
|
23
|
+
{ \
|
|
24
|
+
THROW("There should be 2 arguments: (" #type1 ", " #type2 ")"); \
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#define ARG3(type1, type2, type3) \
|
|
28
|
+
if (!info[0].Is##type1() || !info[1].Is##type2() || !info[2].Is##type3()) \
|
|
29
|
+
{ \
|
|
30
|
+
THROW("There should be 3 arguments: (" #type1 ", " #type2 ", " #type3 ")"); \
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#define ARG4(type1, type2, type3, type4) \
|
|
34
|
+
if (!info[0].Is##type1() || !info[1].Is##type2() || !info[2].Is##type3() || \
|
|
35
|
+
!info[3].Is##type4()) \
|
|
36
|
+
{ \
|
|
37
|
+
THROW("There should be 4 arguments: (" #type1 ", " #type2 ", " #type3 ", " #type4 ")"); \
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#define ARG5(type1, type2, type3, type4, type5) \
|
|
41
|
+
if (!info[0].Is##type1() || !info[1].Is##type2() || !info[2].Is##type3() || \
|
|
42
|
+
!info[3].Is##type4() || !info[4].Is##type5()) \
|
|
43
|
+
{ \
|
|
44
|
+
THROW("There should be 5 arguments: (" #type1 ", " #type2 ", " #type3 ", " #type4 \
|
|
45
|
+
", " #type5 ")"); \
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#define CHECK_MANAGER() \
|
|
49
|
+
if (!manager) \
|
|
50
|
+
{ \
|
|
51
|
+
THROW("BLEManager has already been cleaned up"); \
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
NobleWinrt::NobleWinrt(const Napi::CallbackInfo& info) : ObjectWrap(info)
|
|
55
|
+
{
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
Napi::Value NobleWinrt::Init(const Napi::CallbackInfo& info)
|
|
59
|
+
{
|
|
60
|
+
Napi::Function emit = info.This().As<Napi::Object>().Get("emit").As<Napi::Function>();
|
|
61
|
+
manager = new BLEManager(info.This(), emit);
|
|
62
|
+
return Napi::Value();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// startScanning(serviceUuids, allowDuplicates)
|
|
66
|
+
Napi::Value NobleWinrt::Scan(const Napi::CallbackInfo& info)
|
|
67
|
+
{
|
|
68
|
+
CHECK_MANAGER()
|
|
69
|
+
auto vector = getUuidArray(info[0]);
|
|
70
|
+
// default value false
|
|
71
|
+
auto duplicates = getBool(info[1], false);
|
|
72
|
+
manager->Scan(vector, duplicates);
|
|
73
|
+
return Napi::Value();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// stopScanning()
|
|
77
|
+
Napi::Value NobleWinrt::StopScan(const Napi::CallbackInfo& info)
|
|
78
|
+
{
|
|
79
|
+
CHECK_MANAGER()
|
|
80
|
+
manager->StopScan();
|
|
81
|
+
return Napi::Value();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// connect(deviceUuid)
|
|
85
|
+
Napi::Value NobleWinrt::Connect(const Napi::CallbackInfo& info)
|
|
86
|
+
{
|
|
87
|
+
CHECK_MANAGER()
|
|
88
|
+
ARG1(String)
|
|
89
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
90
|
+
manager->Connect(uuid);
|
|
91
|
+
return Napi::Value();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// disconnect(deviceUuid)
|
|
95
|
+
Napi::Value NobleWinrt::Disconnect(const Napi::CallbackInfo& info)
|
|
96
|
+
{
|
|
97
|
+
CHECK_MANAGER()
|
|
98
|
+
ARG1(String)
|
|
99
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
100
|
+
manager->Disconnect(uuid);
|
|
101
|
+
return Napi::Value();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// updateRssi(deviceUuid)
|
|
105
|
+
Napi::Value NobleWinrt::UpdateRSSI(const Napi::CallbackInfo& info)
|
|
106
|
+
{
|
|
107
|
+
CHECK_MANAGER()
|
|
108
|
+
ARG1(String)
|
|
109
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
110
|
+
manager->UpdateRSSI(uuid);
|
|
111
|
+
return Napi::Value();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// discoverServices(deviceUuid, uuids)
|
|
115
|
+
Napi::Value NobleWinrt::DiscoverServices(const Napi::CallbackInfo& info)
|
|
116
|
+
{
|
|
117
|
+
CHECK_MANAGER()
|
|
118
|
+
ARG1(String)
|
|
119
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
120
|
+
std::vector<winrt::guid> uuids = getUuidArray(info[1]);
|
|
121
|
+
manager->DiscoverServices(uuid, uuids);
|
|
122
|
+
return Napi::Value();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// discoverIncludedServices(deviceUuid, serviceUuid, serviceUuids)
|
|
126
|
+
Napi::Value NobleWinrt::DiscoverIncludedServices(const Napi::CallbackInfo& info)
|
|
127
|
+
{
|
|
128
|
+
CHECK_MANAGER()
|
|
129
|
+
ARG2(String, String)
|
|
130
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
131
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
132
|
+
std::vector<winrt::guid> uuids = getUuidArray(info[2]);
|
|
133
|
+
manager->DiscoverIncludedServices(uuid, service, uuids);
|
|
134
|
+
return Napi::Value();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// discoverCharacteristics(deviceUuid, serviceUuid, characteristicUuids)
|
|
138
|
+
Napi::Value NobleWinrt::DiscoverCharacteristics(const Napi::CallbackInfo& info)
|
|
139
|
+
{
|
|
140
|
+
CHECK_MANAGER()
|
|
141
|
+
ARG2(String, String)
|
|
142
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
143
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
144
|
+
std::vector<winrt::guid> characteristics = getUuidArray(info[2]);
|
|
145
|
+
manager->DiscoverCharacteristics(uuid, service, characteristics);
|
|
146
|
+
return Napi::Value();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// read(deviceUuid, serviceUuid, characteristicUuid)
|
|
150
|
+
Napi::Value NobleWinrt::Read(const Napi::CallbackInfo& info)
|
|
151
|
+
{
|
|
152
|
+
CHECK_MANAGER()
|
|
153
|
+
ARG3(String, String, String)
|
|
154
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
155
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
156
|
+
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
157
|
+
manager->Read(uuid, service, characteristic);
|
|
158
|
+
return Napi::Value();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// write(deviceUuid, serviceUuid, characteristicUuid, data, withoutResponse)
|
|
162
|
+
Napi::Value NobleWinrt::Write(const Napi::CallbackInfo& info)
|
|
163
|
+
{
|
|
164
|
+
CHECK_MANAGER()
|
|
165
|
+
ARG5(String, String, String, Buffer, Boolean)
|
|
166
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
167
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
168
|
+
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
169
|
+
auto data = napiToData(info[3].As<Napi::Buffer<unsigned char>>());
|
|
170
|
+
auto withoutResponse = info[4].As<Napi::Boolean>().Value();
|
|
171
|
+
manager->Write(uuid, service, characteristic, data, withoutResponse);
|
|
172
|
+
return Napi::Value();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// notify(deviceUuid, serviceUuid, characteristicUuid, notify)
|
|
176
|
+
Napi::Value NobleWinrt::Notify(const Napi::CallbackInfo& info)
|
|
177
|
+
{
|
|
178
|
+
CHECK_MANAGER()
|
|
179
|
+
ARG4(String, String, String, Boolean)
|
|
180
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
181
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
182
|
+
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
183
|
+
auto on = info[3].As<Napi::Boolean>().Value();
|
|
184
|
+
manager->Notify(uuid, service, characteristic, on);
|
|
185
|
+
return Napi::Value();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// discoverDescriptors(deviceUuid, serviceUuid, characteristicUuid)
|
|
189
|
+
Napi::Value NobleWinrt::DiscoverDescriptors(const Napi::CallbackInfo& info)
|
|
190
|
+
{
|
|
191
|
+
CHECK_MANAGER()
|
|
192
|
+
ARG3(String, String, String)
|
|
193
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
194
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
195
|
+
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
196
|
+
manager->DiscoverDescriptors(uuid, service, characteristic);
|
|
197
|
+
return Napi::Value();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// readValue(deviceUuid, serviceUuid, characteristicUuid, descriptorUuid)
|
|
201
|
+
Napi::Value NobleWinrt::ReadValue(const Napi::CallbackInfo& info)
|
|
202
|
+
{
|
|
203
|
+
CHECK_MANAGER()
|
|
204
|
+
ARG4(String, String, String, String)
|
|
205
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
206
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
207
|
+
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
208
|
+
auto descriptor = napiToUuid(info[3].As<Napi::String>());
|
|
209
|
+
manager->ReadValue(uuid, service, characteristic, descriptor);
|
|
210
|
+
return Napi::Value();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// writeValue(deviceUuid, serviceUuid, characteristicUuid, descriptorUuid, data)
|
|
214
|
+
Napi::Value NobleWinrt::WriteValue(const Napi::CallbackInfo& info)
|
|
215
|
+
{
|
|
216
|
+
CHECK_MANAGER()
|
|
217
|
+
ARG5(String, String, String, String, Buffer)
|
|
218
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
219
|
+
auto service = napiToUuid(info[1].As<Napi::String>());
|
|
220
|
+
auto characteristic = napiToUuid(info[2].As<Napi::String>());
|
|
221
|
+
auto descriptor = napiToUuid(info[3].As<Napi::String>());
|
|
222
|
+
auto data = napiToData(info[4].As<Napi::Buffer<unsigned char>>());
|
|
223
|
+
manager->WriteValue(uuid, service, characteristic, descriptor, data);
|
|
224
|
+
return Napi::Value();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// readHandle(deviceUuid, handle)
|
|
228
|
+
Napi::Value NobleWinrt::ReadHandle(const Napi::CallbackInfo& info)
|
|
229
|
+
{
|
|
230
|
+
CHECK_MANAGER()
|
|
231
|
+
ARG2(String, Number)
|
|
232
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
233
|
+
auto handle = napiToNumber(info[1].As<Napi::Number>());
|
|
234
|
+
manager->ReadHandle(uuid, handle);
|
|
235
|
+
return Napi::Value();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// writeHandle(deviceUuid, handle, data, (unused)withoutResponse)
|
|
239
|
+
Napi::Value NobleWinrt::WriteHandle(const Napi::CallbackInfo& info)
|
|
240
|
+
{
|
|
241
|
+
CHECK_MANAGER()
|
|
242
|
+
ARG3(String, Number, Buffer)
|
|
243
|
+
auto uuid = info[0].As<Napi::String>().Utf8Value();
|
|
244
|
+
auto handle = napiToNumber(info[1].As<Napi::Number>());
|
|
245
|
+
auto data = napiToData(info[2].As<Napi::Buffer<unsigned char>>());
|
|
246
|
+
manager->WriteHandle(uuid, handle, data);
|
|
247
|
+
return Napi::Value();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
Napi::Value NobleWinrt::CleanUp(const Napi::CallbackInfo& info)
|
|
251
|
+
{
|
|
252
|
+
CHECK_MANAGER()
|
|
253
|
+
delete manager;
|
|
254
|
+
manager = nullptr;
|
|
255
|
+
return Napi::Value();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
Napi::Function NobleWinrt::GetClass(Napi::Env env)
|
|
259
|
+
{
|
|
260
|
+
// clang-format off
|
|
261
|
+
return DefineClass(env, "NobleWinrt", {
|
|
262
|
+
NobleWinrt::InstanceMethod("init", &NobleWinrt::Init),
|
|
263
|
+
NobleWinrt::InstanceMethod("startScanning", &NobleWinrt::Scan),
|
|
264
|
+
NobleWinrt::InstanceMethod("stopScanning", &NobleWinrt::StopScan),
|
|
265
|
+
NobleWinrt::InstanceMethod("connect", &NobleWinrt::Connect),
|
|
266
|
+
NobleWinrt::InstanceMethod("disconnect", &NobleWinrt::Disconnect),
|
|
267
|
+
NobleWinrt::InstanceMethod("updateRssi", &NobleWinrt::UpdateRSSI),
|
|
268
|
+
NobleWinrt::InstanceMethod("discoverServices", &NobleWinrt::DiscoverServices),
|
|
269
|
+
NobleWinrt::InstanceMethod("discoverIncludedServices", &NobleWinrt::DiscoverIncludedServices),
|
|
270
|
+
NobleWinrt::InstanceMethod("discoverCharacteristics", &NobleWinrt::DiscoverCharacteristics),
|
|
271
|
+
NobleWinrt::InstanceMethod("read", &NobleWinrt::Read),
|
|
272
|
+
NobleWinrt::InstanceMethod("write", &NobleWinrt::Write),
|
|
273
|
+
NobleWinrt::InstanceMethod("notify", &NobleWinrt::Notify),
|
|
274
|
+
NobleWinrt::InstanceMethod("discoverDescriptors", &NobleWinrt::DiscoverDescriptors),
|
|
275
|
+
NobleWinrt::InstanceMethod("readValue", &NobleWinrt::ReadValue),
|
|
276
|
+
NobleWinrt::InstanceMethod("writeValue", &NobleWinrt::WriteValue),
|
|
277
|
+
NobleWinrt::InstanceMethod("readHandle", &NobleWinrt::ReadHandle),
|
|
278
|
+
NobleWinrt::InstanceMethod("writeHandle", &NobleWinrt::WriteHandle),
|
|
279
|
+
NobleWinrt::InstanceMethod("cleanUp", &NobleWinrt::CleanUp),
|
|
280
|
+
});
|
|
281
|
+
// clang-format on
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#pragma comment(lib, "windowsapp")
|
|
285
|
+
|
|
286
|
+
Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
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));
|
|
305
|
+
return exports;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
NODE_API_MODULE(addon, Init)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <napi.h>
|
|
4
|
+
|
|
5
|
+
#include "ble_manager.h"
|
|
6
|
+
|
|
7
|
+
class NobleWinrt : public Napi::ObjectWrap<NobleWinrt>
|
|
8
|
+
{
|
|
9
|
+
public:
|
|
10
|
+
NobleWinrt(const Napi::CallbackInfo&);
|
|
11
|
+
Napi::Value Init(const Napi::CallbackInfo&);
|
|
12
|
+
Napi::Value CleanUp(const Napi::CallbackInfo&);
|
|
13
|
+
Napi::Value Scan(const Napi::CallbackInfo&);
|
|
14
|
+
Napi::Value StopScan(const Napi::CallbackInfo&);
|
|
15
|
+
Napi::Value Connect(const Napi::CallbackInfo&);
|
|
16
|
+
Napi::Value Disconnect(const Napi::CallbackInfo&);
|
|
17
|
+
Napi::Value UpdateRSSI(const Napi::CallbackInfo&);
|
|
18
|
+
Napi::Value DiscoverServices(const Napi::CallbackInfo&);
|
|
19
|
+
Napi::Value DiscoverIncludedServices(const Napi::CallbackInfo& info);
|
|
20
|
+
Napi::Value DiscoverCharacteristics(const Napi::CallbackInfo& info);
|
|
21
|
+
Napi::Value Read(const Napi::CallbackInfo& info);
|
|
22
|
+
Napi::Value Write(const Napi::CallbackInfo& info);
|
|
23
|
+
Napi::Value Notify(const Napi::CallbackInfo& info);
|
|
24
|
+
Napi::Value DiscoverDescriptors(const Napi::CallbackInfo& info);
|
|
25
|
+
Napi::Value ReadValue(const Napi::CallbackInfo& info);
|
|
26
|
+
Napi::Value WriteValue(const Napi::CallbackInfo& info);
|
|
27
|
+
Napi::Value ReadHandle(const Napi::CallbackInfo& info);
|
|
28
|
+
Napi::Value WriteHandle(const Napi::CallbackInfo& info);
|
|
29
|
+
|
|
30
|
+
static Napi::Function GetClass(Napi::Env);
|
|
31
|
+
|
|
32
|
+
private:
|
|
33
|
+
BLEManager* manager;
|
|
34
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//
|
|
2
|
+
// notify_map.cc
|
|
3
|
+
// noble-winrt-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Georg Vienna on 07.09.18.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#include "notify_map.h"
|
|
9
|
+
|
|
10
|
+
bool Key::operator==(const Key& other) const
|
|
11
|
+
{
|
|
12
|
+
return (uuid == other.uuid && serviceUuid == other.serviceUuid &&
|
|
13
|
+
characteristicUuid == other.characteristicUuid);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
void NotifyMap::Add(std::string uuid, GattCharacteristic characteristic, winrt::event_token token)
|
|
17
|
+
{
|
|
18
|
+
Key key = { uuid, characteristic.Service().Uuid(), characteristic.Uuid() };
|
|
19
|
+
mNotifyMap.insert(std::make_pair(key, token));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
bool NotifyMap::IsSubscribed(std::string uuid, GattCharacteristic characteristic)
|
|
23
|
+
{
|
|
24
|
+
try
|
|
25
|
+
{
|
|
26
|
+
Key key = { uuid, characteristic.Service().Uuid(), characteristic.Uuid() };
|
|
27
|
+
return mNotifyMap.find(key) != mNotifyMap.end();
|
|
28
|
+
}
|
|
29
|
+
catch (...)
|
|
30
|
+
{
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
void NotifyMap::Unsubscribe(std::string uuid, GattCharacteristic characteristic)
|
|
36
|
+
{
|
|
37
|
+
Key key = { uuid, characteristic.Service().Uuid(), characteristic.Uuid() };
|
|
38
|
+
auto it = mNotifyMap.find(key);
|
|
39
|
+
if (it == mNotifyMap.end())
|
|
40
|
+
{
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
auto& token = it->second;
|
|
44
|
+
characteristic.ValueChanged(token);
|
|
45
|
+
mNotifyMap.erase(key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
void NotifyMap::Remove(std::string uuid)
|
|
49
|
+
{
|
|
50
|
+
for (auto it = mNotifyMap.begin(); it != mNotifyMap.end();)
|
|
51
|
+
{
|
|
52
|
+
auto& key = it->first;
|
|
53
|
+
if (key.uuid == uuid)
|
|
54
|
+
{
|
|
55
|
+
it = mNotifyMap.erase(it);
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
{
|
|
59
|
+
it++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// notify_map.h
|
|
3
|
+
// noble-winrt-native
|
|
4
|
+
//
|
|
5
|
+
// Created by Georg Vienna on 07.09.18.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
|
11
|
+
#include "winrt_guid.h"
|
|
12
|
+
|
|
13
|
+
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
|
|
14
|
+
|
|
15
|
+
struct Key
|
|
16
|
+
{
|
|
17
|
+
public:
|
|
18
|
+
std::string uuid;
|
|
19
|
+
winrt::guid serviceUuid;
|
|
20
|
+
winrt::guid characteristicUuid;
|
|
21
|
+
|
|
22
|
+
bool operator==(const Key& other) const;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
namespace std
|
|
26
|
+
{
|
|
27
|
+
template <> struct hash<Key>
|
|
28
|
+
{
|
|
29
|
+
std::size_t operator()(const Key& k) const
|
|
30
|
+
{
|
|
31
|
+
auto serviceHash = std::hash<winrt::guid>()(k.serviceUuid);
|
|
32
|
+
auto characteristicHash = std::hash<winrt::guid>()(k.characteristicUuid);
|
|
33
|
+
return ((std::hash<std::string>()(k.uuid) ^ (serviceHash << 1)) >> 1) ^
|
|
34
|
+
(characteristicHash << 1);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
} // namespace std
|
|
38
|
+
|
|
39
|
+
class NotifyMap
|
|
40
|
+
{
|
|
41
|
+
public:
|
|
42
|
+
void Add(std::string uuid, GattCharacteristic characteristic, winrt::event_token token);
|
|
43
|
+
bool IsSubscribed(std::string uuid, GattCharacteristic characteristic);
|
|
44
|
+
void Unsubscribe(std::string uuid, GattCharacteristic characteristic);
|
|
45
|
+
|
|
46
|
+
void Remove(std::string uuid);
|
|
47
|
+
|
|
48
|
+
private:
|
|
49
|
+
std::unordered_map<Key, winrt::event_token> mNotifyMap;
|
|
50
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
using Data = std::vector<uint8_t>;
|
|
4
|
+
|
|
5
|
+
enum AddressType
|
|
6
|
+
{
|
|
7
|
+
PUBLIC,
|
|
8
|
+
RANDOM,
|
|
9
|
+
UNKNOWN,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
class Peripheral
|
|
13
|
+
{
|
|
14
|
+
public:
|
|
15
|
+
std::string address = "unknown";
|
|
16
|
+
AddressType addressType = UNKNOWN;
|
|
17
|
+
bool connectable = false;
|
|
18
|
+
std::string name;
|
|
19
|
+
int txPowerLevel;
|
|
20
|
+
Data manufacturerData;
|
|
21
|
+
std::vector<std::pair<std::string, Data>> serviceData;
|
|
22
|
+
std::vector<std::string> serviceUuids;
|
|
23
|
+
};
|