bluetooth-serial-port 2.2.5 → 3.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.
Files changed (55) hide show
  1. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv.h +1724 -0
  2. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv.h.blob +0 -0
  3. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@darwin.h +61 -0
  4. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@darwin.h.blob +0 -0
  5. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@errno.h +443 -0
  6. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@errno.h.blob +0 -0
  7. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@threadpool.h +37 -0
  8. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@threadpool.h.blob +0 -0
  9. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@unix.h +491 -0
  10. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@unix.h.blob +0 -0
  11. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@version.h +43 -0
  12. package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@version.h.blob +0 -0
  13. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@DeviceINQ.h +78 -0
  14. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@DeviceINQ.h.blob +0 -0
  15. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BTSerialPortBinding.cc +404 -0
  16. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BTSerialPortBinding.cc.blob +0 -0
  17. package/{src/osx/BluetoothSerialPort.mm → .ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BluetoothSerialPort.cc} +3 -3
  18. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BluetoothSerialPort.cc.blob +0 -0
  19. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@DeviceINQ.cc +369 -0
  20. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@DeviceINQ.cc.blob +0 -0
  21. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@BluetoothHelpers.h +24 -0
  22. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@BluetoothHelpers.h.blob +0 -0
  23. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@DeviceINQ.cc +527 -0
  24. package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@DeviceINQ.cc.blob +0 -0
  25. package/.circleci/config.yml +47 -0
  26. package/.github/dependabot.yml +11 -0
  27. package/Dockerfile +1 -1
  28. package/Dockerfile.bk +13 -0
  29. package/README.md +91 -78
  30. package/RELEASE_NOTES.md +14 -0
  31. package/appveyor.yml +6 -9
  32. package/binding.gyp +0 -8
  33. package/package.json +56 -58
  34. package/qemu-arm-static +0 -0
  35. package/src/BTSerialPortBinding.h +3 -3
  36. package/src/BTSerialPortBindingServer.h +1 -1
  37. package/src/DeviceINQ.h +1 -1
  38. package/src/linux/BTSerialPortBinding.cc +17 -15
  39. package/src/linux/BTSerialPortBindingServer.cc +29 -19
  40. package/src/linux/BluetoothSerialPort.cc +1 -1
  41. package/src/linux/BluetoothSerialPortServer.cc +1 -1
  42. package/src/linux/DeviceINQ.cc +18 -15
  43. package/src/{osx → macos}/BTSerialPortBinding.mm +23 -17
  44. package/src/{osx → macos}/BluetoothDeviceResources.h +0 -0
  45. package/src/{osx → macos}/BluetoothDeviceResources.mm +0 -0
  46. package/src/macos/BluetoothSerialPort.mm +23 -0
  47. package/src/{osx → macos}/BluetoothWorker.h +3 -3
  48. package/src/{osx → macos}/BluetoothWorker.mm +139 -140
  49. package/src/{osx → macos}/DeviceINQ.mm +21 -23
  50. package/src/{osx → macos}/pipe.c +0 -0
  51. package/src/{osx → macos}/pipe.h +0 -0
  52. package/src/windows/BTSerialPortBinding.cc +17 -18
  53. package/src/windows/BluetoothSerialPort.cc +3 -3
  54. package/src/windows/DeviceINQ.cc +17 -15
  55. package/.travis.yml +0 -48
@@ -23,6 +23,7 @@
23
23
  #include <stdlib.h>
24
24
  #include <unistd.h>
25
25
  #include <node_object_wrap.h>
26
+ #include <dispatch/dispatch.h>
26
27
  #include "pipe.h"
27
28
 
28
29
  #ifndef RFCOMM_UUID
@@ -34,7 +35,7 @@ using namespace v8;
34
35
 
35
36
  /** Private class for wrapping a pipe */
36
37
  @interface Pipe : NSObject {
37
- pipe_t *pipe;
38
+ pipe_t *pipe;
38
39
  }
39
40
  @property (nonatomic, assign) pipe_t *pipe;
40
41
  @end
@@ -46,8 +47,8 @@ using namespace v8;
46
47
 
47
48
  /** Private class for wrapping data */
48
49
  @interface BTData : NSObject {
49
- NSData *data;
50
- NSString *address;
50
+ NSData *data;
51
+ NSString *address;
51
52
  }
52
53
  @property (nonatomic, assign) NSData *data;
53
54
  @property (nonatomic, assign) NSString *address;
@@ -102,193 +103,191 @@ static NSLock *globalConnectLock = nil;
102
103
  deviceLock = [[NSLock alloc] init];
