bluetooth-serial-port 3.0.1 → 3.0.3
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/.circleci/config.yml +29 -17
- package/Dockerfile +1 -1
- package/README.md +3 -2
- package/RELEASE_NOTES.md +10 -0
- package/appveyor.yml +11 -16
- package/package.json +3 -3
- package/src/linux/BTSerialPortBinding.cc +1 -0
- package/src/linux/DeviceINQ.cc +7 -1
- package/src/windows/BTSerialPortBinding.cc +1 -0
- package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv.h +0 -1724
- 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
- package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@darwin.h +0 -61
- 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
- package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@errno.h +0 -443
- 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
- package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@threadpool.h +0 -37
- 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
- package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@unix.h +0 -491
- 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
- package/.ccls-cache/@@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/@usr@local@Cellar@libuv@1.31.0@include@uv@version.h +0 -43
- 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
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@DeviceINQ.h +0 -78
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@DeviceINQ.h.blob +0 -0
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BTSerialPortBinding.cc +0 -404
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BTSerialPortBinding.cc.blob +0 -0
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BluetoothSerialPort.cc +0 -23
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@BluetoothSerialPort.cc.blob +0 -0
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@DeviceINQ.cc +0 -369
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@linux@DeviceINQ.cc.blob +0 -0
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@BluetoothHelpers.h +0 -24
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@BluetoothHelpers.h.blob +0 -0
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@DeviceINQ.cc +0 -527
- package/.ccls-cache/@Users@eelco@Projects@Figaro@workspace@node-bluetooth-serial-port/src@windows@DeviceINQ.cc.blob +0 -0
- package/Dockerfile.bk +0 -13
- package/qemu-arm-static +0 -0
|
@@ -1,527 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2013, Elmar Langholz
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*
|
|
5
|
-
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
6
|
-
*
|
|
7
|
-
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
8
|
-
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
9
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
#ifndef WIN32_LEAN_AND_MEAN
|
|
13
|
-
#define WIN32_LEAN_AND_MEAN
|
|
14
|
-
#endif
|
|
15
|
-
|
|
16
|
-
#include <Windows.h>
|
|
17
|
-
#include <v8.h>
|
|
18
|
-
#include <node.h>
|
|
19
|
-
#include <string.h>
|
|
20
|
-
#include <stdlib.h>
|
|
21
|
-
#include <node_object_wrap.h>
|
|
22
|
-
#include "../DeviceINQ.h"
|
|
23
|
-
#include "BluetoothHelpers.h"
|
|
24
|
-
|
|
25
|
-
using namespace std;
|
|
26
|
-
using namespace node;
|
|
27
|
-
using namespace v8;
|
|
28
|
-
|
|
29
|
-
void DeviceINQ::EIO_SdpSearch(uv_work_t *req) {
|
|
30
|
-
sdp_baton_t *baton = static_cast<sdp_baton_t *>(req->data);
|
|
31
|
-
|
|
32
|
-
// Default, no channel is found
|
|
33
|
-
baton->channelID = -1;
|
|
34
|
-
|
|
35
|
-
// Construct windows socket bluetooth variables
|
|
36
|
-
DWORD flags = LUP_FLUSHCACHE | LUP_RETURN_ADDR;
|
|
37
|
-
DWORD querySetSize = sizeof(WSAQUERYSET);
|
|
38
|
-
WSAQUERYSET *querySet = (WSAQUERYSET *)malloc(querySetSize);
|
|
39
|
-
if (querySet == nullptr) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
ZeroMemory(querySet, querySetSize);
|
|
44
|
-
querySet->dwSize = querySetSize;
|
|
45
|
-
querySet->dwNameSpace = NS_BTH;
|
|
46
|
-
querySet->lpServiceClassId = (LPGUID)&SerialPortServiceClass_UUID;
|
|
47
|
-
querySet->dwNumberOfCsAddrs = 0;
|
|
48
|
-
querySet->lpszContext = baton->address;
|
|
49
|
-
|
|
50
|
-
// Initiate client device inquiry
|
|
51
|
-
HANDLE lookupServiceHandle;
|
|
52
|
-
int lookupServiceError = WSALookupServiceBegin(querySet, flags, &lookupServiceHandle);
|
|
53
|
-
if (lookupServiceError != SOCKET_ERROR) {
|
|
54
|
-
// Iterate over each found bluetooth service
|
|
55
|
-
bool inquiryComplete = false;
|
|
56
|
-
while (!inquiryComplete) {
|
|
57
|
-
// For each bluetooth service retrieve its corresponding details
|
|
58
|
-
lookupServiceError = WSALookupServiceNext(lookupServiceHandle, flags, &querySetSize, querySet);
|
|
59
|
-
if (lookupServiceError != SOCKET_ERROR) {
|
|
60
|
-
char address[19] = { 0 };
|
|
61
|
-
SOCKADDR_BTH *bluetoothSocketAddress = (SOCKADDR_BTH *)querySet->lpcsaBuffer->RemoteAddr.lpSockaddr;
|
|
62
|
-
baton->channelID = bluetoothSocketAddress->port;
|
|
63
|
-
inquiryComplete = true;
|
|
64
|
-
} else {
|
|
65
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
66
|
-
if (lookupServiceErrorNumber == WSAEFAULT) {
|
|
67
|
-
free(querySet);
|
|
68
|
-
querySet = (WSAQUERYSET *)malloc(querySetSize);
|
|
69
|
-
if (querySet == nullptr) {
|
|
70
|
-
WSALookupServiceEnd(lookupServiceHandle);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
} else if (lookupServiceErrorNumber == WSA_E_NO_MORE) {
|
|
74
|
-
// No more services where found
|
|
75
|
-
inquiryComplete = true;
|
|
76
|
-
} else {
|
|
77
|
-
// Unhandled error
|
|
78
|
-
inquiryComplete = true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
} else {
|
|
83
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
84
|
-
if (lookupServiceErrorNumber != WSASERVICE_NOT_FOUND) {
|
|
85
|
-
free(querySet);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
free(querySet);
|
|
91
|
-
WSALookupServiceEnd(lookupServiceHandle);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
void DeviceINQ::EIO_AfterSdpSearch(uv_work_t *req) {
|
|
95
|
-
Nan::HandleScope scope;
|
|
96
|
-
|
|
97
|
-
sdp_baton_t *baton = static_cast<sdp_baton_t *>(req->data);
|
|
98
|
-
|
|
99
|
-
Nan::TryCatch try_catch;
|
|
100
|
-
|
|
101
|
-
Local<Value> argv[] = {
|
|
102
|
-
Nan::New(baton->channelID)
|
|
103
|
-
};
|
|
104
|
-
baton->cb->Call(1, argv);
|
|
105
|
-
|
|
106
|
-
if (try_catch.HasCaught()) {
|
|
107
|
-
Nan::FatalException(try_catch);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
baton->inquire->Unref();
|
|
111
|
-
delete baton->cb;
|
|
112
|
-
delete baton;
|
|
113
|
-
baton = nullptr;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
void DeviceINQ::Init(Local<Object> target) {
|
|
117
|
-
Nan::HandleScope scope;
|
|
118
|
-
|
|
119
|
-
Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
|
|
120
|
-
|
|
121
|
-
t->InstanceTemplate()->SetInternalFieldCount(1);
|
|
122
|
-
t->SetClassName(Nan::New("DeviceINQ").ToLocalChecked());
|
|
123
|
-
|
|
124
|
-
Isolate *isolate = target->GetIsolate();
|
|
125
|
-
Local<Context> ctx = isolate->GetCurrentContext();
|
|
126
|
-
|
|
127
|
-
Nan::SetPrototypeMethod(t, "inquireSync", InquireSync);
|
|
128
|
-
Nan::SetPrototypeMethod(t, "inquire", Inquire);
|
|
129
|
-
Nan::SetPrototypeMethod(t, "findSerialPortChannel", SdpSearch);
|
|
130
|
-
Nan::SetPrototypeMethod(t, "listPairedDevices", ListPairedDevices);
|
|
131
|
-
target->Set(ctx, Nan::New("DeviceINQ").ToLocalChecked(), t->GetFunction(ctx).ToLocalChecked());
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
bt_inquiry DeviceINQ::doInquire() {
|
|
135
|
-
bt_inquiry inquiryResult;
|
|
136
|
-
|
|
137
|
-
// Construct windows socket bluetooth variables
|
|
138
|
-
DWORD flags = LUP_CONTAINERS | LUP_FLUSHCACHE | LUP_RETURN_NAME | LUP_RETURN_ADDR;
|
|
139
|
-
DWORD querySetSize = sizeof(WSAQUERYSET);
|
|
140
|
-
WSAQUERYSET *querySet = (WSAQUERYSET *)malloc(querySetSize);
|
|
141
|
-
if (querySet == nullptr) {
|
|
142
|
-
Nan::ThrowError("Out of memory: Unable to allocate memory resource for inquiry");
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
ZeroMemory(querySet, querySetSize);
|
|
146
|
-
querySet->dwSize = querySetSize;
|
|
147
|
-
querySet->dwNameSpace = NS_BTH;
|
|
148
|
-
|
|
149
|
-
// Initiate client device inquiry
|
|
150
|
-
HANDLE lookupServiceHandle;
|
|
151
|
-
int lookupServiceError = WSALookupServiceBegin(querySet, flags, &lookupServiceHandle);
|
|
152
|
-
if (lookupServiceError != SOCKET_ERROR) {
|
|
153
|
-
// Iterate over each found bluetooth service
|
|
154
|
-
bool inquiryComplete;
|
|
155
|
-
int max_rsp, num_rsp;
|
|
156
|
-
|
|
157
|
-
max_rsp = 255;
|
|
158
|
-
bt_device * max_bt_device_list = (bt_device*)malloc(max_rsp * sizeof(bt_device));
|
|
159
|
-
|
|
160
|
-
num_rsp = 0;
|
|
161
|
-
inquiryComplete = false;
|
|
162
|
-
while (!inquiryComplete) {
|
|
163
|
-
// For each bluetooth service retrieve its corresponding details
|
|
164
|
-
lookupServiceError = WSALookupServiceNext(lookupServiceHandle, flags, &querySetSize, querySet);
|
|
165
|
-
if (lookupServiceError != SOCKET_ERROR) {
|
|
166
|
-
char address[40] = { 0 };
|
|
167
|
-
DWORD addressLength = _countof(address);
|
|
168
|
-
SOCKADDR_BTH *bluetoothSocketAddress = (SOCKADDR_BTH *)querySet->lpcsaBuffer->RemoteAddr.lpSockaddr;
|
|
169
|
-
BTH_ADDR bluetoothAddress = bluetoothSocketAddress->btAddr;
|
|
170
|
-
|
|
171
|
-
// Emit the corresponding event if we were able to retrieve the address
|
|
172
|
-
int addressToStringError = WSAAddressToString(querySet->lpcsaBuffer->RemoteAddr.lpSockaddr,
|
|
173
|
-
sizeof(SOCKADDR_BTH),
|
|
174
|
-
nullptr,
|
|
175
|
-
address,
|
|
176
|
-
&addressLength);
|
|
177
|
-
if (addressToStringError != SOCKET_ERROR) {
|
|
178
|
-
// Strip any leading and trailing parentheses is encountered
|
|
179
|
-
char strippedAddress[19] = { 0 };
|
|
180
|
-
auto addressString = sscanf_s(address, "(" "%18[^)]" ")", strippedAddress) == 1
|
|
181
|
-
? strippedAddress
|
|
182
|
-
: address;
|
|
183
|
-
|
|
184
|
-
strcpy(max_bt_device_list[num_rsp].address, addressString);
|
|
185
|
-
strcpy(max_bt_device_list[num_rsp].name, querySet->lpszServiceInstanceName);
|
|
186
|
-
num_rsp++;
|
|
187
|
-
}
|
|
188
|
-
} else {
|
|
189
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
190
|
-
if (lookupServiceErrorNumber == WSAEFAULT) {
|
|
191
|
-
free(querySet);
|
|
192
|
-
querySet = (WSAQUERYSET *)malloc(querySetSize);
|
|
193
|
-
if (querySet == nullptr) {
|
|
194
|
-
WSALookupServiceEnd(lookupServiceHandle);
|
|
195
|
-
Nan::ThrowError("Out of memory: Unable to allocate memory resource for inquiry");
|
|
196
|
-
}
|
|
197
|
-
} else if (lookupServiceErrorNumber == WSA_E_NO_MORE) {
|
|
198
|
-
// No more services where found
|
|
199
|
-
inquiryComplete = true;
|
|
200
|
-
} else {
|
|
201
|
-
// Unhandled error
|
|
202
|
-
inquiryComplete = true;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
inquiryResult.num_rsp = num_rsp;
|
|
207
|
-
inquiryResult.devices = (bt_device*)malloc(num_rsp * sizeof(bt_device));
|
|
208
|
-
|
|
209
|
-
for (int i = 0; i < num_rsp; i++) {
|
|
210
|
-
strcpy(inquiryResult.devices[i].address, max_bt_device_list[i].address);
|
|
211
|
-
strcpy(inquiryResult.devices[i].name, max_bt_device_list[i].name);
|
|
212
|
-
}
|
|
213
|
-
free(max_bt_device_list);
|
|
214
|
-
|
|
215
|
-
} else {
|
|
216
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
217
|
-
if (lookupServiceErrorNumber != WSASERVICE_NOT_FOUND) {
|
|
218
|
-
free(querySet);
|
|
219
|
-
Nan::ThrowError("Unable to initiate client device inquiry");
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
free(querySet);
|
|
224
|
-
WSALookupServiceEnd(lookupServiceHandle);
|
|
225
|
-
return inquiryResult;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
DeviceINQ::DeviceINQ() {
|
|
229
|
-
initialized = BluetoothHelpers::Initialize();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
DeviceINQ::~DeviceINQ() {
|
|
233
|
-
if (initialized) {
|
|
234
|
-
BluetoothHelpers::Finalize();
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
NAN_METHOD(DeviceINQ::New) {
|
|
239
|
-
if (info.Length() != 0) {
|
|
240
|
-
return Nan::ThrowError("usage: DeviceINQ()");
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
DeviceINQ *inquire = new DeviceINQ();
|
|
244
|
-
if (!inquire->Initialized) {
|
|
245
|
-
return Nan::ThrowError("Unable to initialize socket library");
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
inquire->Wrap(info.This());
|
|
249
|
-
info.GetReturnValue().Set(info.This());
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
NAN_METHOD(DeviceINQ::InquireSync) {
|
|
253
|
-
const char *usage = "usage: inquireSync(found, callback)";
|
|
254
|
-
if (info.Length() != 2) {
|
|
255
|
-
return Nan::ThrowError(usage);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
Nan::Callback *found = new Nan::Callback(info[0].As<Function>());
|
|
259
|
-
Nan::Callback *callback = new Nan::Callback(info[1].As<Function>());
|
|
260
|
-
|
|
261
|
-
bt_inquiry inquiryResult = DeviceINQ::doInquire();
|
|
262
|
-
for (int i = 0; i < inquiryResult.num_rsp; i++) {
|
|
263
|
-
Local<Value> argv[2] = {
|
|
264
|
-
Nan::New(inquiryResult.devices[i].address).ToLocalChecked(),
|
|
265
|
-
Nan::New(inquiryResult.devices[i].name).ToLocalChecked()
|
|
266
|
-
};
|
|
267
|
-
found->Call(2, argv);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
callback->Call(0, 0);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
class InquireWorker : public Nan::AsyncWorker {
|
|
275
|
-
public:
|
|
276
|
-
InquireWorker(Nan::Callback* found, Nan::Callback *callback)
|
|
277
|
-
: Nan::AsyncWorker(callback), found(found) {}
|
|
278
|
-
~InquireWorker() {}
|
|
279
|
-
|
|
280
|
-
// Executed inside the worker-thread.
|
|
281
|
-
// It is not safe to access V8, or V8 data structures
|
|
282
|
-
// here, so everything we need for input and output
|
|
283
|
-
// should go on `this`.
|
|
284
|
-
void Execute () {
|
|
285
|
-
inquiryResult = DeviceINQ::doInquire();
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Executed when the async work is complete
|
|
289
|
-
// this function will be run inside the main event loop
|
|
290
|
-
// so it is safe to use V8 again
|
|
291
|
-
void HandleOKCallback () {
|
|
292
|
-
Nan::HandleScope scope;
|
|
293
|
-
|
|
294
|
-
for (int i = 0; i < inquiryResult.num_rsp; i++) {
|
|
295
|
-
Local<Value> argv[2] = {
|
|
296
|
-
Nan::New(inquiryResult.devices[i].address).ToLocalChecked(),
|
|
297
|
-
Nan::New(inquiryResult.devices[i].name).ToLocalChecked()
|
|
298
|
-
};
|
|
299
|
-
found->Call(2, argv);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
callback->Call(0, 0);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
private:
|
|
306
|
-
bt_inquiry inquiryResult;
|
|
307
|
-
Nan::Callback* found;
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
// Asynchronous access to the `Inquire()` function
|
|
311
|
-
NAN_METHOD(DeviceINQ::Inquire) {
|
|
312
|
-
const char *usage = "usage: inquire(found, callback)";
|
|
313
|
-
if (info.Length() != 2) {
|
|
314
|
-
return Nan::ThrowError(usage);
|
|
315
|
-
}
|
|
316
|
-
Nan::Callback *found = new Nan::Callback(info[0].As<Function>());
|
|
317
|
-
Nan::Callback *callback = new Nan::Callback(info[1].As<Function>());
|
|
318
|
-
|
|
319
|
-
Nan::AsyncQueueWorker(new InquireWorker(found, callback));
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
NAN_METHOD(DeviceINQ::SdpSearch) {
|
|
323
|
-
if (info.Length() != 2) {
|
|
324
|
-
return Nan::ThrowError("usage: findSerialPortChannel(address, callback)");
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (!info[0]->IsString()) {
|
|
328
|
-
return Nan::ThrowTypeError("First argument should be a string value");
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if(!info[1]->IsFunction()) {
|
|
332
|
-
return Nan::ThrowTypeError("Second argument must be a function");
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
sdp_baton_t *baton = new sdp_baton_t();
|
|
336
|
-
|
|
337
|
-
Local<Function> cb = info[1].As<Function>();
|
|
338
|
-
String::Utf8Value address(cb->GetIsolate(), info[0]->ToString());
|
|
339
|
-
if (strcpy_s(baton->address, *address) != 0) {
|
|
340
|
-
delete baton;
|
|
341
|
-
return Nan::ThrowTypeError("Address (first argument) length is invalid");
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
DeviceINQ *inquire = Nan::ObjectWrap::Unwrap<DeviceINQ>(info.This());
|
|
346
|
-
|
|
347
|
-
baton->inquire = inquire;
|
|
348
|
-
baton->cb = new Nan::Callback(cb);
|
|
349
|
-
baton->channelID = -1;
|
|
350
|
-
baton->request.data = baton;
|
|
351
|
-
baton->inquire->Ref();
|
|
352
|
-
|
|
353
|
-
uv_queue_work(uv_default_loop(), &baton->request, EIO_SdpSearch, (uv_after_work_cb)EIO_AfterSdpSearch);
|
|
354
|
-
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
NAN_METHOD(DeviceINQ::ListPairedDevices) {
|
|
359
|
-
const char *usage = "usage: listPairedDevices(callback)";
|
|
360
|
-
if (info.Length() != 1) {
|
|
361
|
-
return Nan::ThrowError(usage);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if(!info[0]->IsFunction()) {
|
|
365
|
-
return Nan::ThrowTypeError("First argument must be a function");
|
|
366
|
-
}
|
|
367
|
-
Local<Function> cb = info[0].As<Function>();
|
|
368
|
-
Local<Array> resultArray = Local<Array>(Nan::New<Array>());
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
// Construct windows socket bluetooth variables
|
|
372
|
-
DWORD flags = LUP_CONTAINERS | LUP_RETURN_ALL;// LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_RES_SERVICE;
|
|
373
|
-
DWORD querySetSize = sizeof(WSAQUERYSET);
|
|
374
|
-
WSAQUERYSET *querySet = (WSAQUERYSET *)malloc(querySetSize);
|
|
375
|
-
if (querySet == nullptr) {
|
|
376
|
-
Nan::ThrowError("Out of memory: Unable to allocate memory resource for inquiry");
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
ZeroMemory(querySet, querySetSize);
|
|
380
|
-
querySet->dwSize = querySetSize;
|
|
381
|
-
querySet->dwNameSpace = NS_BTH;
|
|
382
|
-
|
|
383
|
-
int i = 0;
|
|
384
|
-
|
|
385
|
-
// Initiate client device inquiry
|
|
386
|
-
HANDLE lookupServiceHandle;
|
|
387
|
-
int lookupServiceError = WSALookupServiceBegin(querySet, flags, &lookupServiceHandle);
|
|
388
|
-
if (lookupServiceError != SOCKET_ERROR) {
|
|
389
|
-
// Iterate over each found bluetooth service
|
|
390
|
-
bool inquiryComplete = false;
|
|
391
|
-
while (!inquiryComplete) {
|
|
392
|
-
// For each bluetooth service retrieve its corresponding details
|
|
393
|
-
lookupServiceError = WSALookupServiceNext(lookupServiceHandle, flags, &querySetSize, querySet);
|
|
394
|
-
|
|
395
|
-
// only list devices that are authenticated, paired or bonded
|
|
396
|
-
if (lookupServiceError != SOCKET_ERROR && (querySet->dwOutputFlags & BTHNS_RESULT_DEVICE_AUTHENTICATED)) {
|
|
397
|
-
char address[40] = { 0 };
|
|
398
|
-
DWORD addressLength = _countof(address);
|
|
399
|
-
SOCKADDR_BTH *bluetoothSocketAddress = (SOCKADDR_BTH *)querySet->lpcsaBuffer->RemoteAddr.lpSockaddr;
|
|
400
|
-
BTH_ADDR bluetoothAddress = bluetoothSocketAddress->btAddr;
|
|
401
|
-
|
|
402
|
-
// Emit the corresponding event if we were able to retrieve the address
|
|
403
|
-
int addressToStringError = WSAAddressToString(querySet->lpcsaBuffer->RemoteAddr.lpSockaddr,
|
|
404
|
-
sizeof(SOCKADDR_BTH),
|
|
405
|
-
nullptr,
|
|
406
|
-
address,
|
|
407
|
-
&addressLength);
|
|
408
|
-
if (addressToStringError != SOCKET_ERROR) {
|
|
409
|
-
// Strip any leading and trailing parentheses is encountered
|
|
410
|
-
char strippedAddress[19] = { 0 };
|
|
411
|
-
|
|
412
|
-
sscanf_s(address, "(" "%18[^)]" ")", strippedAddress);
|
|
413
|
-
auto addressString = sscanf_s(address, "(" "%18[^)]" ")", strippedAddress) == 1
|
|
414
|
-
? Nan::New(strippedAddress)
|
|
415
|
-
: Nan::New(address);
|
|
416
|
-
|
|
417
|
-
Local<Object> deviceObj = Nan::New<v8::Object>();
|
|
418
|
-
deviceObj->Set(Nan::New("name").ToLocalChecked(), Nan::New(querySet->lpszServiceInstanceName).ToLocalChecked());
|
|
419
|
-
deviceObj->Set(Nan::New("address").ToLocalChecked(), addressString.ToLocalChecked());
|
|
420
|
-
|
|
421
|
-
Local<Array> servicesArray = Local<Array>(Nan::New<Array>());
|
|
422
|
-
{
|
|
423
|
-
DWORD querySetSize2 = sizeof(WSAQUERYSET);
|
|
424
|
-
WSAQUERYSET *querySet2 = (WSAQUERYSET *)malloc(querySetSize2);
|
|
425
|
-
if (querySet2 == nullptr) {
|
|
426
|
-
Nan::ThrowError("Out of memory: Unable to allocate memory resource for inquiry");
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
ZeroMemory(querySet2, querySetSize2);
|
|
430
|
-
querySet2->dwSize = querySetSize2;
|
|
431
|
-
querySet2->lpszContext = address;
|
|
432
|
-
GUID protocol = RFCOMM_PROTOCOL_UUID ; // L2CAP_PROTOCOL_UUID;
|
|
433
|
-
querySet2->lpServiceClassId = &protocol;
|
|
434
|
-
querySet2->dwNameSpace = NS_BTH;
|
|
435
|
-
|
|
436
|
-
DWORD flags2 = LUP_FLUSHCACHE |LUP_RETURN_NAME | LUP_RETURN_TYPE | LUP_RETURN_ADDR | LUP_RETURN_BLOB | LUP_RETURN_COMMENT;
|
|
437
|
-
HANDLE lookupServiceHandle2;
|
|
438
|
-
|
|
439
|
-
int place = 0;
|
|
440
|
-
int lookupServiceError2 = WSALookupServiceBegin(querySet2, flags2, &lookupServiceHandle2);
|
|
441
|
-
if (lookupServiceError2 != SOCKET_ERROR) {
|
|
442
|
-
bool inquiryComplete2 = false;
|
|
443
|
-
while(!inquiryComplete2) {
|
|
444
|
-
lookupServiceError2 = WSALookupServiceNext(lookupServiceHandle2, flags2, &querySetSize2, querySet2);
|
|
445
|
-
if (lookupServiceError2 != SOCKET_ERROR ) {
|
|
446
|
-
int port = (int)((SOCKADDR_BTH *)querySet2->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
|
|
447
|
-
Local<Object> serviceObj = Nan::New<v8::Object>();
|
|
448
|
-
serviceObj->Set(Nan::New("channel").ToLocalChecked(), Nan::New(port));
|
|
449
|
-
serviceObj->Set(Nan::New("name").ToLocalChecked(), Nan::New(querySet2->lpszServiceInstanceName).ToLocalChecked());
|
|
450
|
-
servicesArray->Set(place++, serviceObj);
|
|
451
|
-
} else {
|
|
452
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
453
|
-
if (lookupServiceErrorNumber == WSAEFAULT) {
|
|
454
|
-
free(querySet2);
|
|
455
|
-
querySet2 = (WSAQUERYSET *)malloc(querySetSize2);
|
|
456
|
-
if (querySet2 == nullptr) {
|
|
457
|
-
WSALookupServiceEnd(lookupServiceHandle2);
|
|
458
|
-
Nan::ThrowError("Out of memory: Unable to allocate memory resource for inquiry");
|
|
459
|
-
}
|
|
460
|
-
} else if (lookupServiceErrorNumber == WSA_E_NO_MORE) {
|
|
461
|
-
// No more services where found
|
|
462
|
-
inquiryComplete2 = true;
|
|
463
|
-
} else {
|
|
464
|
-
// Unhandled error
|
|
465
|
-
inquiryComplete2 = true;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
} else {
|
|
470
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
471
|
-
if (lookupServiceErrorNumber != WSASERVICE_NOT_FOUND) {
|
|
472
|
-
free(querySet);
|
|
473
|
-
Nan::ThrowError("Unable to initiate client device inquiry");
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
free(querySet2);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
deviceObj->Set(Nan::New("services").ToLocalChecked(), servicesArray);
|
|
480
|
-
resultArray->Set(i, deviceObj);
|
|
481
|
-
i = i+1;
|
|
482
|
-
}
|
|
483
|
-
} else {
|
|
484
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
485
|
-
if (lookupServiceErrorNumber == WSAEFAULT) {
|
|
486
|
-
free(querySet);
|
|
487
|
-
querySet = (WSAQUERYSET *)malloc(querySetSize);
|
|
488
|
-
if (querySet == nullptr) {
|
|
489
|
-
WSALookupServiceEnd(lookupServiceHandle);
|
|
490
|
-
Nan::ThrowError("Out of memory: Unable to allocate memory resource for inquiry");
|
|
491
|
-
}
|
|
492
|
-
} else if (lookupServiceErrorNumber == WSA_E_NO_MORE) {
|
|
493
|
-
// No more services where found
|
|
494
|
-
inquiryComplete = true;
|
|
495
|
-
} else {
|
|
496
|
-
// Unhandled error
|
|
497
|
-
inquiryComplete = true;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
} else {
|
|
502
|
-
int lookupServiceErrorNumber = WSAGetLastError();
|
|
503
|
-
if (lookupServiceErrorNumber != WSASERVICE_NOT_FOUND) {
|
|
504
|
-
free(querySet);
|
|
505
|
-
Nan::ThrowError("Unable to initiate client device inquiry");
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
free(querySet);
|
|
510
|
-
WSALookupServiceEnd(lookupServiceHandle);
|
|
511
|
-
|
|
512
|
-
//build an array of objects representing a paired device:
|
|
513
|
-
// ex: {
|
|
514
|
-
// name: 'MyBluetoothDeviceName',
|
|
515
|
-
// address: '12-34-56-78-90',
|
|
516
|
-
// services: [
|
|
517
|
-
// { name: 'SPP', channel: 1 },
|
|
518
|
-
// { name: 'iAP', channel: 2 }
|
|
519
|
-
// ]
|
|
520
|
-
// }
|
|
521
|
-
Local<Value> argv[1] = {
|
|
522
|
-
resultArray
|
|
523
|
-
};
|
|
524
|
-
cb->Call(Nan::GetCurrentContext(), Nan::GetCurrentContext()->Global(), 1, argv);
|
|
525
|
-
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
Binary file
|
package/Dockerfile.bk
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
ARG BASE_IMAGE=node:latest
|
|
2
|
-
FROM $BASE_IMAGE
|
|
3
|
-
|
|
4
|
-
COPY qemu-arm-static /usr/bin
|
|
5
|
-
|
|
6
|
-
RUN apt-get update && \
|
|
7
|
-
apt-get install -y build-essential libbluetooth-dev
|
|
8
|
-
|
|
9
|
-
ADD . node-bluetooth-serial-port
|
|
10
|
-
WORKDIR node-bluetooth-serial-port
|
|
11
|
-
|
|
12
|
-
RUN npm install --unsafe-perm && \
|
|
13
|
-
rm /usr/bin/qemu-arm-static
|
package/qemu-arm-static
DELETED
|
Binary file
|