@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,17 +1,13 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ble_manager.mm
|
|
3
|
-
// noble-mac-native
|
|
4
|
-
//
|
|
5
|
-
// Created by Georg Vienna on 28.08.18.
|
|
6
|
-
//
|
|
7
1
|
#include "ble_manager.h"
|
|
2
|
+
#include "objc_cpp.h"
|
|
3
|
+
#include "Peripheral.h"
|
|
8
4
|
|
|
9
5
|
#import <Foundation/Foundation.h>
|
|
10
6
|
|
|
11
|
-
#include "objc_cpp.h"
|
|
12
|
-
|
|
13
7
|
@implementation BLEManager
|
|
14
|
-
|
|
8
|
+
|
|
9
|
+
- (instancetype)init: (const Napi::Value&) receiver with: (const Napi::Function&) callback
|
|
10
|
+
{
|
|
15
11
|
if (self = [super init]) {
|
|
16
12
|
pendingRead = false;
|
|
17
13
|
// wrap cb before creating the CentralManager as it may call didUpdateState immediately
|
|
@@ -24,69 +20,90 @@
|
|
|
24
20
|
return self;
|
|
25
21
|
}
|
|
26
22
|
|
|
27
|
-
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
|
|
23
|
+
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
|
|
24
|
+
{
|
|
28
25
|
auto state = stateToString(central.state);
|
|
29
26
|
emit.RadioState(state);
|
|
30
27
|
}
|
|
31
28
|
|
|
32
|
-
- (void)scan:
|
|
29
|
+
- (void)scan:(NSArray<NSString*> *)serviceUUIDs allowDuplicates:(BOOL)allowDuplicates {
|
|
30
|
+
[self.discovered removeAllObjects];
|
|
33
31
|
NSMutableArray* advServicesUuid = [NSMutableArray arrayWithCapacity:[serviceUUIDs count]];
|
|
34
32
|
[serviceUUIDs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
|
35
33
|
[advServicesUuid addObject:[CBUUID UUIDWithString:obj]];
|
|
36
34
|
}];
|
|
35
|
+
|
|
37
36
|
NSDictionary *options = @{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:allowDuplicates]};
|
|
38
37
|
[self.centralManager scanForPeripheralsWithServices:advServicesUuid options:options];
|
|
39
38
|
emit.ScanState(true);
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
- (void)stopScan
|
|
41
|
+
- (void)stopScan
|
|
42
|
+
{
|
|
43
43
|
[self.centralManager stopScan];
|
|
44
|
-
[self.discovered removeAllObjects];
|
|
45
44
|
emit.ScanState(false);
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
- (void) centralManager:(CBCentralManager *)central
|
|
47
|
+
- (void) centralManager:(CBCentralManager *)central
|
|
48
|
+
didDiscoverPeripheral:(CBPeripheral *)peripheral
|
|
49
|
+
advertisementData:(NSDictionary<NSString *,id> *)advertisementData
|
|
50
|
+
RSSI:(NSNumber *)RSSI
|
|
51
|
+
{
|
|
49
52
|
std::string uuid = getUuid(peripheral);
|
|
50
53
|
[self.discovered addObject:getNSUuid(peripheral)];
|
|
51
54
|
|
|
52
55
|
Peripheral p;
|
|
53
56
|
p.address = getAddress(uuid, &p.addressType);
|
|
57
|
+
|
|
54
58
|
IF(NSNumber*, connect, [advertisementData objectForKey:CBAdvertisementDataIsConnectable]) {
|
|
55
59
|
p.connectable = [connect boolValue];
|
|
56
60
|
}
|
|
61
|
+
|
|
57
62
|
IF(NSString*, dataLocalName, [advertisementData objectForKey:CBAdvertisementDataLocalNameKey]) {
|
|
58
|
-
p.name = std::
|
|
63
|
+
p.name = std::string([dataLocalName UTF8String]);
|
|
59
64
|
}
|
|
60
|
-
|
|
65
|
+
|
|
66
|
+
if (!p.name) {
|
|
61
67
|
IF(NSString*, name, [peripheral name]) {
|
|
62
|
-
p.name = std::
|
|
68
|
+
p.name = std::string([name UTF8String]);
|
|
63
69
|
}
|
|
64
70
|
}
|
|
71
|
+
|
|
65
72
|
IF(NSNumber*, txLevel, [advertisementData objectForKey:CBAdvertisementDataTxPowerLevelKey]) {
|
|
66
|
-
p.txPowerLevel =
|
|
73
|
+
p.txPowerLevel = [txLevel intValue];
|
|
67
74
|
}
|
|
75
|
+
|
|
68
76
|
IF(NSData*, data, [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey]) {
|
|
69
77
|
const UInt8* bytes = (UInt8 *)[data bytes];
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
Data manufacturerData;
|
|
79
|
+
manufacturerData.assign(bytes, bytes + [data length]);
|
|
80
|
+
p.manufacturerData = manufacturerData;
|
|
72
81
|
}
|
|
82
|
+
|
|
73
83
|
IF(NSDictionary*, dictionary, [advertisementData objectForKey:CBAdvertisementDataServiceDataKey]) {
|
|
84
|
+
std::vector<std::pair<std::string, Data>> serviceData;
|
|
74
85
|
for (CBUUID* key in dictionary) {
|
|
75
86
|
IF(NSData*, value, dictionary[key]) {
|
|
76
87
|
auto serviceUuid = [[key UUIDString] UTF8String];
|
|
77
88
|
Data sData;
|
|
78
89
|
const UInt8* bytes = (UInt8 *)[value bytes];
|
|
79
|
-
sData.assign(bytes, bytes+[value length]);
|
|
80
|
-
|
|
90
|
+
sData.assign(bytes, bytes + [value length]);
|
|
91
|
+
serviceData.push_back(std::make_pair(serviceUuid, sData));
|
|
81
92
|
}
|
|
82
93
|
}
|
|
83
|
-
|
|
94
|
+
if (!serviceData.empty()) {
|
|
95
|
+
p.serviceData = serviceData;
|
|
96
|
+
}
|
|
84
97
|
}
|
|
98
|
+
|
|
85
99
|
IF(NSArray*, services, [advertisementData objectForKey:CBAdvertisementDataServiceUUIDsKey]) {
|
|
100
|
+
std::vector<std::string> serviceUuids;
|
|
86
101
|
for (CBUUID* service in services) {
|
|
87
|
-
|
|
102
|
+
serviceUuids.push_back([[service UUIDString] UTF8String]);
|
|
103
|
+
}
|
|
104
|
+
if (!serviceUuids.empty()) {
|
|
105
|
+
p.serviceUuids = serviceUuids;
|
|
88
106
|
}
|
|
89
|
-
std::get<1>(p.serviceUuids) = true;
|
|
90
107
|
}
|
|
91
108
|
|
|
92
109
|
int rssi = [RSSI intValue];
|
|
@@ -157,17 +174,18 @@
|
|
|
157
174
|
return NO;
|
|
158
175
|
}
|
|
159
176
|
|
|
160
|
-
- (void)
|
|
177
|
+
- (void) peripheral:(CBPeripheral *) peripheral
|
|
178
|
+
didReadRSSI:(NSNumber *) RSSI
|
|
179
|
+
error:(NSError *) error
|
|
180
|
+
{
|
|
161
181
|
std::string uuid = getUuid(peripheral);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
emit.RSSI(uuid, [rssi longValue]);
|
|
165
|
-
}
|
|
182
|
+
int16_t rssi = [RSSI intValue];
|
|
183
|
+
emit.RSSI(uuid, rssi, error ? error.localizedDescription.UTF8String : "");
|
|
166
184
|
}
|
|
167
185
|
|
|
168
186
|
#pragma mark - Services
|
|
169
187
|
|
|
170
|
-
-(BOOL)
|
|
188
|
+
- (BOOL)discoverServices:(NSString*) uuid serviceUuids:(NSArray<NSString*>*) services {
|
|
171
189
|
IF(CBPeripheral*, peripheral, [self.peripherals objectForKey:uuid]) {
|
|
172
190
|
NSMutableArray* servicesUuid = nil;
|
|
173
191
|
if(services) {
|
|
@@ -182,10 +200,10 @@
|
|
|
182
200
|
return NO;
|
|
183
201
|
}
|
|
184
202
|
|
|
185
|
-
- (void)
|
|
203
|
+
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
|
|
186
204
|
std::string uuid = getUuid(peripheral);
|
|
187
205
|
std::vector<std::string> services = getServices(peripheral.services);
|
|
188
|
-
emit.ServicesDiscovered(uuid, services);
|
|
206
|
+
emit.ServicesDiscovered(uuid, services, error ? error.localizedDescription.UTF8String : "");
|
|
189
207
|
}
|
|
190
208
|
|
|
191
209
|
- (BOOL)discoverIncludedServices:(NSString*) uuid forService:(NSString*) serviceUuid services:(NSArray<NSString*>*) serviceUuids {
|
|
@@ -209,7 +227,7 @@
|
|
|
209
227
|
std::string uuid = getUuid(peripheral);
|
|
210
228
|
auto serviceUuid = [[service.UUID UUIDString] UTF8String];
|
|
211
229
|
std::vector<std::string> services = getServices(service.includedServices);
|
|
212
|
-
emit.IncludedServicesDiscovered(uuid, serviceUuid, services);
|
|
230
|
+
emit.IncludedServicesDiscovered(uuid, serviceUuid, services, error ? error.localizedDescription.UTF8String : "");
|
|
213
231
|
}
|
|
214
232
|
|
|
215
233
|
#pragma mark - Characteristics
|
|
@@ -218,7 +236,7 @@
|
|
|
218
236
|
IF(CBPeripheral *, peripheral, [self.peripherals objectForKey:uuid]) {
|
|
219
237
|
IF(CBService*, service, [self getService:peripheral service:serviceUuid]) {
|
|
220
238
|
NSMutableArray* characteristicsUuid = nil;
|
|
221
|
-
if(characteristics) {
|
|
239
|
+
if([characteristics count] > 0) {
|
|
222
240
|
characteristicsUuid = [NSMutableArray arrayWithCapacity:[characteristics count]];
|
|
223
241
|
[characteristics enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
|
224
242
|
[characteristicsUuid addObject:[CBUUID UUIDWithString:obj]];
|
|
@@ -235,7 +253,7 @@
|
|
|
235
253
|
std::string uuid = getUuid(peripheral);
|
|
236
254
|
std::string serviceUuid = std::string([service.UUID.UUIDString UTF8String]);
|
|
237
255
|
auto characteristics = getCharacteristics(service.characteristics);
|
|
238
|
-
emit.CharacteristicsDiscovered(uuid, serviceUuid, characteristics);
|
|
256
|
+
emit.CharacteristicsDiscovered(uuid, serviceUuid, characteristics, error ? error.localizedDescription.UTF8String : "");
|
|
239
257
|
}
|
|
240
258
|
|
|
241
259
|
- (BOOL)read:(NSString*) uuid service:(NSString*) serviceUuid characteristic:(NSString*) characteristicUuid {
|
|
@@ -258,7 +276,7 @@
|
|
|
258
276
|
data.assign(bytes, bytes+[characteristic.value length]);
|
|
259
277
|
bool isNotification = !pendingRead && characteristic.isNotifying;
|
|
260
278
|
pendingRead = false;
|
|
261
|
-
emit.Read(uuid, serviceUuid, characteristicUuid, data, isNotification);
|
|
279
|
+
emit.Read(uuid, serviceUuid, characteristicUuid, data, isNotification, error ? error.localizedDescription.UTF8String : "");
|
|
262
280
|
}
|
|
263
281
|
|
|
264
282
|
- (BOOL)write:(NSString*) uuid service:(NSString*) serviceUuid characteristic:(NSString*) characteristicUuid data:(NSData*) data withoutResponse:(BOOL)withoutResponse {
|
|
@@ -279,7 +297,7 @@
|
|
|
279
297
|
std::string uuid = getUuid(peripheral);
|
|
280
298
|
std::string serviceUuid = [characteristic.service.UUID.UUIDString UTF8String];
|
|
281
299
|
std::string characteristicUuid = [characteristic.UUID.UUIDString UTF8String];
|
|
282
|
-
emit.Write(uuid, serviceUuid, characteristicUuid);
|
|
300
|
+
emit.Write(uuid, serviceUuid, characteristicUuid, error ? error.localizedDescription.UTF8String : "");
|
|
283
301
|
}
|
|
284
302
|
|
|
285
303
|
- (BOOL)notify:(NSString*) uuid service:(NSString*) serviceUuid characteristic:(NSString*) characteristicUuid on:(BOOL)on {
|
|
@@ -296,7 +314,7 @@
|
|
|
296
314
|
std::string uuid = getUuid(peripheral);
|
|
297
315
|
std::string serviceUuid = [characteristic.service.UUID.UUIDString UTF8String];
|
|
298
316
|
std::string characteristicUuid = [characteristic.UUID.UUIDString UTF8String];
|
|
299
|
-
emit.Notify(uuid, serviceUuid, characteristicUuid, characteristic.isNotifying);
|
|
317
|
+
emit.Notify(uuid, serviceUuid, characteristicUuid, characteristic.isNotifying, error ? error.localizedDescription.UTF8String : "");
|
|
300
318
|
}
|
|
301
319
|
|
|
302
320
|
#pragma mark - Descriptors
|
|
@@ -316,7 +334,7 @@
|
|
|
316
334
|
std::string serviceUuid = [characteristic.service.UUID.UUIDString UTF8String];
|
|
317
335
|
std::string characteristicUuid = [characteristic.UUID.UUIDString UTF8String];
|
|
318
336
|
std::vector<std::string> descriptors = getDescriptors(characteristic.descriptors);
|
|
319
|
-
emit.DescriptorsDiscovered(uuid, serviceUuid, characteristicUuid, descriptors);
|
|
337
|
+
emit.DescriptorsDiscovered(uuid, serviceUuid, characteristicUuid, descriptors, error ? error.localizedDescription.UTF8String : "");
|
|
320
338
|
}
|
|
321
339
|
|
|
322
340
|
- (BOOL)readValue:(NSString*) uuid service:(NSString*) serviceUuid characteristic:(NSString*) characteristicUuid descriptor:(NSString*) descriptorUuid {
|
|
@@ -334,13 +352,37 @@
|
|
|
334
352
|
std::string serviceUuid = [descriptor.characteristic.service.UUID.UUIDString UTF8String];
|
|
335
353
|
std::string characteristicUuid = [descriptor.characteristic.UUID.UUIDString UTF8String];
|
|
336
354
|
std::string descriptorUuid = [descriptor.UUID.UUIDString UTF8String];
|
|
337
|
-
|
|
355
|
+
|
|
338
356
|
Data data;
|
|
339
|
-
|
|
357
|
+
|
|
358
|
+
if (descriptor.value != nil) {
|
|
359
|
+
if ([descriptor.value isKindOfClass:[NSData class]]) {
|
|
360
|
+
// Handle NSData directly
|
|
361
|
+
NSData *valueData = (NSData *)descriptor.value;
|
|
362
|
+
const UInt8* bytes = (UInt8 *)[valueData bytes];
|
|
363
|
+
data.assign(bytes, bytes + [valueData length]);
|
|
364
|
+
}
|
|
365
|
+
else if ([descriptor.value isKindOfClass:[NSString class]]) {
|
|
366
|
+
// Convert NSString to bytes
|
|
367
|
+
NSString *valueString = (NSString *)descriptor.value;
|
|
368
|
+
NSData *valueData = [valueString dataUsingEncoding:NSUTF8StringEncoding];
|
|
369
|
+
const UInt8* bytes = (UInt8 *)[valueData bytes];
|
|
370
|
+
data.assign(bytes, bytes + [valueData length]);
|
|
371
|
+
}
|
|
372
|
+
else if ([descriptor.value isKindOfClass:[NSNumber class]]) {
|
|
373
|
+
// Convert NSNumber to bytes
|
|
374
|
+
NSNumber *valueNumber = (NSNumber *)descriptor.value;
|
|
375
|
+
NSData *valueData = [NSData dataWithBytes:valueNumber.stringValue.UTF8String
|
|
376
|
+
length:strlen(valueNumber.stringValue.UTF8String)];
|
|
377
|
+
const UInt8* bytes = (UInt8 *)[valueData bytes];
|
|
378
|
+
data.assign(bytes, bytes + [valueData length]);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
340
382
|
IF(NSNumber*, handle, [self getDescriptorHandle:descriptor]) {
|
|
341
383
|
emit.ReadHandle(uuid, [handle intValue], data);
|
|
342
384
|
}
|
|
343
|
-
emit.ReadValue(uuid, serviceUuid, characteristicUuid, descriptorUuid, data);
|
|
385
|
+
emit.ReadValue(uuid, serviceUuid, characteristicUuid, descriptorUuid, data, error ? error.localizedDescription.UTF8String : "");
|
|
344
386
|
}
|
|
345
387
|
|
|
346
388
|
- (BOOL)writeValue:(NSString*) uuid service:(NSString*) serviceUuid characteristic:(NSString*) characteristicUuid descriptor:(NSString*) descriptorUuid data:(NSData*) data {
|
|
@@ -361,7 +403,7 @@
|
|
|
361
403
|
IF(NSNumber*, handle, [self getDescriptorHandle:descriptor]) {
|
|
362
404
|
emit.WriteHandle(uuid, [handle intValue]);
|
|
363
405
|
}
|
|
364
|
-
emit.WriteValue(uuid, serviceUuid, characteristicUuid, descriptorUuid);
|
|
406
|
+
emit.WriteValue(uuid, serviceUuid, characteristicUuid, descriptorUuid, error ? error.localizedDescription.UTF8String : "");
|
|
365
407
|
}
|
|
366
408
|
|
|
367
409
|
- (BOOL)readHandle:(NSString*) uuid handle:(NSNumber*) handle {
|
|
@@ -450,3 +492,4 @@
|
|
|
450
492
|
}
|
|
451
493
|
|
|
452
494
|
@end
|
|
495
|
+
|
package/lib/mac/src/napi_objc.h
CHANGED
package/lib/mac/src/napi_objc.mm
CHANGED
package/lib/mac/src/noble_mac.h
CHANGED
|
@@ -8,11 +8,13 @@ class NobleMac : public Napi::ObjectWrap<NobleMac>
|
|
|
8
8
|
{
|
|
9
9
|
public:
|
|
10
10
|
NobleMac(const Napi::CallbackInfo&);
|
|
11
|
-
Napi::Value
|
|
11
|
+
Napi::Value Start(const Napi::CallbackInfo&);
|
|
12
|
+
Napi::Value Stop(const Napi::CallbackInfo&);
|
|
12
13
|
Napi::Value Scan(const Napi::CallbackInfo&);
|
|
13
14
|
Napi::Value StopScan(const Napi::CallbackInfo&);
|
|
14
15
|
Napi::Value Connect(const Napi::CallbackInfo&);
|
|
15
16
|
Napi::Value Disconnect(const Napi::CallbackInfo&);
|
|
17
|
+
Napi::Value CancelConnect(const Napi::CallbackInfo&);
|
|
16
18
|
Napi::Value UpdateRSSI(const Napi::CallbackInfo&);
|
|
17
19
|
Napi::Value DiscoverServices(const Napi::CallbackInfo&);
|
|
18
20
|
Napi::Value DiscoverIncludedServices(const Napi::CallbackInfo& info);
|
|
@@ -25,9 +27,9 @@ public:
|
|
|
25
27
|
Napi::Value WriteValue(const Napi::CallbackInfo& info);
|
|
26
28
|
Napi::Value ReadHandle(const Napi::CallbackInfo& info);
|
|
27
29
|
Napi::Value WriteHandle(const Napi::CallbackInfo& info);
|
|
28
|
-
Napi::Value
|
|
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/mac/src/noble_mac.mm
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
// noble_mac.mm
|
|
3
|
-
// noble-mac-native
|
|
4
|
-
//
|
|
5
|
-
// Created by Georg Vienna on 28.08.18.
|
|
6
|
-
//
|
|
7
1
|
#include "noble_mac.h"
|
|
8
|
-
|
|
9
2
|
#include "napi_objc.h"
|
|
10
3
|
|
|
11
4
|
#define THROW(msg) \
|
|
@@ -39,107 +32,134 @@ if (!info[0].Is##type1() || !info[1].Is##type2() || !info[2].Is##type3() || !inf
|
|
|
39
32
|
|
|
40
33
|
#define CHECK_MANAGER() \
|
|
41
34
|
if(!manager) { \
|
|
42
|
-
THROW("BLEManager has already been cleaned up"); \
|
|
35
|
+
THROW(std::string(__FUNCTION__) + ": BLEManager has already been cleaned up"); \
|
|
43
36
|
}
|
|
44
37
|
|
|
45
|
-
NobleMac::NobleMac(const Napi::CallbackInfo& info) : ObjectWrap(info) {
|
|
46
|
-
}
|
|
38
|
+
NobleMac::NobleMac(const Napi::CallbackInfo& info) : ObjectWrap(info) {}
|
|
47
39
|
|
|
48
|
-
Napi::Value NobleMac::
|
|
40
|
+
Napi::Value NobleMac::Start(const Napi::CallbackInfo& info)
|
|
41
|
+
{
|
|
49
42
|
Napi::Function emit = info.This().As<Napi::Object>().Get("emit").As<Napi::Function>();
|
|
50
43
|
manager = [[BLEManager alloc] init:info.This() with:emit];
|
|
51
44
|
return Napi::Value();
|
|
52
45
|
}
|
|
53
46
|
|
|
47
|
+
Napi::Value NobleMac::Stop(const Napi::CallbackInfo& info)
|
|
48
|
+
{
|
|
49
|
+
CHECK_MANAGER()
|
|
50
|
+
manager = nil;
|
|
51
|
+
return info.Env().Undefined();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
54
|
// startScanning(serviceUuids, allowDuplicates)
|
|
55
|
-
Napi::Value NobleMac::Scan(const Napi::CallbackInfo& info)
|
|
55
|
+
Napi::Value NobleMac::Scan(const Napi::CallbackInfo& info)
|
|
56
|
+
{
|
|
56
57
|
CHECK_MANAGER()
|
|
57
58
|
NSArray* array = getUuidArray(info[0]);
|
|
58
59
|
// default value NO
|
|
59
60
|
auto duplicates = getBool(info[1], NO);
|
|
60
61
|
[manager scan:array allowDuplicates:duplicates];
|
|
61
|
-
return
|
|
62
|
+
return info.Env().Undefined();
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
// stopScanning()
|
|
65
|
-
Napi::Value NobleMac::StopScan(const Napi::CallbackInfo& info)
|
|
66
|
+
Napi::Value NobleMac::StopScan(const Napi::CallbackInfo& info)
|
|
67
|
+
{
|
|
66
68
|
CHECK_MANAGER()
|
|
67
69
|
[manager stopScan];
|
|
68
|
-
return
|
|
70
|
+
return info.Env().Undefined();
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
// connect(deviceUuid)
|
|
72
|
-
Napi::Value NobleMac::Connect(const Napi::CallbackInfo& info)
|
|
74
|
+
Napi::Value NobleMac::Connect(const Napi::CallbackInfo& info)
|
|
75
|
+
{
|
|
73
76
|
CHECK_MANAGER()
|
|
74
77
|
ARG1(String)
|
|
75
78
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
76
79
|
[manager connect:uuid];
|
|
77
|
-
return
|
|
80
|
+
return info.Env().Undefined();
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
// disconnect(deviceUuid)
|
|
81
|
-
Napi::Value NobleMac::Disconnect(const Napi::CallbackInfo& info)
|
|
84
|
+
Napi::Value NobleMac::Disconnect(const Napi::CallbackInfo& info)
|
|
85
|
+
{
|
|
82
86
|
CHECK_MANAGER()
|
|
83
87
|
ARG1(String)
|
|
84
88
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
85
89
|
[manager disconnect:uuid];
|
|
86
|
-
return
|
|
90
|
+
return info.Env().Undefined();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// cancelConnect(deviceUuid)
|
|
94
|
+
Napi::Value NobleMac::CancelConnect(const Napi::CallbackInfo& info)
|
|
95
|
+
{
|
|
96
|
+
CHECK_MANAGER()
|
|
97
|
+
ARG1(String)
|
|
98
|
+
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
99
|
+
[manager disconnect:uuid];
|
|
100
|
+
return info.Env().Undefined();
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
// updateRssi(deviceUuid)
|
|
90
|
-
Napi::Value NobleMac::UpdateRSSI(const Napi::CallbackInfo& info)
|
|
104
|
+
Napi::Value NobleMac::UpdateRSSI(const Napi::CallbackInfo& info)
|
|
105
|
+
{
|
|
91
106
|
CHECK_MANAGER()
|
|
92
107
|
ARG1(String)
|
|
93
108
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
94
109
|
[manager updateRSSI:uuid];
|
|
95
|
-
return
|
|
110
|
+
return info.Env().Undefined();
|
|
96
111
|
}
|
|
97
112
|
|
|
98
113
|
// discoverServices(deviceUuid, uuids)
|
|
99
|
-
Napi::Value NobleMac::DiscoverServices(const Napi::CallbackInfo& info)
|
|
114
|
+
Napi::Value NobleMac::DiscoverServices(const Napi::CallbackInfo& info)
|
|
115
|
+
{
|
|
100
116
|
CHECK_MANAGER()
|
|
101
117
|
ARG1(String)
|
|
102
118
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
103
119
|
NSArray* array = getUuidArray(info[1]);
|
|
104
120
|
[manager discoverServices:uuid serviceUuids:array];
|
|
105
|
-
return
|
|
121
|
+
return info.Env().Undefined();
|
|
106
122
|
}
|
|
107
123
|
|
|
108
124
|
// discoverIncludedServices(deviceUuid, serviceUuid, serviceUuids)
|
|
109
|
-
Napi::Value NobleMac::DiscoverIncludedServices(const Napi::CallbackInfo& info)
|
|
125
|
+
Napi::Value NobleMac::DiscoverIncludedServices(const Napi::CallbackInfo& info)
|
|
126
|
+
{
|
|
110
127
|
CHECK_MANAGER()
|
|
111
128
|
ARG2(String, String)
|
|
112
129
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
113
130
|
auto service = napiToUuidString(info[1].As<Napi::String>());
|
|
114
131
|
NSArray* serviceUuids = getUuidArray(info[2]);
|
|
115
132
|
[manager discoverIncludedServices:uuid forService:service services:serviceUuids];
|
|
116
|
-
return
|
|
133
|
+
return info.Env().Undefined();
|
|
117
134
|
}
|
|
118
135
|
|
|
119
136
|
// discoverCharacteristics(deviceUuid, serviceUuid, characteristicUuids)
|
|
120
|
-
Napi::Value NobleMac::DiscoverCharacteristics(const Napi::CallbackInfo& info)
|
|
137
|
+
Napi::Value NobleMac::DiscoverCharacteristics(const Napi::CallbackInfo& info)
|
|
138
|
+
{
|
|
121
139
|
CHECK_MANAGER()
|
|
122
140
|
ARG2(String, String)
|
|
123
141
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
124
142
|
auto service = napiToUuidString(info[1].As<Napi::String>());
|
|
125
143
|
NSArray* characteristics = getUuidArray(info[2]);
|
|
126
144
|
[manager discoverCharacteristics:uuid forService:service characteristics:characteristics];
|
|
127
|
-
return
|
|
145
|
+
return info.Env().Undefined();
|
|
128
146
|
}
|
|
129
147
|
|
|
130
148
|
// read(deviceUuid, serviceUuid, characteristicUuid)
|
|
131
|
-
Napi::Value NobleMac::Read(const Napi::CallbackInfo& info)
|
|
149
|
+
Napi::Value NobleMac::Read(const Napi::CallbackInfo& info)
|
|
150
|
+
{
|
|
132
151
|
CHECK_MANAGER()
|
|
133
152
|
ARG3(String, String, String)
|
|
134
153
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
135
154
|
auto service = napiToUuidString(info[1].As<Napi::String>());
|
|
136
155
|
auto characteristic = napiToUuidString(info[2].As<Napi::String>());
|
|
137
156
|
[manager read:uuid service:service characteristic:characteristic];
|
|
138
|
-
return
|
|
157
|
+
return info.Env().Undefined();
|
|
139
158
|
}
|
|
140
159
|
|
|
141
160
|
// write(deviceUuid, serviceUuid, characteristicUuid, data, withoutResponse)
|
|
142
|
-
Napi::Value NobleMac::Write(const Napi::CallbackInfo& info)
|
|
161
|
+
Napi::Value NobleMac::Write(const Napi::CallbackInfo& info)
|
|
162
|
+
{
|
|
143
163
|
CHECK_MANAGER()
|
|
144
164
|
ARG4(String, String, String, Buffer /*, Boolean */)
|
|
145
165
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
@@ -153,11 +173,12 @@ Napi::Value NobleMac::Write(const Napi::CallbackInfo& info) {
|
|
|
153
173
|
}
|
|
154
174
|
|
|
155
175
|
[manager write:uuid service:service characteristic:characteristic data:data withoutResponse:withoutResponse];
|
|
156
|
-
return
|
|
176
|
+
return info.Env().Undefined();
|
|
157
177
|
}
|
|
158
178
|
|
|
159
179
|
// notify(deviceUuid, serviceUuid, characteristicUuid, notify)
|
|
160
|
-
Napi::Value NobleMac::Notify(const Napi::CallbackInfo& info)
|
|
180
|
+
Napi::Value NobleMac::Notify(const Napi::CallbackInfo& info)
|
|
181
|
+
{
|
|
161
182
|
CHECK_MANAGER()
|
|
162
183
|
ARG4(String, String, String, Boolean)
|
|
163
184
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
@@ -165,22 +186,24 @@ Napi::Value NobleMac::Notify(const Napi::CallbackInfo& info) {
|
|
|
165
186
|
auto characteristic = napiToUuidString(info[2].As<Napi::String>());
|
|
166
187
|
auto on = info[3].As<Napi::Boolean>().Value();
|
|
167
188
|
[manager notify:uuid service:service characteristic:characteristic on:on];
|
|
168
|
-
return
|
|
189
|
+
return info.Env().Undefined();
|
|
169
190
|
}
|
|
170
191
|
|
|
171
192
|
// discoverDescriptors(deviceUuid, serviceUuid, characteristicUuid)
|
|
172
|
-
Napi::Value NobleMac::DiscoverDescriptors(const Napi::CallbackInfo& info)
|
|
193
|
+
Napi::Value NobleMac::DiscoverDescriptors(const Napi::CallbackInfo& info)
|
|
194
|
+
{
|
|
173
195
|
CHECK_MANAGER()
|
|
174
196
|
ARG3(String, String, String)
|
|
175
197
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
176
198
|
auto service = napiToUuidString(info[1].As<Napi::String>());
|
|
177
199
|
auto characteristic = napiToUuidString(info[2].As<Napi::String>());
|
|
178
200
|
[manager discoverDescriptors:uuid service:service characteristic:characteristic];
|
|
179
|
-
return
|
|
201
|
+
return info.Env().Undefined();
|
|
180
202
|
}
|
|
181
203
|
|
|
182
204
|
// readValue(deviceUuid, serviceUuid, characteristicUuid, descriptorUuid)
|
|
183
|
-
Napi::Value NobleMac::ReadValue(const Napi::CallbackInfo& info)
|
|
205
|
+
Napi::Value NobleMac::ReadValue(const Napi::CallbackInfo& info)
|
|
206
|
+
{
|
|
184
207
|
CHECK_MANAGER()
|
|
185
208
|
ARG4(String, String, String, String)
|
|
186
209
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
@@ -188,11 +211,12 @@ Napi::Value NobleMac::ReadValue(const Napi::CallbackInfo& info) {
|
|
|
188
211
|
auto characteristic = napiToUuidString(info[2].As<Napi::String>());
|
|
189
212
|
auto descriptor = napiToUuidString(info[3].As<Napi::String>());
|
|
190
213
|
[manager readValue:uuid service:service characteristic:characteristic descriptor:descriptor];
|
|
191
|
-
return
|
|
214
|
+
return info.Env().Undefined();
|
|
192
215
|
}
|
|
193
216
|
|
|
194
217
|
// writeValue(deviceUuid, serviceUuid, characteristicUuid, descriptorUuid, data)
|
|
195
|
-
Napi::Value NobleMac::WriteValue(const Napi::CallbackInfo& info)
|
|
218
|
+
Napi::Value NobleMac::WriteValue(const Napi::CallbackInfo& info)
|
|
219
|
+
{
|
|
196
220
|
CHECK_MANAGER()
|
|
197
221
|
ARG5(String, String, String, String, Buffer)
|
|
198
222
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
@@ -201,44 +225,61 @@ Napi::Value NobleMac::WriteValue(const Napi::CallbackInfo& info) {
|
|
|
201
225
|
auto descriptor = napiToUuidString(info[3].As<Napi::String>());
|
|
202
226
|
auto data = napiToData(info[4].As<Napi::Buffer<Byte>>());
|
|
203
227
|
[manager writeValue:uuid service:service characteristic:characteristic descriptor:descriptor data: data];
|
|
204
|
-
return
|
|
228
|
+
return info.Env().Undefined();
|
|
205
229
|
}
|
|
206
230
|
|
|
207
231
|
// readHandle(deviceUuid, handle)
|
|
208
|
-
Napi::Value NobleMac::ReadHandle(const Napi::CallbackInfo& info)
|
|
232
|
+
Napi::Value NobleMac::ReadHandle(const Napi::CallbackInfo& info)
|
|
233
|
+
{
|
|
209
234
|
CHECK_MANAGER()
|
|
210
235
|
ARG2(String, Number)
|
|
211
236
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
212
237
|
auto handle = napiToNumber(info[1].As<Napi::Number>());
|
|
213
238
|
[manager readHandle:uuid handle:handle];
|
|
214
|
-
return
|
|
239
|
+
return info.Env().Undefined();
|
|
215
240
|
}
|
|
216
241
|
|
|
217
242
|
// writeHandle(deviceUuid, handle, data, (unused)withoutResponse)
|
|
218
|
-
Napi::Value NobleMac::WriteHandle(const Napi::CallbackInfo& info)
|
|
243
|
+
Napi::Value NobleMac::WriteHandle(const Napi::CallbackInfo& info)
|
|
244
|
+
{
|
|
219
245
|
CHECK_MANAGER()
|
|
220
246
|
ARG3(String, Number, Buffer)
|
|
221
247
|
auto uuid = napiToUuidString(info[0].As<Napi::String>());
|
|
222
248
|
auto handle = napiToNumber(info[1].As<Napi::Number>());
|
|
223
249
|
auto data = napiToData(info[2].As<Napi::Buffer<Byte>>());
|
|
224
250
|
[manager writeHandle:uuid handle:handle data: data];
|
|
225
|
-
return
|
|
251
|
+
return info.Env().Undefined();
|
|
226
252
|
}
|
|
227
253
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
254
|
+
// addressToId(address)
|
|
255
|
+
Napi::Value NobleMac::AddressToId(const Napi::CallbackInfo& info)
|
|
256
|
+
{
|
|
257
|
+
ARG1(String)
|
|
258
|
+
auto address = info[0].As<Napi::String>().Utf8Value();
|
|
259
|
+
NSMutableString * uuidString = [[NSMutableString alloc] initWithCString:address.c_str() encoding:NSASCIIStringEncoding];
|
|
260
|
+
if ([uuidString containsString:@"-"]) {
|
|
261
|
+
NSUUID* uuid = [[NSUUID alloc] initWithUUIDString:uuidString];
|
|
262
|
+
if (uuid) {
|
|
263
|
+
NSString* canonical = uuid.UUIDString;
|
|
264
|
+
NSString* result = [[canonical stringByReplacingOccurrencesOfString:@"-" withString:@""] lowercaseString];
|
|
265
|
+
return Napi::String::New(info.Env(), [result UTF8String]);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return info.Env().Null();
|
|
233
269
|
}
|
|
234
270
|
|
|
235
|
-
Napi::
|
|
236
|
-
|
|
237
|
-
|
|
271
|
+
Napi::Object NobleMac::Init(Napi::Env env, Napi::Object exports)
|
|
272
|
+
{
|
|
273
|
+
Napi::HandleScope scope(env);
|
|
274
|
+
|
|
275
|
+
Napi::Function func = DefineClass(env, "NobleMac", {
|
|
276
|
+
NobleMac::InstanceMethod("start", &NobleMac::Start),
|
|
277
|
+
NobleMac::InstanceMethod("stop", &NobleMac::Stop),
|
|
238
278
|
NobleMac::InstanceMethod("startScanning", &NobleMac::Scan),
|
|
239
279
|
NobleMac::InstanceMethod("stopScanning", &NobleMac::StopScan),
|
|
240
280
|
NobleMac::InstanceMethod("connect", &NobleMac::Connect),
|
|
241
281
|
NobleMac::InstanceMethod("disconnect", &NobleMac::Disconnect),
|
|
282
|
+
NobleMac::InstanceMethod("cancelConnect", &NobleMac::CancelConnect),
|
|
242
283
|
NobleMac::InstanceMethod("updateRssi", &NobleMac::UpdateRSSI),
|
|
243
284
|
NobleMac::InstanceMethod("discoverServices", &NobleMac::DiscoverServices),
|
|
244
285
|
NobleMac::InstanceMethod("discoverIncludedServices", &NobleMac::DiscoverIncludedServices),
|
|
@@ -251,14 +292,15 @@ Napi::Function NobleMac::GetClass(Napi::Env env) {
|
|
|
251
292
|
NobleMac::InstanceMethod("writeValue", &NobleMac::WriteValue),
|
|
252
293
|
NobleMac::InstanceMethod("readHandle", &NobleMac::ReadHandle),
|
|
253
294
|
NobleMac::InstanceMethod("writeHandle", &NobleMac::WriteHandle),
|
|
254
|
-
NobleMac::InstanceMethod("
|
|
295
|
+
NobleMac::InstanceMethod("addressToId", &NobleMac::AddressToId),
|
|
255
296
|
});
|
|
256
|
-
}
|
|
257
297
|
|
|
258
|
-
Napi::
|
|
259
|
-
|
|
260
|
-
|
|
298
|
+
Napi::FunctionReference* constructor = new Napi::FunctionReference();
|
|
299
|
+
*constructor = Napi::Persistent(func);
|
|
300
|
+
env.SetInstanceData(constructor);
|
|
301
|
+
|
|
302
|
+
exports.Set("NobleMac", func);
|
|
261
303
|
return exports;
|
|
262
304
|
}
|
|
263
305
|
|
|
264
|
-
|
|
306
|
+
NODE_API_NAMED_ADDON(addon, NobleMac);
|
package/lib/mac/src/objc_cpp.h
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
#include <string>
|
|
4
4
|
#include <vector>
|
|
5
|
+
|
|
6
|
+
#include "Peripheral.h"
|
|
7
|
+
|
|
5
8
|
#import <Foundation/Foundation.h>
|
|
6
9
|
#import <CoreBluetooth/CoreBluetooth.h>
|
|
7
|
-
#include "peripheral.h"
|
|
8
10
|
|
|
9
11
|
#define IF(type, var, code) type var = code; if(var)
|
|
10
12
|
|
|
@@ -17,7 +19,6 @@
|
|
|
17
19
|
std::string stateToString(CBCentralManagerState state);
|
|
18
20
|
#endif
|
|
19
21
|
|
|
20
|
-
|
|
21
22
|
NSString* getNSUuid(CBPeripheral* peripheral);
|
|
22
23
|
std::string getUuid(CBPeripheral* peripheral);
|
|
23
24
|
std::string getAddress(std::string uuid, AddressType* addressType);
|