103
104
  connectLock = [[NSLock alloc] init];
104
105
  writeLock = [[NSLock alloc] init];
105
-
106
- // creates a worker thread that handles all the asynchronous stuff
107
- worker = [[NSThread alloc]initWithTarget: self selector: @selector(startBluetoothThread:) object: nil];
108
- [worker start];
106
+ worker_queue = dispatch_queue_create("btworker", NULL);
109
107
  return self;
110
108
  }
111
109
 
112
- /** Creates a run loop and sets a timer to keep the run loop alive */
113
- - (void) startBluetoothThread: (id) arg
114
- {
115
- NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
116
- //schedule a timer so runMode won't stop immediately
117
- keepAliveTimer = [[NSTimer alloc] initWithFireDate:[NSDate distantFuture]
118
- interval:1 target:nil selector:nil userInfo:nil repeats:YES];
119
- [runLoop addTimer:keepAliveTimer forMode:NSDefaultRunLoopMode];
120
- [[NSRunLoop currentRunLoop] run];
121
- }
122
-
123
110
  /** Disconnect from a Bluetooth device */
124
111
  - (void) disconnectFromDevice:(NSString *)address
125
112
  {
126
- // this function is called synchronous from javascript so it waits on the worker task to complete.
127
- [self performSelector:@selector(disconnectFromDeviceTask:) onThread:worker withObject: address waitUntilDone:true];
113
+ // this function is called synchronous from javascript so it waits on the worker task to complete.
114
+ dispatch_sync(worker_queue, ^{
115
+ [self disconnectFromDeviceTask: address];
116
+ });
128
117
  }
129
118
 
130
119
  /** Task on the worker to disconnect from a Bluetooth device */
131
120
  - (void) disconnectFromDeviceTask: (NSString *) address
132
121
  {
133
- // make it safe
134
- [deviceLock lock];
122
+ // make it safe
123
+ [deviceLock lock];
135
124
 
136
- if (res != nil) {
137
- if (res.producer != NULL) {
138
- pipe_producer_free(res.producer);
139
- res.producer = NULL;
140
- }
125
+ if (res != nil) {
126
+ if (res.producer != NULL) {
127
+ pipe_producer_free(res.producer);
128
+ res.producer = NULL;
129
+ }
141
130
 
142
- if (res.channel != NULL) {
143
- [res.channel closeChannel];
144
- res.channel = NULL;
145
- }
131
+ if (res.channel != NULL) {
132
+ [res.channel closeChannel];
133
+ res.channel = NULL;
134
+ }
146
135
 
147
- if (res.device != NULL) {
148
- [res.device closeConnection];
149
- res.device = NULL;
150
- }
136
+ if (res.device != NULL) {
137
+ [res.device closeConnection];
138
+ res.device = NULL;
139
+ }
151
140
 
152
141
  res = nil;
153
- }
142
+ }
154
143
 
155
- [deviceLock unlock];
144
+ [deviceLock unlock];
156
145
  }
157
146
 
158
147
  /** Connect to a Bluetooth device on a specific channel using a pipe to communicate with the main thread */
159
148
  - (IOReturn)connectDevice: (NSString *) address onChannel: (int) channel withPipe: (pipe_t *)pipe
160
149
  {
161
- [connectLock lock];
150
+ [connectLock lock];
162
151
 
163
- Pipe *pipeObj = [[Pipe alloc] init];
164
- pipeObj.pipe = pipe;
152
+ Pipe *pipeObj = [[Pipe alloc] init];
153
+ pipeObj.pipe = pipe;
165
154
 
166
- NSDictionary *parameters = [[NSDictionary alloc] initWithObjectsAndKeys:
167
- address, @"address", [NSNumber numberWithInt: channel], @"channel", pipeObj, @"pipe", nil];
155
+ NSDictionary *parameters = [[NSDictionary alloc] initWithObjectsAndKeys:
156
+ address, @"address", [NSNumber numberWithInt: channel], @"channel", pipeObj, @"pipe", nil];
168
157
 
169
- // connect to a device and wait for the result
170
- [self performSelector:@selector(connectDeviceTask:) onThread:worker withObject:parameters waitUntilDone:true];
171
- IOReturn result = connectResult;
172
- [connectLock unlock];
158
+ // connect to a device and wait for the result
159
+ dispatch_sync(worker_queue, ^{
160
+ [self connectDeviceTask:parameters];
161
+ });
162
+ IOReturn result = connectResult;
163
+ [connectLock unlock];
173
164
 
174
- return result;
165
+ return result;
175
166
  }
