bluetooth-serial-port 2.2.7 → 3.0.1
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 +47 -0
- package/.github/dependabot.yml +11 -0
- package/Dockerfile +1 -1
- package/README.md +95 -78
- package/RELEASE_NOTES.md +9 -0
- package/appveyor.yml +6 -8
- package/binding.gyp +0 -8
- package/lib/bluetooth-serial-port.d.ts +1 -1
- package/package.json +56 -58
- package/src/linux/BTSerialPortBinding.cc +11 -10
- package/src/linux/BTSerialPortBindingServer.cc +18 -14
- package/src/linux/DeviceINQ.cc +11 -8
- package/src/{osx → macos}/BTSerialPortBinding.mm +10 -9
- package/src/{osx → macos}/BluetoothDeviceResources.h +0 -0
- package/src/{osx → macos}/BluetoothDeviceResources.mm +0 -0
- package/src/{osx → macos}/BluetoothSerialPort.mm +0 -0
- package/src/{osx → macos}/BluetoothWorker.h +3 -3
- package/src/{osx → macos}/BluetoothWorker.mm +26 -27
- package/src/{osx → macos}/DeviceINQ.mm +14 -13
- package/src/{osx → macos}/pipe.c +0 -0
- package/src/{osx → macos}/pipe.h +0 -0
- package/src/windows/BTSerialPortBinding.cc +10 -12
- package/src/windows/DeviceINQ.cc +7 -7
- package/.travis.yml +0 -47
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
|
2
|
+
# See: https://circleci.com/docs/2.0/configuration-reference
|
|
3
|
+
version: 2.1
|
|
4
|
+
|
|
5
|
+
orbs:
|
|
6
|
+
# The Node.js orb contains a set of prepackaged CircleCI configuration you can utilize
|
|
7
|
+
# Orbs reduce the amount of configuration required for common tasks.
|
|
8
|
+
# See the orb documentation here: https://circleci.com/developer/orbs/orb/circleci/node
|
|
9
|
+
node: circleci/node@4.1
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-14:
|
|
13
|
+
docker:
|
|
14
|
+
- image: node:14
|
|
15
|
+
steps:
|
|
16
|
+
- checkout
|
|
17
|
+
- run:
|
|
18
|
+
name: Install dependencies
|
|
19
|
+
command: apt-get update && apt-get install -y build-essential libbluetooth-dev
|
|
20
|
+
- node/install-packages
|
|
21
|
+
|
|
22
|
+
build-16:
|
|
23
|
+
docker:
|
|
24
|
+
- image: node:16
|
|
25
|
+
steps:
|
|
26
|
+
- checkout
|
|
27
|
+
- run:
|
|
28
|
+
name: Install build dependencies
|
|
29
|
+
command: apt-get update && apt-get install -y build-essential libbluetooth-dev
|
|
30
|
+
- node/install-packages
|
|
31
|
+
|
|
32
|
+
build-18:
|
|
33
|
+
docker:
|
|
34
|
+
- image: node:18
|
|
35
|
+
steps:
|
|
36
|
+
- checkout
|
|
37
|
+
- run:
|
|
38
|
+
name: Install build dependencies
|
|
39
|
+
command: apt-get update && apt-get install -y build-essential libbluetooth-dev
|
|
40
|
+
- node/install-packages
|
|
41
|
+
|
|
42
|
+
workflows:
|
|
43
|
+
build:
|
|
44
|
+
jobs:
|
|
45
|
+
- build-14
|
|
46
|
+
- build-16
|
|
47
|
+
- build-18
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
|
3
|
+
# Please see the documentation for all configuration options:
|
|
4
|
+
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
5
|
+
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: "npm" # See documentation for possible values
|
|
9
|
+
directory: "/" # Location of package manifests
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "daily"
|
package/Dockerfile
CHANGED
package/README.md
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
# Bluetooth serial port communication for Node.js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Consider a donation
|
|
4
|
+
|
|
5
|
+
This piece of open source software is free (as in speech) to [use, modify and distribute](LICENSE.md), no strings attached. If this software saves you some cash and you want to do something for the good please consider making a donation to a [charity](https://www.doctorswithoutborders.org). Any charity will do. 🙏
|
|
6
|
+
|
|
7
|
+
> MacOS support has (temporarily) been dropped as of version v3.0.0 of the module. If you use the module on a Mac please stay on v2 of this module.
|
|
8
|
+
|
|
9
|
+
> _DEPRECATED_ Currently I have no plans to add support for NodeJS version 1.13 and up. If you want to help out by adding support please contact me. It was a great experience maintaining this project for almost 8 years. It was great to see people step in to improve this project. Thank you all!
|
|
10
|
+
|
|
11
|
+
[](https://dl.circleci.com/status-badge/redirect/gh/eelcocramer/node-bluetooth-serial-port/tree/master)
|
|
4
12
|
[](https://ci.appveyor.com/project/eelcocramer/node-bluetooth-serial-port)
|
|
5
13
|
|
|
6
|
-
This node module lets you communicate over Bluetooth serial port with devices using
|
|
14
|
+
This node module lets you communicate over Bluetooth serial port with devices using NodeJS. The goal is have an easy to use API. This module is great for communicating with Bluetooth enabled Arduino devices.
|
|
7
15
|
|
|
8
16
|
If you have any problems make sure to [checkout the FAQ](https://github.com/eelcocramer/node-bluetooth-serial-port/issues?q=label%3AFAQ).
|
|
9
17
|
|
|
10
18
|
## New in the last release
|
|
11
19
|
|
|
12
|
-
|
|
20
|
+
- Changes node version to `lts` in the Dockerfile
|
|
13
21
|
|
|
14
22
|
Check the [release notes](RELEASE_NOTES.md) for an overview of the change history.
|
|
15
23
|
|
|
16
24
|
## Prerequisites on Linux
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
- Needs Bluetooth development packages to build
|
|
19
27
|
|
|
20
28
|
`apt-get install build-essential libbluetooth-dev`
|
|
21
29
|
|
|
22
30
|
### Note on RFCOMM Server Sockets
|
|
23
|
-
|
|
31
|
+
|
|
32
|
+
As the initial implementation of the RFCOMM server sockets is based on BlueZ4, in order to work with SDP we need to change the bluetooth service configuration file by modifing the systemd unit file: bluetooth.service:
|
|
24
33
|
|
|
25
34
|
(Debian based distro)
|
|
26
35
|
|
|
@@ -41,14 +50,10 @@ sudo systemctl daemon-reload
|
|
|
41
50
|
sudo systemctl restart bluetooth
|
|
42
51
|
```
|
|
43
52
|
|
|
44
|
-
## Prerequisites on macOS
|
|
45
|
-
|
|
46
|
-
* Needs Xcode and Xcode command line tools installed.
|
|
47
|
-
|
|
48
53
|
## Prerequisites on Windows
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
- Needs Visual Studio (Visual C++) and its command line tools installed.
|
|
56
|
+
- Needs Python 2.x installed and accessible from the command line path.
|
|
52
57
|
|
|
53
58
|
## Install
|
|
54
59
|
|
|
@@ -63,64 +68,78 @@ sudo systemctl restart bluetooth
|
|
|
63
68
|
## Basic client usage
|
|
64
69
|
|
|
65
70
|
```javascript
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
btSerial.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
71
|
+
var btSerial = new (require("bluetooth-serial-port").BluetoothSerialPort)();
|
|
72
|
+
|
|
73
|
+
btSerial.on("found", function (address, name) {
|
|
74
|
+
btSerial.findSerialPortChannel(
|
|
75
|
+
address,
|
|
76
|
+
function (channel) {
|
|
77
|
+
btSerial.connect(
|
|
78
|
+
address,
|
|
79
|
+
channel,
|
|
80
|
+
function () {
|
|
81
|
+
console.log("connected");
|
|
82
|
+
|
|
83
|
+
btSerial.write(
|
|
84
|
+
Buffer.from("my data", "utf-8"),
|
|
85
|
+
function (err, bytesWritten) {
|
|
86
|
+
if (err) console.log(err);
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
btSerial.on("data", function (buffer) {
|
|
91
|
+
console.log(buffer.toString("utf-8"));
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
function () {
|
|
95
|
+
console.log("cannot connect");
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// close the connection when you're ready
|
|
100
|
+
btSerial.close();
|
|
101
|
+
},
|
|
102
|
+
function () {
|
|
103
|
+
console.log("found nothing");
|
|
104
|
+
}
|
|
105
|
+
);
|
|
90
106
|
});
|
|
91
107
|
|
|
92
108
|
btSerial.inquire();
|
|
93
|
-
|
|
94
109
|
```
|
|
95
110
|
|
|
96
111
|
## Basic server usage (only on Linux)
|
|
97
112
|
|
|
98
113
|
```javascript
|
|
99
|
-
var server = new(require(
|
|
114
|
+
var server = new (require("bluetooth-serial-port").BluetoothSerialPortServer)();
|
|
100
115
|
|
|
101
116
|
var CHANNEL = 10; // My service channel. Defaults to 1 if omitted.
|
|
102
|
-
var UUID =
|
|
117
|
+
var UUID = "38e851bc-7144-44b4-9cd8-80549c6f2912"; // My own service UUID. Defaults to '1101' if omitted
|
|
103
118
|
|
|
104
|
-
server.on(
|
|
105
|
-
console.log(
|
|
119
|
+
server.on("data", function (buffer) {
|
|
120
|
+
console.log("Received data from client: " + buffer);
|
|
106
121
|
|
|
107
122
|
// ...
|
|
108
123
|
|
|
109
|
-
console.log(
|
|
110
|
-
server.write(Buffer.from(
|
|
124
|
+
console.log("Sending data to the client");
|
|
125
|
+
server.write(Buffer.from("..."), function (err, bytesWritten) {
|
|
111
126
|
if (err) {
|
|
112
|
-
console.log(
|
|
127
|
+
console.log("Error!");
|
|
113
128
|
} else {
|
|
114
|
-
console.log(
|
|
129
|
+
console.log("Send " + bytesWritten + " to the client!");
|
|
115
130
|
}
|
|
116
131
|
});
|
|
117
132
|
});
|
|
118
133
|
|
|
119
|
-
server.listen(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
server.listen(
|
|
135
|
+
function (clientAddress) {
|
|
136
|
+
console.log("Client: " + clientAddress + " connected!");
|
|
137
|
+
},
|
|
138
|
+
function (error) {
|
|
139
|
+
console.error("Something wrong happened!:" + error);
|
|
140
|
+
},
|
|
141
|
+
{ uuid: UUID, channel: CHANNEL }
|
|
142
|
+
);
|
|
124
143
|
```
|
|
125
144
|
|
|
126
145
|
## API
|
|
@@ -131,7 +150,7 @@ server.listen(function (clientAddress) {
|
|
|
131
150
|
|
|
132
151
|
Emitted when data is read from the serial port connection.
|
|
133
152
|
|
|
134
|
-
|
|
153
|
+
- buffer - the data that was read into a [Buffer](http://nodejs.org/api/buffer.html) object.
|
|
135
154
|
|
|
136
155
|
#### Event: ('closed')
|
|
137
156
|
|
|
@@ -141,14 +160,14 @@ Emitted when a connection was closed either by the user (i.e. calling `close` or
|
|
|
141
160
|
|
|
142
161
|
Emitted when reading from the serial port connection results in an error. The connection is closed.
|
|
143
162
|
|
|
144
|
-
|
|
163
|
+
- err - an [Error object](http://docs.nodejitsu.com/articles/errors/what-is-the-error-object) describing the failure.
|
|
145
164
|
|
|
146
165
|
#### Event: ('found', address, name)
|
|
147
166
|
|
|
148
167
|
Emitted when a bluetooth device was found.
|
|
149
168
|
|
|
150
|
-
|
|
151
|
-
|
|
169
|
+
- address - the address of the device
|
|
170
|
+
- name - the name of the device (or the address if the name is unavailable)
|
|
152
171
|
|
|
153
172
|
#### Event: ('finished')
|
|
154
173
|
|
|
@@ -166,14 +185,14 @@ Starts searching synchronously for bluetooth devices. When a device is found a '
|
|
|
166
185
|
|
|
167
186
|
Checks if a device has a serial port service running and if it is found it passes the channel id to use for the RFCOMM connection.
|
|
168
187
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
Connects to a remote bluetooth device.
|
|
188
|
+
- callback(channel) - called when finished looking for a serial port on the device.
|
|
189
|
+
- errorCallback - called the search finished but no serial port channel was found on the device.
|
|
190
|
+
Connects to a remote bluetooth device.
|
|
172
191
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
192
|
+
- bluetoothAddress - the address of the remote Bluetooth device.
|
|
193
|
+
- channel - the channel to connect to.
|
|
194
|
+
- [successCallback] - called when a connection has been established.
|
|
195
|
+
- [errorCallback(err)] - called when the connection attempt results in an error. The parameter is an [Error object](http://docs.nodejitsu.com/articles/errors/what-is-the-error-object).
|
|
177
196
|
|
|
178
197
|
#### BluetoothSerialPort.close()
|
|
179
198
|
|
|
@@ -187,16 +206,16 @@ Check whether the connection is open or not.
|
|
|
187
206
|
|
|
188
207
|
Writes a [Buffer](http://nodejs.org/api/buffer.html) to the serial port connection.
|
|
189
208
|
|
|
190
|
-
|
|
191
|
-
|
|
209
|
+
- buffer - the [Buffer](http://nodejs.org/api/buffer.html) to be written.
|
|
210
|
+
- callback(err, bytesWritten) - is called when the write action has been completed. When the `err` parameter is set an error has occured, in that case `err` is an [Error object](http://docs.nodejitsu.com/articles/errors/what-is-the-error-object). When `err` is not set the write action was successful and `bytesWritten` contains the amount of bytes that is written to the connection.
|
|
192
211
|
|
|
193
212
|
#### BluetoothSerialPort.listPairedDevices(callback)
|
|
194
213
|
|
|
195
|
-
|
|
214
|
+
**NOT AVAILABLE ON LINUX**
|
|
196
215
|
|
|
197
216
|
Lists the devices that are currently paired with the host.
|
|
198
217
|
|
|
199
|
-
|
|
218
|
+
- callback(pairedDevices) - is called when the paired devices object has been populated. See the [pull request](https://github.com/eelcocramer/node-bluetooth-serial-port/pull/30) for more information on the `pairedDevices` object.
|
|
200
219
|
|
|
201
220
|
### BluetoothSerialPortServer
|
|
202
221
|
|
|
@@ -204,24 +223,22 @@ Lists the devices that are currently paired with the host.
|
|
|
204
223
|
|
|
205
224
|
Listens for an incoming bluetooth connection. It will automatically advertise the server via SDP
|
|
206
225
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
226
|
+
- callback(address) - is called when a new client is connecting.
|
|
227
|
+
- errorCallback(err) - is called when an error occurs.
|
|
228
|
+
- options - An object with these properties:
|
|
229
|
+
|
|
230
|
+
- uuid - [String] The UUID of the server. If omitted the default value will be 1101 (corresponding to Serial Port Profile UUID). Can be a 16 bit or 32 bit UUID.
|
|
231
|
+
- channel - [Number] The RFCOMM channel the server is listening on, in the range of 1-30. If omitted the default value will be 1.
|
|
212
232
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
uuid: 'ffffffff-ffff-ffff-ffff-fffffffffff1',
|
|
216
|
-
channel: 10
|
|
217
|
-
}`
|
|
233
|
+
Example:
|
|
234
|
+
`var options = { uuid: 'ffffffff-ffff-ffff-ffff-fffffffffff1', channel: 10 }`
|
|
218
235
|
|
|
219
236
|
#### BluetoothSerialPortServer.write(buffer, callback)
|
|
220
237
|
|
|
221
238
|
Writes data from a buffer to a connection.
|
|
222
239
|
|
|
223
|
-
|
|
224
|
-
|
|
240
|
+
- buffer - the buffer to send over the connection.
|
|
241
|
+
- callback(err, len) - called when the data is send or an error did occur. `error` contains the error is appropriated. `len` has the number of bytes that were written to the connection.
|
|
225
242
|
|
|
226
243
|
#### BluetoothSerialPortServer.close()
|
|
227
244
|
|
|
@@ -239,7 +256,7 @@ Checks is a server is listening or not.
|
|
|
239
256
|
|
|
240
257
|
Emitted when data is read from the serial port connection.
|
|
241
258
|
|
|
242
|
-
|
|
259
|
+
- buffer - the data that was read into a [Buffer](http://nodejs.org/api/buffer.html) object.
|
|
243
260
|
|
|
244
261
|
#### Event: ('disconnected')
|
|
245
262
|
|
|
@@ -253,7 +270,7 @@ Emitted when the server is closed (i.e. from calling `close` or as the result of
|
|
|
253
270
|
|
|
254
271
|
Emitted when reading from the serial port connection results in an error. The connection is closed.
|
|
255
272
|
|
|
256
|
-
|
|
273
|
+
- err - an [Error object](http://docs.nodejitsu.com/articles/errors/what-is-the-error-object) describing the failure.
|
|
257
274
|
|
|
258
275
|
## Typescript support
|
|
259
276
|
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## RELEASE NOTES
|
|
2
2
|
|
|
3
|
+
### 3.0.1
|
|
4
|
+
|
|
5
|
+
* Fixes typescript definition for `listPairedDevices`.
|
|
6
|
+
|
|
7
|
+
### 3.0.0
|
|
8
|
+
|
|
9
|
+
* Fixes building issues with recent version of NodeJS.
|
|
10
|
+
* Drops support for Darwin / MacOS for the moment. If you want to use the module on a Mac please install v2.2.7.
|
|
11
|
+
|
|
3
12
|
### 2.2.7
|
|
4
13
|
|
|
5
14
|
* Changes node version to `lts` in the Dockerfile
|
package/appveyor.yml
CHANGED
|
@@ -4,14 +4,12 @@ environment:
|
|
|
4
4
|
# Test against these versions of Node.js and io.js
|
|
5
5
|
matrix:
|
|
6
6
|
# node.js
|
|
7
|
-
- nodejs_version: "
|
|
8
|
-
- nodejs_version: "
|
|
9
|
-
- nodejs_version: "
|
|
10
|
-
|
|
11
|
-
- nodejs_version: "12"
|
|
7
|
+
- nodejs_version: "14"
|
|
8
|
+
- nodejs_version: "16"
|
|
9
|
+
- nodejs_version: "18"
|
|
10
|
+
|
|
12
11
|
|
|
13
12
|
platform:
|
|
14
|
-
- x86
|
|
15
13
|
- x64
|
|
16
14
|
|
|
17
15
|
# Install scripts. (runs after repo cloning)
|
|
@@ -23,8 +21,8 @@ install:
|
|
|
23
21
|
- npm -g install npm@latest
|
|
24
22
|
- npm --version
|
|
25
23
|
- node -e "console.log(process.arch);"
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
#- if "%PLATFORM%" == "x64" SET PATH=C:\Python27-x64;%PATH%
|
|
25
|
+
#- if "%PLATFORM%" == "x86" SET PATH=C:\python27;%PATH%
|
|
28
26
|
- npm install node-gyp
|
|
29
27
|
- npm update
|
|
30
28
|
- npm run install-debug
|
package/binding.gyp
CHANGED
|
@@ -11,14 +11,6 @@
|
|
|
11
11
|
'libraries': ['-lbluetooth'],
|
|
12
12
|
'cflags':['-std=c++11']
|
|
13
13
|
}],
|
|
14
|
-
[ 'OS=="mac"', {
|
|
15
|
-
'sources': ['src/osx/DeviceINQ.mm', 'src/osx/BluetoothWorker.mm', 'src/osx/pipe.c', 'src/osx/BluetoothDeviceResources.mm', 'src/osx/BluetoothSerialPort.mm', 'src/osx/BTSerialPortBinding.mm'],
|
|
16
|
-
'include_dirs' : [ "<!(node -e \"require('nan')\")", 'src', 'src/osx' ],
|
|
17
|
-
'libraries':['-framework Foundation', '-framework IOBluetooth', '-fobjc-arc'],
|
|
18
|
-
'cflags!': [ '-fno-exceptions' ],
|
|
19
|
-
'cflags_cc!': [ '-fno-exceptions' ],
|
|
20
|
-
'xcode_settings': { 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', 'OTHER_CFLAGS': [ '-Wno-unused-function' ] }
|
|
21
|
-
}],
|
|
22
14
|
[ 'OS=="win"', {
|
|
23
15
|
'sources': [ 'src/windows/BluetoothSerialPort.cc', 'src/windows/DeviceINQ.cc', 'src/windows/BTSerialPortBinding.cc', 'src/windows/BluetoothHelpers.cc' ],
|
|
24
16
|
'include_dirs' : [ "<!(node -e \"require('nan')\")", 'src', 'src/windows' ],
|
|
@@ -20,7 +20,7 @@ declare module BluetoothSerialPort {
|
|
|
20
20
|
write(buffer: Buffer, cb: (err?: Error) => void): void;
|
|
21
21
|
close(): void;
|
|
22
22
|
isOpen(): boolean;
|
|
23
|
-
listPairedDevices(): void;
|
|
23
|
+
listPairedDevices(cb: (devices: any) => void): void;
|
|
24
24
|
}
|
|
25
25
|
class BluetoothSerialPortServer {
|
|
26
26
|
constructor();
|
package/package.json
CHANGED
|
@@ -1,60 +1,58 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"Kevin Clarens"
|
|
59
|
-
]
|
|
2
|
+
"name": "bluetooth-serial-port",
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"description": "Bluetooth serial port communication for Node.js",
|
|
5
|
+
"author": "Eelco Cramer <eelco@hailendal.org>",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"bluetooth",
|
|
8
|
+
"serial port",
|
|
9
|
+
"rfcomm",
|
|
10
|
+
"linux",
|
|
11
|
+
"windows"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/eelcocramer/node-bluetooth-serial-port",
|
|
14
|
+
"bugs": "https://github.com/eelcocramer/node-bluetooth-serial-port/issues",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/eelcocramer/node-bluetooth-serial-port"
|
|
18
|
+
},
|
|
19
|
+
"directories": {
|
|
20
|
+
"lib": "./lib"
|
|
21
|
+
},
|
|
22
|
+
"main": "./lib/bluetooth-serial-port.js",
|
|
23
|
+
"types": "./lib/bluetooth-serial-port.d.ts",
|
|
24
|
+
"os": [
|
|
25
|
+
"linux",
|
|
26
|
+
"win32"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"bindings": "1.5.x",
|
|
30
|
+
"nan": "2.16.x",
|
|
31
|
+
"stable": "^0.1.8"
|
|
32
|
+
},
|
|
33
|
+
"optionalDependencies": {
|
|
34
|
+
"@types/node": "^18.0.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">= 16.x",
|
|
38
|
+
"npm": ">= 8.x"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"install": "node-gyp configure build",
|
|
42
|
+
"install-debug": "node-gyp configure build --debug"
|
|
43
|
+
},
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"contributors": [
|
|
46
|
+
"Eric Smekens",
|
|
47
|
+
"Juho Vepsäläinen",
|
|
48
|
+
"Elmar Langholz",
|
|
49
|
+
"Donald Ness",
|
|
50
|
+
"Joost Verdoorn",
|
|
51
|
+
"Max Metral",
|
|
52
|
+
"Thomas Wickham",
|
|
53
|
+
"Adrián Estrada",
|
|
54
|
+
"Juan Gomez",
|
|
55
|
+
"Eric Lundby",
|
|
56
|
+
"Kevin Clarens"
|
|
57
|
+
]
|
|
60
58
|
}
|
|
@@ -79,15 +79,16 @@ void BTSerialPortBinding::EIO_AfterConnect(uv_work_t *req) {
|
|
|
79
79
|
|
|
80
80
|
Nan::TryCatch try_catch;
|
|
81
81
|
|
|
82
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Connect");
|
|
82
83
|
if (baton->status == 0) {
|
|
83
|
-
baton->cb->Call(0, NULL);
|
|
84
|
+
baton->cb->Call(0, NULL, &resource);
|
|
84
85
|
} else {
|
|
85
86
|
char msg[80];
|
|
86
87
|
sprintf(msg, "Cannot connect: %d", baton->status);
|
|
87
88
|
Local<Value> argv[] = {
|
|
88
89
|
Nan::Error(msg)
|
|
89
90
|
};
|
|
90
|
-
baton->ecb->Call(1, argv);
|
|
91
|
+
baton->ecb->Call(1, argv, &resource);
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
if (try_catch.HasCaught()) {
|
|
@@ -140,7 +141,8 @@ void BTSerialPortBinding::EIO_AfterWrite(uv_work_t *req) {
|
|
|
140
141
|
argv[1] = Nan::New<v8::Integer>((int32_t)data->result);
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Write");
|
|
145
|
+
data->callback->Call(2, argv, &resource);
|
|
144
146
|
|
|
145
147
|
uv_mutex_lock(&write_queue_mutex);
|
|
146
148
|
ngx_queue_remove(&queuedWrite->queue);
|
|
@@ -202,17 +204,15 @@ void BTSerialPortBinding::EIO_AfterRead(uv_work_t *req) {
|
|
|
202
204
|
argv[0] = Nan::Error("Error reading from connection");
|
|
203
205
|
argv[1] = Nan::Undefined();
|
|
204
206
|
} else {
|
|
205
|
-
Local<Object>
|
|
206
|
-
Local<Function> bufferConstructor = Local<Function>::Cast(globalObj->Get(Nan::New("Buffer").ToLocalChecked()));
|
|
207
|
-
Local<Value> constructorArgs[1] = { Nan::New<v8::Integer>(baton->size) };
|
|
208
|
-
Local<Object> resultBuffer = Nan::NewInstance(bufferConstructor, 1, constructorArgs).ToLocalChecked();
|
|
207
|
+
Local<Object> resultBuffer = Nan::NewBuffer(baton->size).ToLocalChecked();
|
|
209
208
|
memcpy(Buffer::Data(resultBuffer), baton->result, baton->size);
|
|
210
209
|
|
|
211
210
|
argv[0] = Nan::Undefined();
|
|
212
211
|
argv[1] = resultBuffer;
|
|
213
212
|
}
|
|
214
213
|
|
|
215
|
-
|
|
214
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Read");
|
|
215
|
+
baton->cb->Call(2, argv, &resource);
|
|
216
216
|
|
|
217
217
|
if (try_catch.HasCaught()) {
|
|
218
218
|
Nan::FatalException(try_catch);
|
|
@@ -239,7 +239,7 @@ void BTSerialPortBinding::Init(Local<Object> target) {
|
|
|
239
239
|
Nan::SetPrototypeMethod(t, "write", Write);
|
|
240
240
|
Nan::SetPrototypeMethod(t, "read", Read);
|
|
241
241
|
Nan::SetPrototypeMethod(t, "close", Close);
|
|
242
|
-
|
|
242
|
+
Nan::Set(target, Nan::New("BTSerialPortBinding").ToLocalChecked(), t->GetFunction(ctx).ToLocalChecked());
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
BTSerialPortBinding::BTSerialPortBinding() :
|
|
@@ -388,8 +388,9 @@ NAN_METHOD(BTSerialPortBinding::Read) {
|
|
|
388
388
|
argv[0] = Nan::Error("The connection has been closed");
|
|
389
389
|
argv[1] = Nan::Undefined();
|
|
390
390
|
|
|
391
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Read");
|
|
391
392
|
Nan::Callback *nc = new Nan::Callback(cb);
|
|
392
|
-
nc->Call(2, argv);
|
|
393
|
+
nc->Call(2, argv, &resource);
|
|
393
394
|
} else {
|
|
394
395
|
read_baton_t *baton = new read_baton_t();
|
|
395
396
|
baton->rfcomm = rfcomm;
|
|
@@ -162,7 +162,8 @@ void BTSerialPortBindingServer::EIO_AfterListen(uv_work_t *req) {
|
|
|
162
162
|
Nan::Error(baton->errorString)
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
Nan::AsyncResource resource("bluetooth-serial-port:server.Listen");
|
|
166
|
+
baton->ecb->Call(1, argv, &resource);
|
|
166
167
|
return;
|
|
167
168
|
}
|
|
168
169
|
|
|
@@ -214,7 +215,9 @@ void BTSerialPortBindingServer::EIO_AfterWrite(uv_work_t *req) {
|
|
|
214
215
|
argv[1] = Nan::New<v8::Integer>((int32_t)data->result);
|
|
215
216
|
}
|
|
216
217
|
|
|
217
|
-
|
|
218
|
+
|
|
219
|
+
Nan::AsyncResource resource("bluetooth-serial-port:server.Write");
|
|
220
|
+
data->callback->Call(2, argv, &resource);
|
|
218
221
|
|
|
219
222
|
uv_mutex_lock(&data->rfcomm->mWriteQueueMutex);
|
|
220
223
|
ngx_queue_remove(&queuedWrite->queue);
|
|
@@ -283,6 +286,7 @@ void BTSerialPortBindingServer::EIO_AfterRead(uv_work_t *req) {
|
|
|
283
286
|
|
|
284
287
|
Local<Value> argv[2];
|
|
285
288
|
|
|
289
|
+
Nan::AsyncResource resource("bluetooth-serial-port:server.Read");
|
|
286
290
|
if (baton->size <= 0) {
|
|
287
291
|
char msg[512];
|
|
288
292
|
sprintf(msg, "Error reading from connection: errno: %d", baton->errorno);
|
|
@@ -294,21 +298,18 @@ void BTSerialPortBindingServer::EIO_AfterRead(uv_work_t *req) {
|
|
|
294
298
|
baton->rfcomm->AdvertiseAndAccept();
|
|
295
299
|
}
|
|
296
300
|
argv[0] = Nan::Error(CLIENT_CLOSED_CONNECTION);
|
|
297
|
-
baton->cb->Call(2, argv);
|
|
301
|
+
baton->cb->Call(2, argv, &resource);
|
|
298
302
|
}
|
|
299
303
|
return;
|
|
300
304
|
}
|
|
301
305
|
|
|
302
|
-
Local<Object>
|
|
303
|
-
Local<Function> bufferConstructor = Local<Function>::Cast(globalObj->Get(Nan::New("Buffer").ToLocalChecked()));
|
|
304
|
-
Local<Value> constructorArgs[1] = { Nan::New<v8::Integer>(baton->size) };
|
|
305
|
-
Local<Object> resultBuffer = Nan::NewInstance(bufferConstructor, 1, constructorArgs).ToLocalChecked();
|
|
306
|
+
Local<Object> resultBuffer = Nan::NewBuffer(baton->size).ToLocalChecked();
|
|
306
307
|
memcpy(Buffer::Data(resultBuffer), baton->result, baton->size);
|
|
307
308
|
|
|
308
309
|
argv[0] = Nan::Undefined();
|
|
309
310
|
argv[1] = resultBuffer;
|
|
310
311
|
|
|
311
|
-
baton->cb->Call(2, argv);
|
|
312
|
+
baton->cb->Call(2, argv, &resource);
|
|
312
313
|
|
|
313
314
|
if (try_catch.HasCaught()) {
|
|
314
315
|
Nan::FatalException(try_catch);
|
|
@@ -336,7 +337,7 @@ void BTSerialPortBindingServer::Init(Local<Object> target) {
|
|
|
336
337
|
Nan::SetPrototypeMethod(t, "disconnectClient", DisconnectClient);
|
|
337
338
|
Nan::SetPrototypeMethod(t, "isOpen", IsOpen);
|
|
338
339
|
|
|
339
|
-
|
|
340
|
+
Nan::Set(target, Nan::New("BTSerialPortBindingServer").ToLocalChecked(), t->GetFunction(ctx).ToLocalChecked());
|
|
340
341
|
}
|
|
341
342
|
|
|
342
343
|
BTSerialPortBindingServer::BTSerialPortBindingServer() :
|
|
@@ -389,9 +390,9 @@ NAN_METHOD(BTSerialPortBindingServer::New) {
|
|
|
389
390
|
std::map<std::string, std::string> options;
|
|
390
391
|
|
|
391
392
|
for (int i = 0; i < n ; i++) {
|
|
392
|
-
Local<Value> property =
|
|
393
|
+
Local<Value> property = Nan::Get(properties, Nan::New<Integer>(i)).ToLocalChecked();
|
|
393
394
|
string propertyName = std::string(*String::Utf8Value(isolate, property));
|
|
394
|
-
Local<Value> optionValue =
|
|
395
|
+
Local<Value> optionValue = Nan::Get(jsOptions, property).ToLocalChecked();
|
|
395
396
|
options[propertyName] = std::string(*String::Utf8Value(isolate, optionValue));
|
|
396
397
|
}
|
|
397
398
|
|
|
@@ -606,8 +607,9 @@ NAN_METHOD(BTSerialPortBindingServer::Read) {
|
|
|
606
607
|
argv[0] = Nan::Error(CLIENT_CLOSED_CONNECTION);
|
|
607
608
|
argv[1] = Nan::Undefined();
|
|
608
609
|
|
|
610
|
+
Nan::AsyncResource resource("bluetooth-serial-port:server.Read");
|
|
609
611
|
std::unique_ptr<Nan::Callback> nc(new Nan::Callback(cb));
|
|
610
|
-
nc->Call(2, argv);
|
|
612
|
+
nc->Call(2, argv, &resource);
|
|
611
613
|
return;
|
|
612
614
|
}
|
|
613
615
|
read_baton_t *baton = new read_baton_t();
|
|
@@ -672,7 +674,7 @@ void BTSerialPortBindingServer::ClientWorker::Execute(){
|
|
|
672
674
|
|
|
673
675
|
select_status = select(mBaton->rfcomm->s + 1, &fds, NULL, NULL, &timeout);
|
|
674
676
|
if (select_status > 0) {
|
|
675
|
-
break;
|
|
677
|
+
break;
|
|
676
678
|
}
|
|
677
679
|
else if (select_status == -1) {
|
|
678
680
|
return Nan::ThrowError("error pselect'ing socket!");
|
|
@@ -707,6 +709,8 @@ void BTSerialPortBindingServer::ClientWorker::HandleOKCallback(){
|
|
|
707
709
|
Local<Value> argv[] = {
|
|
708
710
|
Nan::New<v8::String>((mBaton->clientAddress)).ToLocalChecked()
|
|
709
711
|
};
|
|
710
|
-
|
|
712
|
+
|
|
713
|
+
Nan::AsyncResource resource("bluetooth-serial-port:server.HandleOK");
|
|
714
|
+
callback->Call(1, argv, &resource);
|
|
711
715
|
|
|
712
716
|
}
|
package/src/linux/DeviceINQ.cc
CHANGED
|
@@ -136,7 +136,8 @@ void DeviceINQ::EIO_AfterSdpSearch(uv_work_t *req) {
|
|
|
136
136
|
Nan::New(baton->channelID)
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
Nan::AsyncResource resource("bluetooth-serial-port:SdpSearch");
|
|
140
|
+
baton->cb->Call(1, argv, &resource);
|
|
140
141
|
|
|
141
142
|
if (try_catch.HasCaught()) {
|
|
142
143
|
Nan::FatalException(try_catch);
|
|
@@ -239,26 +240,27 @@ NAN_METHOD(DeviceINQ::InquireSync) {
|
|
|
239
240
|
return Nan::ThrowError(usage);
|
|
240
241
|
}
|
|
241
242
|
|
|
243
|
+
Nan::AsyncResource resource("bluetooth-serial-port:InquireSync");
|
|
242
244
|
Nan::Callback *found = new Nan::Callback(info[0].As<Function>());
|
|
243
245
|
Nan::Callback *callback = new Nan::Callback(info[1].As<Function>());
|
|
244
246
|
|
|
245
247
|
bt_inquiry inquiryResult = DeviceINQ::doInquire();
|
|
246
248
|
for (int i = 0; i < inquiryResult.num_rsp; i++) {
|
|
247
249
|
Local<Value> argv[] = {
|
|
248
|
-
Nan::New(inquiryResult.devices[i].address).ToLocalChecked(),
|
|
250
|
+
Nan::New(inquiryResult.devices[i].address).ToLocalChecked(),
|
|
249
251
|
Nan::New(inquiryResult.devices[i].name).ToLocalChecked()
|
|
250
252
|
};
|
|
251
|
-
found->Call(2, argv);
|
|
253
|
+
found->Call(2, argv, &resource);
|
|
252
254
|
}
|
|
253
255
|
|
|
254
256
|
Local<Value> argv[] = {};
|
|
255
|
-
callback->Call(0, argv);
|
|
257
|
+
callback->Call(0, argv, &resource);
|
|
256
258
|
return;
|
|
257
259
|
}
|
|
258
260
|
|
|
259
261
|
class InquireWorker : public Nan::AsyncWorker {
|
|
260
262
|
public:
|
|
261
|
-
InquireWorker(Nan::Callback* found, Nan::Callback *callback)
|
|
263
|
+
InquireWorker(Nan::Callback* found, Nan::Callback *callback)
|
|
262
264
|
: Nan::AsyncWorker(callback), found(found) {}
|
|
263
265
|
~InquireWorker() {}
|
|
264
266
|
|
|
@@ -276,16 +278,17 @@ class InquireWorker : public Nan::AsyncWorker {
|
|
|
276
278
|
void HandleOKCallback () {
|
|
277
279
|
Nan::HandleScope scope;
|
|
278
280
|
|
|
281
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Inquire");
|
|
279
282
|
for (int i = 0; i < inquiryResult.num_rsp; i++) {
|
|
280
283
|
Local<Value> argv[] = {
|
|
281
|
-
Nan::New(inquiryResult.devices[i].address).ToLocalChecked(),
|
|
284
|
+
Nan::New(inquiryResult.devices[i].address).ToLocalChecked(),
|
|
282
285
|
Nan::New(inquiryResult.devices[i].name).ToLocalChecked()
|
|
283
286
|
};
|
|
284
|
-
found->Call(2, argv);
|
|
287
|
+
found->Call(2, argv, &resource);
|
|
285
288
|
}
|
|
286
289
|
|
|
287
290
|
Local<Value> argv[] = {};
|
|
288
|
-
callback->Call(0, argv);
|
|
291
|
+
callback->Call(0, argv, &resource);
|
|
289
292
|
}
|
|
290
293
|
|
|
291
294
|
private:
|
|
@@ -75,15 +75,16 @@ void BTSerialPortBinding::EIO_AfterConnect(uv_work_t *req) {
|
|
|
75
75
|
|
|
76
76
|
Nan::TryCatch try_catch;
|
|
77
77
|
|
|
78
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Connect");
|
|
78
79
|
if (baton->status == 0) {
|
|
79
|
-
baton->cb->Call(0, NULL);
|
|
80
|
+
baton->cb->Call(0, NULL, &resource);
|
|
80
81
|
} else {
|
|
81
82
|
char msg[80];
|
|
82
83
|
sprintf(msg, "Cannot connect: %d", baton->status);
|
|
83
84
|
Local<Value> argv[] = {
|
|
84
85
|
Nan::Error(msg)
|
|
85
86
|
};
|
|
86
|
-
baton->ecb->Call(1, argv);
|
|
87
|
+
baton->ecb->Call(1, argv, &resource);
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
if (try_catch.HasCaught()) {
|
|
@@ -130,7 +131,8 @@ void BTSerialPortBinding::EIO_AfterWrite(uv_work_t *req) {
|
|
|
130
131
|
argv[1] = Nan::New<v8::Integer>((int32_t)data->result);
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
|
|
134
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Write");
|
|
135
|
+
data->callback->Call(2, argv, &resource);
|
|
134
136
|
|
|
135
137
|
uv_mutex_lock(&write_queue_mutex);
|
|
136
138
|
ngx_queue_remove(&queuedWrite->queue);
|
|
@@ -186,17 +188,15 @@ void BTSerialPortBinding::EIO_AfterRead(uv_work_t *req) {
|
|
|
186
188
|
argv[0] = Nan::Error("Error reading from connection");
|
|
187
189
|
argv[1] = Nan::Undefined();
|
|
188
190
|
} else {
|
|
189
|
-
Local<Object>
|
|
190
|
-
Local<Function> bufferConstructor = Local<Function>::Cast(globalObj->Get(Nan::New("Buffer").ToLocalChecked()));
|
|
191
|
-
Local<Value> constructorArgs[1] = { Nan::New<v8::Integer>(baton->size) };
|
|
192
|
-
Local<Object> resultBuffer = Nan::NewInstance(bufferConstructor, 1, constructorArgs).ToLocalChecked();
|
|
191
|
+
Local<Object> resultBuffer = Nan::NewBuffer(baton->size).ToLocalChecked();
|
|
193
192
|
memcpy(Buffer::Data(resultBuffer), baton->result, baton->size);
|
|
194
193
|
|
|
195
194
|
argv[0] = Nan::Undefined();
|
|
196
195
|
argv[1] = resultBuffer;
|
|
197
196
|
}
|
|
198
197
|
|
|
199
|
-
|
|
198
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Read");
|
|
199
|
+
baton->cb->Call(2, argv, &resource);
|
|
200
200
|
|
|
201
201
|
if (try_catch.HasCaught()) {
|
|
202
202
|
Nan::FatalException(try_catch);
|
|
@@ -361,7 +361,8 @@ NAN_METHOD(BTSerialPortBinding::Read) {
|
|
|
361
361
|
argv[1] = Nan::Undefined();
|
|
362
362
|
|
|
363
363
|
Nan::Callback *nc = new Nan::Callback(cb);
|
|
364
|
-
|
|
364
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Read");
|
|
365
|
+
nc->Call(2, argv, &resource);
|
|
365
366
|
} else {
|
|
366
367
|
read_baton_t *baton = new read_baton_t();
|
|
367
368
|
baton->rfcomm = rfcomm;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
8
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.
|
|
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
10
|
*/
|
|
11
11
|
|
|
12
12
|
#ifndef NODE_BTSP_SRC_BLUETOOTH_WORKER_H
|
|
@@ -29,7 +29,7 @@ struct device_info_t {
|
|
|
29
29
|
@interface BluetoothWorker: NSObject {
|
|
30
30
|
@private
|
|
31
31
|
BluetoothDeviceResources *res;
|
|
32
|
-
|
|
32
|
+
dispatch_queue_t worker_queue;
|
|
33
33
|
pipe_producer_t *inquiryProducer;
|
|
34
34
|
NSLock *sdpLock;
|
|
35
35
|
NSLock *connectLock;
|
|
@@ -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
|
|
@@ -102,29 +103,17 @@ 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
113
|
// this function is called synchronous from javascript so it waits on the worker task to complete.
|
|
127
|
-
|
|
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 */
|
|
@@ -167,7 +156,9 @@ static NSLock *globalConnectLock = nil;
|
|
|
167
156
|
address, @"address", [NSNumber numberWithInt: channel], @"channel", pipeObj, @"pipe", nil];
|
|
168
157
|
|
|
169
158
|
// connect to a device and wait for the result
|
|
170
|
-
|
|
159
|
+
dispatch_sync(worker_queue, ^{
|
|
160
|
+
[self connectDeviceTask:parameters];
|
|
161
|
+
});
|
|
171
162
|
IOReturn result = connectResult;
|
|
172
163
|
[connectLock unlock];
|
|
173
164
|
|
|
@@ -218,7 +209,9 @@ static NSLock *globalConnectLock = nil;
|
|
|
218
209
|
writeData.address = address;
|
|
219
210
|
|
|
220
211
|
// wait for the write to be performed on the worker thread
|
|
221
|
-
|
|
212
|
+
dispatch_sync(worker_queue, ^{
|
|
213
|
+
[self writeAsyncTask:writeData];
|
|
214
|
+
});
|
|
222
215
|
|
|
223
216
|
IOReturn result = writeResult;
|
|
224
217
|
[writeLock unlock];
|
|
@@ -268,16 +261,20 @@ static NSLock *globalConnectLock = nil;
|
|
|
268
261
|
{
|
|
269
262
|
@synchronized(self) {
|
|
270
263
|
inquiryProducer = pipe_producer_new(pipe);
|
|
271
|
-
|
|
264
|
+
dispatch_async(worker_queue, ^{
|
|
265
|
+
[self inquiryTask];
|
|
266
|
+
});
|
|
272
267
|
}
|
|
273
268
|
}
|
|
274
269
|
|
|
275
270
|
/** Worker task to the the inquiry */
|
|
276
271
|
- (void) inquiryTask
|
|
277
272
|
{
|
|
278
|
-
IOBluetoothDeviceInquiry *bdi = [
|
|
279
|
-
|
|
280
|
-
|
|
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 */
|
|
@@ -285,7 +282,9 @@ static NSLock *globalConnectLock = nil;
|
|
|
285
282
|
{
|
|
286
283
|
[sdpLock lock];
|
|
287
284
|
// call the task on the worker thread and wait for the result
|
|
288
|
-
|
|
285
|
+
dispatch_sync(worker_queue, ^{
|
|
286
|
+
[self getRFCOMMChannelIDTask:address];
|
|
287
|
+
});
|
|
289
288
|
int returnValue = lastChannelID;
|
|
290
289
|
[sdpLock unlock];
|
|
291
290
|
return returnValue;
|
|
@@ -336,7 +335,7 @@ static NSLock *globalConnectLock = nil;
|
|
|
336
335
|
}
|
|
337
336
|
}
|
|
338
337
|
|
|
339
|
-
// This can happen
|
|
338
|
+
// This can happen in some conditions where the network is unreliable. Just ignore for now...
|
|
340
339
|
lastChannelID = -1;
|
|
341
340
|
}
|
|
342
341
|
|
|
@@ -356,7 +355,7 @@ static NSLock *globalConnectLock = nil;
|
|
|
356
355
|
/** Called when a channel has been closed */
|
|
357
356
|
- (void)rfcommChannelClosed:(IOBluetoothRFCOMMChannel*)rfcommChannel
|
|
358
357
|
{
|
|
359
|
-
[self disconnectFromDevice: [[rfcommChannel getDevice]
|
|
358
|
+
[self disconnectFromDevice: [[rfcommChannel getDevice] addressString]];
|
|
360
359
|
}
|
|
361
360
|
|
|
362
361
|
/** Called when the device inquiry completes */
|
|
@@ -377,8 +376,8 @@ static NSLock *globalConnectLock = nil;
|
|
|
377
376
|
@synchronized(self) {
|
|
378
377
|
if (inquiryProducer != NULL) {
|
|
379
378
|
device_info_t *info = new device_info_t;
|
|
380
|
-
strcpy(info->address, [[device
|
|
381
|
-
strcpy(info->name, [[device
|
|
379
|
+
strcpy(info->address, [[device addressString] UTF8String]);
|
|
380
|
+
strcpy(info->name, [[device addressString] UTF8String]);
|
|
382
381
|
|
|
383
382
|
// push the device data into the pipe to notify the main thread
|
|
384
383
|
pipe_push(inquiryProducer, info, 1);
|
|
@@ -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
|
|
109
|
+
Nan::Call(*baton->cb, 1, argv);
|
|
110
110
|
|
|
111
111
|
if (try_catch.HasCaught()) {
|
|
112
112
|
Nan::FatalException(try_catch);
|
|
@@ -215,6 +215,7 @@ NAN_METHOD(DeviceINQ::InquireSync) {
|
|
|
215
215
|
NSValue *boxedDevice;
|
|
216
216
|
NSArray *inquiryResult = doInquire();
|
|
217
217
|
NSEnumerator *enumerator = [inquiryResult objectEnumerator];
|
|
218
|
+
Nan::AsyncResource resource("bluetooth-serial-port:inqureSync");
|
|
218
219
|
while (boxedDevice = [enumerator nextObject]) {
|
|
219
220
|
struct bt_device device;
|
|
220
221
|
|
|
@@ -224,10 +225,10 @@ NAN_METHOD(DeviceINQ::InquireSync) {
|
|
|
224
225
|
Nan::New(device.name).ToLocalChecked()
|
|
225
226
|
};
|
|
226
227
|
|
|
227
|
-
found->Call(2, argv);
|
|
228
|
+
found->Call(2, argv, &resource);
|
|
228
229
|
}
|
|
229
230
|
|
|
230
|
-
callback->Call(0, 0);
|
|
231
|
+
callback->Call(0, 0, &resource);
|
|
231
232
|
[inquiryResult release];
|
|
232
233
|
|
|
233
234
|
return;
|
|
@@ -293,8 +294,8 @@ NAN_METHOD(DeviceINQ::ListPairedDevices) {
|
|
|
293
294
|
|
|
294
295
|
Local<Object> deviceObj = Nan::New<v8::Object>();
|
|
295
296
|
|
|
296
|
-
|
|
297
|
-
|
|
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());
|
|
298
299
|
|
|
299
300
|
// A device may have multiple services, so enumerate each one
|
|
300
301
|
Local<Array> servicesArray = Nan::New<v8::Array>((int)device.services.count);
|
|
@@ -304,18 +305,18 @@ NAN_METHOD(DeviceINQ::ListPairedDevices) {
|
|
|
304
305
|
[service getRFCOMMChannelID:&channelID];
|
|
305
306
|
|
|
306
307
|
Local<Object> serviceObj = Nan::New<v8::Object>();
|
|
307
|
-
|
|
308
|
+
Nan::Set(serviceObj, Nan::New("channel").ToLocalChecked(), Nan::New((int)channelID));
|
|
308
309
|
|
|
309
310
|
if ([service getServiceName])
|
|
310
|
-
|
|
311
|
+
Nan::Set(serviceObj, Nan::New("name").ToLocalChecked(), Nan::New([[service getServiceName] UTF8String]).ToLocalChecked());
|
|
311
312
|
else
|
|
312
|
-
|
|
313
|
+
Nan::Set(serviceObj, Nan::New("name").ToLocalChecked(), Nan::Undefined());
|
|
313
314
|
|
|
314
|
-
|
|
315
|
+
Nan::Set(servicesArray, j, serviceObj);
|
|
315
316
|
}
|
|
316
|
-
|
|
317
|
+
Nan::Set(deviceObj, Nan::New("services").ToLocalChecked(), servicesArray);
|
|
317
318
|
|
|
318
|
-
|
|
319
|
+
Nan::Set(resultArray, i, deviceObj);
|
|
319
320
|
}
|
|
320
321
|
|
|
321
322
|
Local<Value> argv[1] = {
|
package/src/{osx → macos}/pipe.c
RENAMED
|
File without changes
|
package/src/{osx → macos}/pipe.h
RENAMED
|
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
|
-
|
|
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>
|
|
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
|
-
|
|
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);
|
|
@@ -354,8 +351,9 @@ NAN_METHOD(BTSerialPortBinding::Read) {
|
|
|
354
351
|
argv[0] = Nan::Error("The connection has been closed");
|
|
355
352
|
argv[1] = Nan::Undefined();
|
|
356
353
|
|
|
354
|
+
Nan::AsyncResource resource("bluetooth-serial-port:Read");
|
|
357
355
|
Nan::Callback *nc = new Nan::Callback(cb);
|
|
358
|
-
nc->Call(2, argv);
|
|
356
|
+
nc->Call(2, argv, &resource);
|
|
359
357
|
} else {
|
|
360
358
|
read_baton_t *baton = new read_baton_t();
|
|
361
359
|
baton->rfcomm = rfcomm;
|
package/src/windows/DeviceINQ.cc
CHANGED
|
@@ -415,8 +415,8 @@ NAN_METHOD(DeviceINQ::ListPairedDevices) {
|
|
|
415
415
|
: Nan::New(address);
|
|
416
416
|
|
|
417
417
|
Local<Object> deviceObj = Nan::New<v8::Object>();
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
Nan::Set(deviceObj, Nan::New("name").ToLocalChecked(), Nan::New(querySet->lpszServiceInstanceName).ToLocalChecked());
|
|
419
|
+
Nan::Set(deviceObj, Nan::New("address").ToLocalChecked(), addressString.ToLocalChecked());
|
|
420
420
|
|
|
421
421
|
Local<Array> servicesArray = Local<Array>(Nan::New<Array>());
|
|
422
422
|
{
|
|
@@ -445,9 +445,9 @@ NAN_METHOD(DeviceINQ::ListPairedDevices) {
|
|
|
445
445
|
if (lookupServiceError2 != SOCKET_ERROR ) {
|
|
446
446
|
int port = (int)((SOCKADDR_BTH *)querySet2->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
|
|
447
447
|
Local<Object> serviceObj = Nan::New<v8::Object>();
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
448
|
+
Nan::Set(serviceObj, Nan::New("channel").ToLocalChecked(), Nan::New(port));
|
|
449
|
+
Nan::Set(serviceObj, Nan::New("name").ToLocalChecked(), Nan::New(querySet2->lpszServiceInstanceName).ToLocalChecked());
|
|
450
|
+
Nan::Set(servicesArray, place++, serviceObj);
|
|
451
451
|
} else {
|
|
452
452
|
int lookupServiceErrorNumber = WSAGetLastError();
|
|
453
453
|
if (lookupServiceErrorNumber == WSAEFAULT) {
|
|
@@ -476,8 +476,8 @@ NAN_METHOD(DeviceINQ::ListPairedDevices) {
|
|
|
476
476
|
free(querySet2);
|
|
477
477
|
}
|
|
478
478
|
|
|
479
|
-
|
|
480
|
-
|
|
479
|
+
Nan::Set(deviceObj, Nan::New("services").ToLocalChecked(), servicesArray);
|
|
480
|
+
Nan::Set(resultArray, i, deviceObj);
|
|
481
481
|
i = i+1;
|
|
482
482
|
}
|
|
483
483
|
} else {
|
package/.travis.yml
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
language: cpp # node_js is not supported yet on osx
|
|
2
|
-
compiler: gcc
|
|
3
|
-
sudo: false
|
|
4
|
-
|
|
5
|
-
os:
|
|
6
|
-
- linux
|
|
7
|
-
- osx
|
|
8
|
-
|
|
9
|
-
env:
|
|
10
|
-
matrix:
|
|
11
|
-
- export NODE_VERSION="8"
|
|
12
|
-
- export NODE_VERSION="9"
|
|
13
|
-
- export NODE_VERSION="10"
|
|
14
|
-
- export NODE_VERSION="11"
|
|
15
|
-
- export NODE_VERSION="12"
|
|
16
|
-
|
|
17
|
-
matrix:
|
|
18
|
-
fast-finish: true
|
|
19
|
-
|
|
20
|
-
addons:
|
|
21
|
-
apt:
|
|
22
|
-
sources:
|
|
23
|
-
- ubuntu-toolchain-r-test
|
|
24
|
-
packages:
|
|
25
|
-
- libbluetooth-dev
|
|
26
|
-
|
|
27
|
-
before_install:
|
|
28
|
-
- git clone https://github.com/creationix/nvm.git ./.nvm
|
|
29
|
-
- source ./.nvm/nvm.sh
|
|
30
|
-
- nvm install $NODE_VERSION
|
|
31
|
-
- nvm use $NODE_VERSION
|
|
32
|
-
- npm config set python `which python`
|
|
33
|
-
- gcc --version
|
|
34
|
-
- g++ --version
|
|
35
|
-
- npm --version
|
|
36
|
-
- node --version
|
|
37
|
-
|
|
38
|
-
script:
|
|
39
|
-
- npm install
|
|
40
|
-
- node ./test/index.js
|
|
41
|
-
|
|
42
|
-
cache:
|
|
43
|
-
directories:
|
|
44
|
-
- $HOME/.node-gyp
|
|
45
|
-
- $HOME/.npm
|
|
46
|
-
- node_modules
|
|
47
|
-
|