@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.
Files changed (112) hide show
  1. package/.editorconfig +11 -0
  2. package/.eslintrc.js +25 -0
  3. package/.github/FUNDING.yml +2 -0
  4. package/.github/workflows/fediverse-action.yml +16 -0
  5. package/.github/workflows/nodepackage.yml +77 -0
  6. package/.github/workflows/npm-publish.yml +26 -0
  7. package/.github/workflows/prebuild.yml +65 -0
  8. package/.nycrc.json +4 -0
  9. package/CHANGELOG.md +119 -0
  10. package/LICENSE +20 -0
  11. package/MAINTAINERS.md +1 -0
  12. package/README.md +833 -0
  13. package/assets/noble-logo.png +0 -0
  14. package/assets/noble-logo.svg +13 -0
  15. package/binding.gyp +19 -0
  16. package/codecov.yml +5 -0
  17. package/examples/advertisement-discovery.js +65 -0
  18. package/examples/cache-gatt-discovery.js +198 -0
  19. package/examples/cache-gatt-reconnect.js +164 -0
  20. package/examples/echo.js +104 -0
  21. package/examples/enter-exit.js +78 -0
  22. package/examples/peripheral-explorer-async.js +133 -0
  23. package/examples/peripheral-explorer.js +225 -0
  24. package/examples/pizza/README.md +15 -0
  25. package/examples/pizza/central.js +194 -0
  26. package/examples/pizza/pizza.js +60 -0
  27. package/index.d.ts +203 -0
  28. package/index.js +6 -0
  29. package/lib/characteristic.js +161 -0
  30. package/lib/characteristics.json +449 -0
  31. package/lib/descriptor.js +72 -0
  32. package/lib/descriptors.json +47 -0
  33. package/lib/distributed/bindings.js +326 -0
  34. package/lib/hci-socket/acl-stream.js +60 -0
  35. package/lib/hci-socket/bindings.js +788 -0
  36. package/lib/hci-socket/crypto.js +74 -0
  37. package/lib/hci-socket/gap.js +432 -0
  38. package/lib/hci-socket/gatt.js +809 -0
  39. package/lib/hci-socket/hci-status.json +71 -0
  40. package/lib/hci-socket/hci.js +1264 -0
  41. package/lib/hci-socket/signaling.js +76 -0
  42. package/lib/hci-socket/smp.js +140 -0
  43. package/lib/hci-uart/bindings.js +569 -0
  44. package/lib/hci-uart/hci-serial-parser.js +70 -0
  45. package/lib/hci-uart/hci.js +1336 -0
  46. package/lib/mac/binding.gyp +26 -0
  47. package/lib/mac/bindings.js +11 -0
  48. package/lib/mac/src/ble_manager.h +41 -0
  49. package/lib/mac/src/ble_manager.mm +435 -0
  50. package/lib/mac/src/callbacks.cc +222 -0
  51. package/lib/mac/src/callbacks.h +84 -0
  52. package/lib/mac/src/napi_objc.h +12 -0
  53. package/lib/mac/src/napi_objc.mm +50 -0
  54. package/lib/mac/src/noble_mac.h +34 -0
  55. package/lib/mac/src/noble_mac.mm +264 -0
  56. package/lib/mac/src/objc_cpp.h +26 -0
  57. package/lib/mac/src/objc_cpp.mm +126 -0
  58. package/lib/mac/src/peripheral.h +23 -0
  59. package/lib/manufacture.js +48 -0
  60. package/lib/noble.js +593 -0
  61. package/lib/peripheral.js +219 -0
  62. package/lib/resolve-bindings-web.js +9 -0
  63. package/lib/resolve-bindings.js +44 -0
  64. package/lib/service.js +72 -0
  65. package/lib/services.json +92 -0
  66. package/lib/webbluetooth/bindings.js +368 -0
  67. package/lib/websocket/bindings.js +321 -0
  68. package/lib/win/binding.gyp +23 -0
  69. package/lib/win/bindings.js +11 -0
  70. package/lib/win/src/ble_manager.cc +802 -0
  71. package/lib/win/src/ble_manager.h +77 -0
  72. package/lib/win/src/callbacks.cc +274 -0
  73. package/lib/win/src/callbacks.h +33 -0
  74. package/lib/win/src/napi_winrt.cc +76 -0
  75. package/lib/win/src/napi_winrt.h +12 -0
  76. package/lib/win/src/noble_winrt.cc +308 -0
  77. package/lib/win/src/noble_winrt.h +34 -0
  78. package/lib/win/src/notify_map.cc +62 -0
  79. package/lib/win/src/notify_map.h +50 -0
  80. package/lib/win/src/peripheral.h +23 -0
  81. package/lib/win/src/peripheral_winrt.cc +296 -0
  82. package/lib/win/src/peripheral_winrt.h +82 -0
  83. package/lib/win/src/radio_watcher.cc +125 -0
  84. package/lib/win/src/radio_watcher.h +61 -0
  85. package/lib/win/src/winrt_cpp.cc +82 -0
  86. package/lib/win/src/winrt_cpp.h +11 -0
  87. package/lib/win/src/winrt_guid.cc +12 -0
  88. package/lib/win/src/winrt_guid.h +13 -0
  89. package/misc/nrf52840dk.hex +6921 -0
  90. package/misc/prj.conf +43 -0
  91. package/package.json +96 -0
  92. package/test/lib/characteristic.test.js +791 -0
  93. package/test/lib/descriptor.test.js +249 -0
  94. package/test/lib/distributed/bindings.test.js +918 -0
  95. package/test/lib/hci-socket/acl-stream.test.js +188 -0
  96. package/test/lib/hci-socket/bindings.test.js +1756 -0
  97. package/test/lib/hci-socket/crypto.test.js +55 -0
  98. package/test/lib/hci-socket/gap.test.js +1089 -0
  99. package/test/lib/hci-socket/gatt.test.js +2392 -0
  100. package/test/lib/hci-socket/hci.test.js +1891 -0
  101. package/test/lib/hci-socket/signaling.test.js +94 -0
  102. package/test/lib/hci-socket/smp.test.js +268 -0
  103. package/test/lib/manufacture.test.js +77 -0
  104. package/test/lib/peripheral.test.js +623 -0
  105. package/test/lib/resolve-bindings.test.js +102 -0
  106. package/test/lib/service.test.js +195 -0
  107. package/test/lib/webbluetooth/bindings.test.js +190 -0
  108. package/test/lib/websocket/bindings.test.js +456 -0
  109. package/test/noble.test.js +1565 -0
  110. package/test.js +131 -0
  111. package/with-bindings.js +5 -0
  112. 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
+ };