176
167
 
177
168
  /** Task to connect to a specific device */
178
169
  - (void)connectDeviceTask: (NSDictionary *)parameters
179
170
  {
180
- NSString *address = [parameters objectForKey:@"address"];
181
- NSNumber *channelID = [parameters objectForKey:@"channel"];
182
- pipe_t *pipe = ((Pipe *)[parameters objectForKey:@"pipe"]).pipe;
171
+ NSString *address = [parameters objectForKey:@"address"];
172
+ NSNumber *channelID = [parameters objectForKey:@"channel"];
173
+ pipe_t *pipe = ((Pipe *)[parameters objectForKey:@"pipe"]).pipe;
183
174
 
184
- connectResult = kIOReturnError;
175
+ connectResult = kIOReturnError;
185
176
 
186
- [deviceLock lock];
177
+ [deviceLock lock];
187
178
 
188
- if (res == nil) {
189
- IOBluetoothDevice *device = [IOBluetoothDevice deviceWithAddressString:address];
179
+ if (res == nil) {
180
+ IOBluetoothDevice *device = [IOBluetoothDevice deviceWithAddressString:address];
190
181
 
191
- if (device != nil) {
192
- IOBluetoothRFCOMMChannel *channel = [[IOBluetoothRFCOMMChannel alloc] init];
182
+ if (device != nil) {
183
+ IOBluetoothRFCOMMChannel *channel = [[IOBluetoothRFCOMMChannel alloc] init];
193
184
  [globalConnectLock lock];
194
- if ([device openRFCOMMChannelSync: &channel withChannelID:[channelID intValue] delegate: self] == kIOReturnSuccess) {
185
+ if ([device openRFCOMMChannelSync: &channel withChannelID:[channelID intValue] delegate: self] == kIOReturnSuccess) {
195
186
  [globalConnectLock unlock];
196
- connectResult = kIOReturnSuccess;
197
- pipe_producer_t *producer = pipe_producer_new(pipe);
187
+ connectResult = kIOReturnSuccess;
188
+ pipe_producer_t *producer = pipe_producer_new(pipe);
198
189
  res = [[BluetoothDeviceResources alloc] init];
199
- res.device = device;
200
- res.producer = producer;
201
- res.channel = channel;
202
- } else {
190
+ res.device = device;
191
+ res.producer = producer;
192
+ res.channel = channel;
193
+ } else {
203
194
  [globalConnectLock unlock];
204
195
  }
205
- }
206
- }
196
+ }
197
+ }
207
198
 
208
- [deviceLock unlock];
199
+ [deviceLock unlock];
209
200
  }
210
201
 
211
202
  /** Write synchronized to a connected Bluetooth device */
212
203
  - (IOReturn)writeAsync:(void *)data length:(UInt16)length toDevice: (NSString *)address
213
204
  {
214
- [writeLock lock];
205
+ [writeLock lock];
215
206
 
216
- BTData *writeData = [[BTData alloc] init];
217
- writeData.data = [NSData dataWithBytes: data length: length];
218
- writeData.address = address;
207
+ BTData *writeData = [[BTData alloc] init];
208
+ writeData.data = [NSData dataWithBytes: data length: length];
209
+ writeData.address = address;
219
210
 
220
- // wait for the write to be performed on the worker thread
221
- [self performSelector:@selector(writeAsyncTask:) onThread:worker withObject:writeData waitUntilDone:true];
211
+ // wait for the write to be performed on the worker thread
212
+ dispatch_sync(worker_queue, ^{
213
+ [self writeAsyncTask:writeData];
214
+ });
222
215
 
223
- IOReturn result = writeResult;
224
- [writeLock unlock];
216
+ IOReturn result = writeResult;
217
+ [writeLock unlock];
225
218
 
226
- return result;
219
+ return result;
227
220
  }
228
221
 
229
222
  /** Task to do the writing */
230
223
  - (void)writeAsyncTask:(BTData *)writeData
231
224
  {
232
- if (res != nil) {
233
- char *idx = (char *)[writeData.data bytes];
234
- ssize_t numBytesRemaining;
235
- BluetoothRFCOMMMTU rfcommChannelMTU;
225
+ if (res != nil) {
226
+ char *idx = (char *)[writeData.data bytes];
227
+ ssize_t numBytesRemaining;
228
+ BluetoothRFCOMMMTU rfcommChannelMTU;
236
229
 
237
- numBytesRemaining = [writeData.data length];
238
- writeResult = kIOReturnSuccess;
230
+ numBytesRemaining = [writeData.data length];
231
+ writeResult = kIOReturnSuccess;
239
232
 
240
- // Get the RFCOMM Channel's MTU. Each write can only
241
- // contain up to the MTU size number of bytes.
242
- rfcommChannelMTU = [res.channel getMTU];
233
+ // Get the RFCOMM Channel's MTU. Each write can only
234
+ // contain up to the MTU size number of bytes.
235
+ rfcommChannelMTU = [res.channel getMTU];
243
236
 
244
- // Loop through the data until we have no more to send.
245
- while ((writeResult == kIOReturnSuccess) && (numBytesRemaining > 0)) {
246
- // finds how many bytes I can send:
247
- ssize_t numBytesToWrite = ((numBytesRemaining > rfcommChannelMTU) ? rfcommChannelMTU : numBytesRemaining);
237
+ // Loop through the data until we have no more to send.
238
+ while ((writeResult == kIOReturnSuccess) && (numBytesRemaining > 0)) {
239
+ // finds how many bytes I can send:
240
+ ssize_t numBytesToWrite = ((numBytesRemaining > rfcommChannelMTU) ? rfcommChannelMTU : numBytesRemaining);
248
241
 
249
- // Send the bytes
250
- writeResult = [res.channel writeAsync:idx length:numBytesToWrite refcon:res];
242
+ // Send the bytes
243
+ writeResult = [res.channel writeAsync:idx length:numBytesToWrite refcon:res];
251
244
 
252
- // Updates the position in the buffer:
253
- numBytesRemaining -= numBytesToWrite;
254
- idx += numBytesToWrite;
255
- }
256
- }
245
+ // Updates the position in the buffer:
246
+ numBytesRemaining -= numBytesToWrite;
247
+ idx += numBytesToWrite;
248
+ }
249
+ }
257
250
 
258
- CFRunLoopStop(CFRunLoopGetCurrent());
251
+ CFRunLoopStop(CFRunLoopGetCurrent());
259
252
  }
260
253
 
261
254
  - (void)rfcommChannelWriteComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel refcon:(void*)refcon status:(IOReturn)error
262
255
  {
263
- CFRunLoopStop(CFRunLoopGetCurrent());
256
+ CFRunLoopStop(CFRunLoopGetCurrent());
264
257
  }
265
258
 
266
259
  /** Inquire Bluetooth devices and send results through the given pipe */
267
260
  - (void) inquireWithPipe: (pipe_t *)pipe
268
261
  {
269
- @synchronized(self) {
270
- inquiryProducer = pipe_producer_new(pipe);
271
- [self performSelector:@selector(inquiryTask) onThread:worker withObject:nil waitUntilDone:false];
272
- }
262
+ @synchronized(self) {
263
+ inquiryProducer = pipe_producer_new(pipe);
264
+ dispatch_async(worker_queue, ^{
265
+ [self inquiryTask];
266
+ });
267
+ }
273
268
  }
274
269
 
275
270
  /** Worker task to the the inquiry */
276
271
  - (void) inquiryTask
277
272
  {
278
- IOBluetoothDeviceInquiry *bdi = [[IOBluetoothDeviceInquiry alloc] init];
279
- [bdi setDelegate: self];
280
- [bdi start];
273
+ IOBluetoothDeviceInquiry *bdi = [IOBluetoothDeviceInquiry inquiryWithDelegate:self];
274
+ // bdi.inquiryLength = 30;
275
+ [bdi start];
276
+ // [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 31]];
277
+ // [bdi stop];
281
278
  }
282
279
 
283
280
  /** Get the RFCOMM channel for a given device */
284
281
  - (int) getRFCOMMChannelID: (NSString *) address
285
282
  {
286
- [sdpLock lock];
287
- // call the task on the worker thread and wait for the result
288
- [self performSelector:@selector(getRFCOMMChannelIDTask:) onThread:worker withObject:address waitUntilDone:true];
289
- int returnValue = lastChannelID;
290
- [sdpLock unlock];
291
- return returnValue;
283
+ [sdpLock lock];
284
+ // call the task on the worker thread and wait for the result
285
+ dispatch_sync(worker_queue, ^{
286
+ [self getRFCOMMChannelIDTask:address];
287
+ });
288
+ int returnValue = lastChannelID;
289
+ [sdpLock unlock];
290
+ return returnValue;
292
291
  }
293
292
 
294
293
  /** Task to get the RFCOMM channel */
@@ -307,7 +306,7 @@ static NSLock *globalConnectLock = nil;
307
306
 
308
307
  bool stop = false;
309
308
 
310
- NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970] + 60;
309
+ NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970] + 60;
311
310
  // if needed wait for a while for the sdp update
312
311
  while (!stop && [[NSDate date] timeIntervalSince1970] < endTime) { // wait no more than 60 seconds for SDP update
313
312
  currentServiceUpdate = [device getLastServicesUpdate];
@@ -329,63 +328,63 @@ static NSLock *globalConnectLock = nil;
329
328
  if ([sr hasServiceFromArray: uuids]) {
330
329
  BluetoothRFCOMMChannelID cid = -1;
331
330
  if ([sr getRFCOMMChannelID: &cid] == kIOReturnSuccess) {
332
- lastChannelID = cid;
333
- return;
331
+ lastChannelID = cid;
332
+ return;
334
333
  }
335
334
  }
336
335
  }
337
336
  }
338
337
 
339
- // This can happen is some conditions where the network is unreliable. Just ignore for now...
338
+ // This can happen in some conditions where the network is unreliable. Just ignore for now...
340
339
  lastChannelID = -1;
341
340
  }
342
341
 
343
342
  /** Called when data is received from a remote device */
344
343
  - (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength
345
344
  {
346
- NSData *data = [NSData dataWithBytes: dataPointer length: dataLength];
345
+ NSData *data = [NSData dataWithBytes: dataPointer length: dataLength];
347
346
 
348
- if (res != NULL && res.producer != NULL) {
349
- // push the data into the pipe so it can be read from the main thread
350
- pipe_push(res.producer, [data bytes], data.length);
351
- }
347
+ if (res != NULL && res.producer != NULL) {
348
+ // push the data into the pipe so it can be read from the main thread
349
+ pipe_push(res.producer, [data bytes], data.length);
350
+ }
352
351
 
353
- CFRunLoopStop(CFRunLoopGetCurrent());
352
+ CFRunLoopStop(CFRunLoopGetCurrent());
354
353
  }
355
354
 
356
355
  /** Called when a channel has been closed */
357
356
  - (void)rfcommChannelClosed:(IOBluetoothRFCOMMChannel*)rfcommChannel
358
357
  {
359
- [self disconnectFromDevice: [[rfcommChannel getDevice] getAddressString]];
358
+ [self disconnectFromDevice: [[rfcommChannel getDevice] addressString]];
360
359
  }
361
360
 
362
361
  /** Called when the device inquiry completes */
363
362
  - (void) deviceInquiryComplete: (IOBluetoothDeviceInquiry *) sender error: (IOReturn) error aborted: (BOOL) aborted
364
363
  {
365
- @synchronized(self) {
366
- if (inquiryProducer != NULL) {
367
- // free the producer so the main thread is signaled that the inquiry has been completed.
368
- pipe_producer_free(inquiryProducer);
369
- inquiryProducer = NULL;
370
- }
371
- }
364
+ @synchronized(self) {
365
+ if (inquiryProducer != NULL) {
366
+ // free the producer so the main thread is signaled that the inquiry has been completed.
367
+ pipe_producer_free(inquiryProducer);
368
+ inquiryProducer = NULL;
369
+ }
370
+ }
372
371
  }
373
372
 
374
373
  /** Called when a device has been found */
375
374
  - (void) deviceInquiryDeviceFound: (IOBluetoothDeviceInquiry*) sender device: (IOBluetoothDevice*) device
376
375
  {
377
- @synchronized(self) {
378
- if (inquiryProducer != NULL) {
379
- device_info_t *info = new device_info_t;
380
- strcpy(info->address, [[device getAddressString] UTF8String]);
381
- strcpy(info->name, [[device getNameOrAddress] UTF8String]);
382
-
383
- // push the device data into the pipe to notify the main thread
384
- pipe_push(inquiryProducer, info, 1);
385
-
386
- delete info;
387
- }
388
- }
376
+ @synchronized(self) {
377
+ if (inquiryProducer != NULL) {
378
+ device_info_t *info = new device_info_t;
379
+ strcpy(info->address, [[device addressString] UTF8String]);
380
+ strcpy(info->name, [[device addressString] UTF8String]);
381
+
382
+ // push the device data into the pipe to notify the main thread
383
+ pipe_push(inquiryProducer, info, 1);
384
+
385
+ delete info;
386
+ }
387
+ }
389
388
  }
390
389
 
391
390
  @end
@@ -72,10 +72,10 @@ class InquireWorker : public Nan::AsyncWorker {
72
72
  Nan::New(device.address).ToLocalChecked(),
73
73
  Nan::New(device.name).ToLocalChecked()
74
74
  };
75
- found->Call(2, argv);
75
+ found->Call(2, argv, async_resource);
76
76
  }
77
77
 
78
- callback->Call(0, 0);
78
+ callback->Call(0, 0, async_resource);
79
79
  [inquiryResult release];
80
80
  }
81
81
 
@@ -106,7 +106,7 @@ void DeviceINQ::EIO_AfterSdpSearch(uv_work_t *req) {
106
106
  Local<Value> argv[] = {
107
107
  Nan::New(baton->channelID)
108
108
  };
109
- baton->cb->Call(1, argv);
109
+ Nan::Call(*baton->cb, 1, argv);
110
110
 
111
111
  if (try_catch.HasCaught()) {
112
112
  Nan::FatalException(try_catch);
@@ -118,7 +118,7 @@ void DeviceINQ::EIO_AfterSdpSearch(uv_work_t *req) {
118
118
  baton = NULL;
119
119
  }
120
120
 
121
- void DeviceINQ::Init(Handle<Object> target) {
121
+ void DeviceINQ::Init(Local<Object> target) {
122
122
  Nan::HandleScope scope;
123
123
 
124
124
  Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
@@ -126,15 +126,14 @@ void DeviceINQ::Init(Handle<Object> target) {
126
126
  t->InstanceTemplate()->SetInternalFieldCount(1);
127
127
  t->SetClassName(Nan::New("DeviceINQ").ToLocalChecked());
128
128
 
129
+ Isolate *isolate = target->GetIsolate();
130
+ Local<Context> ctx = isolate->GetCurrentContext();
131
+
129
132
  Nan::SetPrototypeMethod(t, "inquireSync", InquireSync);
130
133
  Nan::SetPrototypeMethod(t, "inquire", Inquire);
131
134
  Nan::SetPrototypeMethod(t, "findSerialPortChannel", SdpSearch);
132
135
  Nan::SetPrototypeMethod(t, "listPairedDevices", ListPairedDevices);
133
- target->Set(Nan::New("DeviceINQ").ToLocalChecked(), t->GetFunction());
134
- target->Set(Nan::New("DeviceINQ").ToLocalChecked(), t->GetFunction());
135
- target->Set(Nan::New("DeviceINQ").ToLocalChecked(), t->GetFunction());
136
- target->Set(Nan::New("DeviceINQ").ToLocalChecked(), t->GetFunction());
137
-
136
+ target->Set(ctx, Nan::New("DeviceINQ").ToLocalChecked(), t->GetFunction(ctx).ToLocalChecked());
138
137
  }
139
138
 
140
139
  NSArray *DeviceINQ::doInquire() {
@@ -216,6 +215,7 @@ NAN_METHOD(DeviceINQ::InquireSync) {
216
215
  NSValue *boxedDevice;
217
216
  NSArray *inquiryResult = doInquire();
218
217
  NSEnumerator *enumerator = [inquiryResult objectEnumerator];
218
+ Nan::AsyncResource resource("bluetooth-serial-port:inqureSync");
219
219
  while (boxedDevice = [enumerator nextObject]) {
220
220
  struct bt_device device;
221
221
 
@@ -225,10 +225,10 @@ NAN_METHOD(DeviceINQ::InquireSync) {
225
225
  Nan::New(device.name).ToLocalChecked()
226
226
  };
227
227
 
228
- found->Call(2, argv);
228
+ found->Call(2, argv, &resource);
229
229
  }
230
230
 
231
- callback->Call(0, 0);
231
+ callback->Call(0, 0, &resource);
232
232
  [inquiryResult release];
233
233
 
234
234
  return;
@@ -243,7 +243,7 @@ NAN_METHOD(DeviceINQ::SdpSearch) {
243
243
  if (!info[0]->IsString()) {
244
244
  return Nan::ThrowTypeError("First argument should be a string value");
245
245
  }
246
- String::Utf8Value address(info[0]);
246
+ String::Utf8Value address(info.GetIsolate(), info[0]);
247
247
 
248
248
  if(!info[1]->IsFunction()) {
249
249
  return Nan::ThrowTypeError("Second argument must be a function");
@@ -294,8 +294,8 @@ NAN_METHOD(DeviceINQ::ListPairedDevices) {
294
294
 
295
295
  Local<Object> deviceObj = Nan::New<v8::Object>();
296
296
 
297
- deviceObj->Set(Nan::New("name").ToLocalChecked(), Nan::New([device.nameOrAddress UTF8String]).ToLocalChecked());
298
- deviceObj->Set(Nan::New("address").ToLocalChecked(), Nan::New([device.addressString UTF8String]).ToLocalChecked());
297
+ Nan::Set(deviceObj, Nan::New("name").ToLocalChecked(), Nan::New([device.nameOrAddress UTF8String]).ToLocalChecked());
298
+ Nan::Set(deviceObj, Nan::New("address").ToLocalChecked(), Nan::New([device.addressString UTF8String]).ToLocalChecked());
299
299
 
300
300
  // A device may have multiple services, so enumerate each one
301
301
  Local<Array> servicesArray = Nan::New<v8::Array>((int)device.services.count);
@@ -305,26 +305,24 @@ NAN_METHOD(DeviceINQ::ListPairedDevices) {
305
305
  [service getRFCOMMChannelID:&channelID];
306
306
 
307
307
  Local<Object> serviceObj = Nan::New<v8::Object>();
308
- serviceObj->Set(Nan::New("channel").ToLocalChecked(), Nan::New((int)channelID));
308
+ Nan::Set(serviceObj, Nan::New("channel").ToLocalChecked(), Nan::New((int)channelID));
309
309
 
310
310
  if ([service getServiceName])
311
- serviceObj->Set(Nan::New("name").ToLocalChecked(), Nan::New([[service getServiceName] UTF8String]).ToLocalChecked());
311
+ Nan::Set(serviceObj, Nan::New("name").ToLocalChecked(), Nan::New([[service getServiceName] UTF8String]).ToLocalChecked());
312
312
  else
313
- serviceObj->Set(Nan::New("name").ToLocalChecked(), Nan::Undefined());
313
+ Nan::Set(serviceObj, Nan::New("name").ToLocalChecked(), Nan::Undefined());
314
314
 
315
- servicesArray->Set(j, serviceObj);
315
+ Nan::Set(servicesArray, j, serviceObj);
316
316
  }
317
- deviceObj->Set(Nan::New("services").ToLocalChecked(), servicesArray);
317
+ Nan::Set(deviceObj, Nan::New("services").ToLocalChecked(), servicesArray);
318
318
 
319
- resultArray->Set(i, deviceObj);
319
+ Nan::Set(resultArray, i, deviceObj);
320
320
  }
321
321
 
322
322
  Local<Value> argv[1] = {
323
323
  resultArray
324
324
  };
325
- cb->Call(Nan::GetCurrentContext()->Global(), 1, argv);
325
+ cb->Call(Nan::GetCurrentContext(), Nan::GetCurrentContext()->Global(), 1, argv);
326
326
 
327
327
  return;
328
328
  }
329
-
330
-
File without changes
File without changes
@@ -61,9 +61,9 @@ void BTSerialPortBinding::EIO_AfterConnect(uv_work_t *req) {
61
61
  connect_baton_t *baton = static_cast<connect_baton_t *>(req->data);
62
62
 
63
63
  Nan::TryCatch try_catch;
64
-
64
+ Nan::AsyncResource resource("bluetooth-serial-port:Connect");
65
65
  if (baton->status == 0) {
66
- baton->cb->Call(0, nullptr);
66
+ baton->cb->Call(0, nullptr, &resource);
67
67
  } else {
68
68
  if (baton->rfcomm->s != INVALID_SOCKET) {
69
69
  closesocket(baton->rfcomm->s);
@@ -74,7 +74,7 @@ void BTSerialPortBinding::EIO_AfterConnect(uv_work_t *req) {
74
74
  Local<Value> argv[] = {
75
75
  Nan::Error(msg)
76
76
  };
77
- baton->ecb->Call(1, argv);
77
+ baton->ecb->Call(1, argv, &resource);
78
78
  }
79
79
 
80
80
  if (try_catch.HasCaught()) {
@@ -127,7 +127,8 @@ void BTSerialPortBinding::EIO_AfterWrite(uv_work_t *req) {
127
127
  argv[1] = Nan::New<v8::Integer>(static_cast<int32_t>(data->result));
128
128
  }
129
129
 
130
- data->callback->Call(2, argv);
130
+ Nan::AsyncResource resource("bluetooth-serial-port:Write");
131
+ data->callback->Call(2, argv, &resource);
131
132
 
132
133
  uv_mutex_lock(&write_queue_mutex);
133
134
  ngx_queue_remove(&queuedWrite->queue);
@@ -187,18 +188,14 @@ void BTSerialPortBinding::EIO_AfterRead(uv_work_t *req) {
187
188
  argv[0] = Nan::Error("Error reading from connection");
188
189
  argv[1] = Nan::Undefined();
189
190
  } else {
190
- Local<Object> globalObj = Nan::GetCurrentContext()->Global();
191
- Local<Function> bufferConstructor = Local<Function>::Cast(globalObj->Get(Nan::New("Buffer").ToLocalChecked()));
192
- Local<Value> constructorArgs[1] = { Nan::New<v8::Integer>(baton->size) };
193
- Local<Object> resultBuffer = Nan::NewInstance(bufferConstructor, 1, constructorArgs).ToLocalChecked();
194
-
191
+ Local<Object> resultBuffer = Nan::NewBuffer(baton->size).ToLocalChecked();
195
192
  memcpy_s(Buffer::Data(resultBuffer), baton->size, baton->result, baton->size);
196
-
197
193
  argv[0] = Nan::Undefined();
198
194
  argv[1] = resultBuffer;
199
195
  }
200
196
 
201
- baton->cb->Call(2, argv);
197
+ Nan::AsyncResource resource("bluetooth-serial-port:Read");
198
+ baton->cb->Call(2, argv, &resource);
202
199
 
203
200
  if (try_catch.HasCaught()) {
204
201
  Nan::FatalException(try_catch);
@@ -210,20 +207,21 @@ void BTSerialPortBinding::EIO_AfterRead(uv_work_t *req) {
210
207
  baton = nullptr;
211
208
  }
212
209
 
213
- void BTSerialPortBinding::Init(Handle<Object> target) {
210
+ void BTSerialPortBinding::Init(Local<Object> target) {
214
211
  Nan::HandleScope scope;
215
212
 
216
213
  Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
217
214
 
215
+ Isolate *isolate = target->GetIsolate();
216
+ Local<Context> ctx = isolate->GetCurrentContext();
217
+
218
218
  t->InstanceTemplate()->SetInternalFieldCount(1);
219
219
  t->SetClassName(Nan::New("BTSerialPortBinding").ToLocalChecked());
220
220
 
221
221
  Nan::SetPrototypeMethod(t, "write", Write);
222
222
  Nan::SetPrototypeMethod(t, "read", Read);
223
223
  Nan::SetPrototypeMethod(t, "close", Close);
224
- target->Set(Nan::New("BTSerialPortBinding").ToLocalChecked(), t->GetFunction());
225
- target->Set(Nan::New("BTSerialPortBinding").ToLocalChecked(), t->GetFunction());
226
- target->Set(Nan::New("BTSerialPortBinding").ToLocalChecked(), t->GetFunction());
224
+ target->Set(ctx, Nan::New("BTSerialPortBinding").ToLocalChecked(), t->GetFunction(ctx).ToLocalChecked());
227
225
  }
228
226
 
229
227
  BTSerialPortBinding::BTSerialPortBinding() : s(INVALID_SOCKET) {
@@ -244,8 +242,8 @@ NAN_METHOD(BTSerialPortBinding::New) {
244
242
  return Nan::ThrowError("usage: BTSerialPortBinding(address, channelID, callback, error)");
245
243
  }
246
244
 
247
- String::Utf8Value address(info[0]);
248
- int channelID = info[1]->Int32Value();
245
+ String::Utf8Value address(info.GetIsolate(), info[0]);
246
+ int channelID = info[1]->Int32Value(Nan::GetCurrentContext()).ToChecked();
249
247
  if (channelID <= 0) {
250
248
  return Nan::ThrowTypeError("ChannelID should be a positive int value");
251
249
  }
@@ -353,8 +351,9 @@ NAN_METHOD(BTSerialPortBinding::Read) {
353
351
  argv[0] = Nan::Error("The connection has been closed");
354
352
  argv[1] = Nan::Undefined();
355
353
 
354
+ Nan::AsyncResource resource("bluetooth-serial-port:Read");
356
355
  Nan::Callback *nc = new Nan::Callback(cb);
357
- nc->Call(2, argv);
356
+ nc->Call(2, argv, &resource);
358
357
  } else {
359
358
  read_baton_t *baton = new read_baton_t();
360
359
  baton->rfcomm = rfcomm;