@stoprocent/bleno 0.8.6 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -30
- package/examples/echo/async.js +47 -0
- package/examples/echo/characteristic.js +15 -17
- package/examples/echo/main.js +19 -1
- package/examples/uart/main.js +3 -2
- package/examples/with-bindings/main.js +35 -0
- package/index.d.ts +166 -121
- package/index.js +5 -1
- package/lib/bleno.js +108 -17
- package/lib/characteristic.js +27 -10
- package/lib/hci-socket/acl-stream.js +3 -3
- package/lib/hci-socket/bindings.js +36 -29
- package/lib/hci-socket/gatt.js +177 -105
- package/lib/hci-socket/hci.js +5 -3
- package/lib/hci-socket/mgmt.js +1 -1
- package/lib/hci-socket/smp.js +5 -4
- package/lib/mac/src/ble_peripheral_manager.h +3 -7
- package/lib/mac/src/ble_peripheral_manager.mm +101 -171
- package/lib/mac/src/bleno_mac.h +0 -1
- package/lib/mac/src/bleno_mac.mm +21 -33
- package/lib/mac/src/callbacks.h +12 -48
- package/lib/mac/src/callbacks.mm +34 -45
- package/lib/mac/src/napi_objc.mm +9 -30
- package/lib/mac/src/objc_cpp.h +2 -2
- package/lib/mac/src/objc_cpp.mm +3 -37
- package/lib/resolve-bindings.js +27 -6
- package/package.json +7 -9
- package/prebuilds/darwin-x64+arm64/@stoprocent+bleno.node +0 -0
- package/prebuilds/win32-ia32/@stoprocent+bleno.node +0 -0
- package/prebuilds/win32-x64/@stoprocent+bleno.node +0 -0
- package/test/characteristic.test.js +158 -11
- package/examples/battery-service/README.md +0 -14
- package/examples/blink1/README.md +0 -44
- package/examples/pizza/README.md +0 -16
- package/lib/mac/src/noble_mac.h +0 -34
- package/lib/mac/src/noble_mac.mm +0 -267
- package/lib/mac/src/peripheral.h +0 -23
- package/with-bindings.js +0 -5
- package/with-custom-binding.js +0 -6
package/index.d.ts
CHANGED
|
@@ -1,155 +1,200 @@
|
|
|
1
|
-
// Type definitions for bleno 0.4
|
|
2
|
-
// Project: https://github.com/sandeepmistry/bleno
|
|
3
|
-
// Definitions by: Manuel Francisco Naranjo <naranjo.manuel@gmail.com>
|
|
4
|
-
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
|
5
|
-
|
|
6
1
|
/// <reference types="node" />
|
|
7
|
-
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
interface CharacteristicOptions {
|
|
13
|
-
uuid: string;
|
|
14
|
-
properties?: ReadonlyArray<Property> | null;
|
|
15
|
-
secure?: ReadonlyArray<Property> | null;
|
|
16
|
-
value?: Buffer | null;
|
|
17
|
-
descriptors?: ReadonlyArray<Descriptor> | null;
|
|
18
|
-
onIndicate?: (() => void) | null;
|
|
19
|
-
onNotify?: (() => void) | null;
|
|
20
|
-
onReadRequest?: ((
|
|
21
|
-
offset: number,
|
|
22
|
-
callback: (result: number, data?: Buffer) => void
|
|
23
|
-
) => void) | null;
|
|
24
|
-
onSubscribe?: ((maxValueSize: number, updateValueCallback: (data: Buffer) => void) => void) | null;
|
|
25
|
-
onUnsubscribe?: (() => void) | null;
|
|
26
|
-
onWriteRequest?: ((
|
|
27
|
-
data: Buffer,
|
|
28
|
-
offset: number,
|
|
29
|
-
withoutResponse: boolean,
|
|
30
|
-
callback: (result: number) => void
|
|
31
|
-
) => void) | null;
|
|
2
|
+
declare module '@stoprocent/bluetooth-hci-socket' {
|
|
3
|
+
type DriverType = any; // Fallback type
|
|
4
|
+
interface BindParams {
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}
|
|
32
7
|
}
|
|
33
8
|
|
|
34
|
-
declare
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
onIndicate(): void;
|
|
44
|
-
|
|
45
|
-
onNotify(): void;
|
|
46
|
-
|
|
47
|
-
onReadRequest(offset: number, callback: (result: number, data?: Buffer) => void): void;
|
|
48
|
-
|
|
49
|
-
onSubscribe(maxValueSize: number, updateValueCallback: (data: Buffer) => void): void;
|
|
50
|
-
|
|
51
|
-
onUnsubscribe(): void;
|
|
52
|
-
|
|
53
|
-
onWriteRequest(data: Buffer, offset: number, withoutResponse: boolean, callback: (result: number) => void): void;
|
|
54
|
-
|
|
55
|
-
toString(): string;
|
|
9
|
+
declare module '@stoprocent/bleno' {
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
|
|
12
|
+
export type State = 'poweredOn' | 'poweredOff' | 'unauthorized' | 'unsupported' | 'unknown' | 'resetting';
|
|
13
|
+
|
|
14
|
+
export type Property = 'read' | 'write' | 'indicate' | 'notify' | 'writeWithoutResponse';
|
|
15
|
+
|
|
16
|
+
export type ConnectionHandle = number | string;
|
|
56
17
|
|
|
57
|
-
|
|
18
|
+
// Common callback types
|
|
19
|
+
export type ReadRequestCallback = (result: number, data?: Buffer) => void;
|
|
20
|
+
export type UpdateValueCallback = (data?: Buffer) => void;
|
|
21
|
+
export type WriteRequestCallback = (result: number) => void;
|
|
58
22
|
|
|
59
|
-
|
|
23
|
+
// Common function types
|
|
24
|
+
export type OnReadRequestFn = (handle: ConnectionHandle, offset: number, callback: ReadRequestCallback) => void;
|
|
25
|
+
export type OnSubscribeFn = (handle: ConnectionHandle, maxValueSize: number, updateValueCallback: UpdateValueCallback) => void;
|
|
26
|
+
export type OnUnsubscribeFn = (handle: ConnectionHandle) => void;
|
|
27
|
+
export type OnWriteRequestFn = (handle: ConnectionHandle, data: Buffer, offset: number, withoutResponse: boolean, callback: WriteRequestCallback) => void;
|
|
28
|
+
export type OnIndicateFn = (handle: ConnectionHandle) => void;
|
|
29
|
+
export type OnNotifyFn = (handle: ConnectionHandle) => void;
|
|
60
30
|
|
|
61
|
-
|
|
31
|
+
export interface CharacteristicOptions {
|
|
32
|
+
uuid: string;
|
|
33
|
+
properties?: ReadonlyArray<Property> | null;
|
|
34
|
+
secure?: ReadonlyArray<Property> | null;
|
|
35
|
+
value?: Buffer | null;
|
|
36
|
+
descriptors?: ReadonlyArray<Descriptor> | null;
|
|
37
|
+
onIndicate?: OnIndicateFn | null;
|
|
38
|
+
onNotify?: OnNotifyFn | null;
|
|
39
|
+
onReadRequest?: OnReadRequestFn | null;
|
|
40
|
+
onSubscribe?: OnSubscribeFn | null;
|
|
41
|
+
onUnsubscribe?: OnUnsubscribeFn | null;
|
|
42
|
+
onWriteRequest?: OnWriteRequestFn | null;
|
|
43
|
+
}
|
|
62
44
|
|
|
63
|
-
|
|
45
|
+
export class Characteristic {
|
|
46
|
+
uuid: string;
|
|
47
|
+
properties: ReadonlyArray<Property>;
|
|
48
|
+
secure: ReadonlyArray<Property>;
|
|
49
|
+
value: Buffer | null;
|
|
50
|
+
descriptors: ReadonlyArray<Descriptor>;
|
|
64
51
|
|
|
65
|
-
|
|
52
|
+
constructor(options: CharacteristicOptions);
|
|
66
53
|
|
|
67
|
-
|
|
54
|
+
onIndicate: OnIndicateFn;
|
|
55
|
+
onNotify: OnNotifyFn;
|
|
56
|
+
onReadRequest: OnReadRequestFn;
|
|
57
|
+
onSubscribe: OnSubscribeFn;
|
|
58
|
+
onUnsubscribe: OnUnsubscribeFn;
|
|
59
|
+
onWriteRequest: OnWriteRequestFn;
|
|
68
60
|
|
|
69
|
-
|
|
61
|
+
toString(): string;
|
|
70
62
|
|
|
71
|
-
|
|
63
|
+
readonly RESULT_ATTR_NOT_LONG: number;
|
|
64
|
+
readonly RESULT_INVALID_ATTRIBUTE_LENGTH: number;
|
|
65
|
+
readonly RESULT_INVALID_OFFSET: number;
|
|
66
|
+
readonly RESULT_SUCCESS: number;
|
|
67
|
+
readonly RESULT_UNLIKELY_ERROR: number;
|
|
68
|
+
|
|
69
|
+
static readonly RESULT_ATTR_NOT_LONG: number;
|
|
70
|
+
static readonly RESULT_INVALID_ATTRIBUTE_LENGTH: number;
|
|
71
|
+
static readonly RESULT_INVALID_OFFSET: number;
|
|
72
|
+
static readonly RESULT_SUCCESS: number;
|
|
73
|
+
static readonly RESULT_UNLIKELY_ERROR: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface DescriptorOptions {
|
|
77
|
+
uuid: string;
|
|
78
|
+
value?: Buffer | string | null;
|
|
79
|
+
}
|
|
72
80
|
|
|
73
|
-
|
|
81
|
+
export class Descriptor {
|
|
82
|
+
uuid: string;
|
|
83
|
+
value: Buffer;
|
|
84
|
+
|
|
85
|
+
constructor(options: DescriptorOptions);
|
|
74
86
|
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
interface DescriptorOptions {
|
|
79
|
-
uuid: string;
|
|
80
|
-
value?: Buffer | string | null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
declare class Descriptor {
|
|
84
|
-
uuid: string;
|
|
85
|
-
value: Buffer;
|
|
86
|
-
|
|
87
|
-
constructor(options: DescriptorOptions);
|
|
87
|
+
toString(): string;
|
|
88
|
+
}
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
export interface PrimaryServiceOptions {
|
|
91
|
+
uuid: string;
|
|
92
|
+
characteristics?: ReadonlyArray<Characteristic> | null;
|
|
93
|
+
}
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
95
|
+
export class PrimaryService {
|
|
96
|
+
uuid: string;
|
|
97
|
+
characteristics: ReadonlyArray<Characteristic>;
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
uuid: string;
|
|
99
|
-
characteristics: ReadonlyArray<Characteristic>;
|
|
99
|
+
constructor(options: PrimaryServiceOptions);
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
toString(): string;
|
|
102
|
+
}
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
export class Bleno extends EventEmitter {
|
|
105
|
+
readonly Characteristic: typeof Characteristic;
|
|
106
|
+
readonly Descriptor: typeof Descriptor;
|
|
107
|
+
readonly PrimaryService: typeof PrimaryService;
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
readonly Characteristic: typeof Characteristic;
|
|
108
|
-
readonly Descriptor: typeof Descriptor;
|
|
109
|
-
readonly PrimaryService: typeof PrimaryService;
|
|
109
|
+
readonly address: string;
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
readonly mtu: number;
|
|
112
|
+
|
|
113
|
+
readonly platform: string;
|
|
114
|
+
|
|
115
|
+
readonly rssi: number;
|
|
116
|
+
|
|
117
|
+
readonly state: State;
|
|
118
|
+
|
|
119
|
+
disconnect(): void;
|
|
120
|
+
|
|
121
|
+
stop(): void;
|
|
122
|
+
|
|
123
|
+
setAddress(address: string): void;
|
|
124
|
+
|
|
125
|
+
setServices(services: ReadonlyArray<PrimaryService>, callback?: (arg: Error | undefined | null) => void): void;
|
|
126
|
+
|
|
127
|
+
startAdvertising(name: string, serviceUuids?: ReadonlyArray<string>, callback?: (arg: Error | undefined | null) => void): void;
|
|
128
|
+
|
|
129
|
+
startAdvertisingIBeacon(uuid: string, major: number, minor: number, measuredPower: number, callback?: (arg: Error | undefined | null) => void): void;
|
|
112
130
|
|
|
113
|
-
|
|
131
|
+
startAdvertisingWithEIRData(advertisementData: Buffer, callback?: (arg: Error | undefined | null) => void): void;
|
|
132
|
+
startAdvertisingWithEIRData(advertisementData: Buffer, scanData: Buffer, callback?: (arg: Error | undefined | null) => void): void;
|
|
133
|
+
|
|
134
|
+
stopAdvertising(callback?: () => void): void;
|
|
114
135
|
|
|
115
|
-
|
|
136
|
+
updateRssi(callback?: (err: null, rssi: number) => void): void;
|
|
116
137
|
|
|
117
|
-
|
|
138
|
+
// Async methods
|
|
139
|
+
waitForPoweredOnAsync(timeout?: number): Promise<void>;
|
|
118
140
|
|
|
119
|
-
|
|
141
|
+
setAddressAsync(address: string): Promise<void>;
|
|
142
|
+
|
|
143
|
+
setServicesAsync(services: ReadonlyArray<PrimaryService>): Promise<void>;
|
|
144
|
+
|
|
145
|
+
startAdvertisingAsync(name: string, serviceUuids?: ReadonlyArray<string>): Promise<void>;
|
|
146
|
+
|
|
147
|
+
startAdvertisingIBeaconAsync(
|
|
148
|
+
uuid: string,
|
|
149
|
+
major: number,
|
|
150
|
+
minor: number,
|
|
151
|
+
measuredPower: number
|
|
152
|
+
): Promise<void>;
|
|
153
|
+
|
|
154
|
+
startAdvertisingWithEIRDataAsync(advertisementData: Buffer): Promise<void>;
|
|
155
|
+
startAdvertisingWithEIRDataAsync(advertisementData: Buffer, scanData: Buffer): Promise<void>;
|
|
156
|
+
|
|
157
|
+
stopAdvertisingAsync(): Promise<void>;
|
|
158
|
+
|
|
159
|
+
updateRssiAsync(): Promise<number>;
|
|
120
160
|
|
|
121
|
-
|
|
161
|
+
on(event: 'stateChange', cb: (state: State) => void): this;
|
|
162
|
+
on(event: 'platform', cb: (platform: NodeJS.Platform) => void): this;
|
|
163
|
+
on(event: 'addressChange', cb: (address: string) => void): this;
|
|
164
|
+
on(event: 'accept', cb: (address: string, handle: ConnectionHandle) => void): this;
|
|
165
|
+
on(event: 'mtuChange', cb: (mtu: number) => void): this;
|
|
166
|
+
on(event: 'disconnect', cb: (address: string, handle: ConnectionHandle) => void): this;
|
|
167
|
+
on(event: 'advertisingStart', cb: (err?: Error | null) => void): this;
|
|
168
|
+
on(event: 'advertisingStartError', cb: (err: Error) => void): this;
|
|
169
|
+
on(event: 'advertisingStop', cb: () => void): this;
|
|
170
|
+
on(event: 'servicesSet', cb: (err?: Error | null) => void): this;
|
|
171
|
+
on(event: 'servicesSetError', cb: (err: Error) => void): this;
|
|
172
|
+
on(event: 'rssiUpdate', cb: (rssi: number) => void): this;
|
|
173
|
+
}
|
|
122
174
|
|
|
123
|
-
|
|
175
|
+
export type BindingType = 'default' | 'hci' | 'mac';
|
|
124
176
|
|
|
125
|
-
|
|
177
|
+
export interface BaseBindingsOptions {
|
|
126
178
|
|
|
127
|
-
|
|
179
|
+
}
|
|
128
180
|
|
|
129
|
-
|
|
181
|
+
export interface HciBindingsOptions extends BaseBindingsOptions {
|
|
182
|
+
hciDriver?: import('@stoprocent/bluetooth-hci-socket').DriverType;
|
|
183
|
+
bindParams?: import('@stoprocent/bluetooth-hci-socket').BindParams;
|
|
184
|
+
}
|
|
130
185
|
|
|
131
|
-
|
|
186
|
+
export interface MacBindingsOptions extends BaseBindingsOptions {
|
|
132
187
|
|
|
133
|
-
|
|
134
|
-
startAdvertisingWithEIRData(advertisementData: Buffer, scanData: Buffer, callback?: (arg: Error | undefined | null) => void): void;
|
|
188
|
+
}
|
|
135
189
|
|
|
136
|
-
|
|
190
|
+
export type WithBindingsOptions = HciBindingsOptions | MacBindingsOptions;
|
|
137
191
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
on(event: 'addressChange', cb: (address: string) => void): this;
|
|
143
|
-
on(event: 'accept', cb: (address: string) => void): this;
|
|
144
|
-
on(event: 'mtuChange', cb: (mtu: number) => void): this;
|
|
145
|
-
on(event: 'disconnect', cb: (clientAddress: string) => void): this;
|
|
146
|
-
on(event: 'advertisingStart', cb: (err?: Error | null) => void): this;
|
|
147
|
-
on(event: 'advertisingStartError', cb: (err: Error) => void): this;
|
|
148
|
-
on(event: 'advertisingStop', cb: () => void): this;
|
|
149
|
-
on(event: 'servicesSet', cb: (err?: Error | null) => void): this;
|
|
150
|
-
on(event: 'servicesSetError', cb: (err: Error) => void): this;
|
|
151
|
-
on(event: 'rssiUpdate', cb: (rssi: number) => void): this;
|
|
152
|
-
}
|
|
192
|
+
export function withBindings(
|
|
193
|
+
bindingType?: BindingType,
|
|
194
|
+
options?: WithBindingsOptions
|
|
195
|
+
): Bleno;
|
|
153
196
|
|
|
154
|
-
|
|
155
|
-
|
|
197
|
+
// Define a default export
|
|
198
|
+
const BlenoDefault: Bleno;
|
|
199
|
+
export default BlenoDefault;
|
|
200
|
+
}
|
package/index.js
CHANGED
package/lib/bleno.js
CHANGED
|
@@ -59,22 +59,43 @@ class Bleno extends EventEmitter {
|
|
|
59
59
|
this.address = address;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
onAccept (clientAddress) {
|
|
63
|
-
debug('accept ' + clientAddress);
|
|
64
|
-
this.emit('accept', clientAddress);
|
|
62
|
+
onAccept (clientAddress, handle) {
|
|
63
|
+
debug('accept ' + clientAddress + ' ' + handle);
|
|
64
|
+
this.emit('accept', clientAddress, handle);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
onMtuChange (mtu) {
|
|
68
68
|
debug('mtu ' + mtu);
|
|
69
|
-
|
|
70
69
|
this.mtu = mtu;
|
|
71
|
-
|
|
72
70
|
this.emit('mtuChange', mtu);
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
onDisconnect (clientAddress) {
|
|
76
|
-
debug('disconnect ' + clientAddress);
|
|
77
|
-
this.emit('disconnect', clientAddress);
|
|
73
|
+
onDisconnect (clientAddress, handle) {
|
|
74
|
+
debug('disconnect ' + clientAddress + ' ' + handle);
|
|
75
|
+
this.emit('disconnect', clientAddress, handle);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async waitForPoweredOnAsync (timeout = 10000) {
|
|
79
|
+
if (this.state === 'poweredOn') {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
const timeoutId = setTimeout(() => {
|
|
85
|
+
this.removeListener('stateChange', stateChangeHandler);
|
|
86
|
+
reject(new Error(`Timeout waiting for poweredOn state. Current state: ${this.state}`));
|
|
87
|
+
}, timeout);
|
|
88
|
+
|
|
89
|
+
const stateChangeHandler = (state) => {
|
|
90
|
+
if (state === 'poweredOn') {
|
|
91
|
+
clearTimeout(timeoutId);
|
|
92
|
+
this.removeListener('stateChange', stateChangeHandler);
|
|
93
|
+
resolve();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
this.on('stateChange', stateChangeHandler);
|
|
98
|
+
});
|
|
78
99
|
}
|
|
79
100
|
|
|
80
101
|
setAddress (address) {
|
|
@@ -85,6 +106,27 @@ class Bleno extends EventEmitter {
|
|
|
85
106
|
}
|
|
86
107
|
}
|
|
87
108
|
|
|
109
|
+
setAddressAsync (address) {
|
|
110
|
+
if (this._bindings.setAddress === undefined) {
|
|
111
|
+
return Promise.resolve();
|
|
112
|
+
}
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
const timeout = setTimeout(() => {
|
|
115
|
+
reject(new Error('Timeout waiting for address change'));
|
|
116
|
+
}, 2000);
|
|
117
|
+
this._bindings.once('addressChange', (address) => {
|
|
118
|
+
if (address === address) {
|
|
119
|
+
clearTimeout(timeout);
|
|
120
|
+
resolve();
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
reject(new Error('Address change failed'));
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
this.setAddress(address);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
88
130
|
startAdvertising (name, serviceUuids, callback) {
|
|
89
131
|
if (this.state !== 'poweredOn') {
|
|
90
132
|
const error = new Error('Could not start advertising, state is ' + this.state + ' (not poweredOn)');
|
|
@@ -111,6 +153,15 @@ class Bleno extends EventEmitter {
|
|
|
111
153
|
}
|
|
112
154
|
}
|
|
113
155
|
|
|
156
|
+
startAdvertisingAsync (name, serviceUuids) {
|
|
157
|
+
return new Promise((resolve, reject) => {
|
|
158
|
+
this.startAdvertising(name, serviceUuids, (error) => {
|
|
159
|
+
if (error) reject(error);
|
|
160
|
+
else resolve();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
114
165
|
startAdvertisingIBeacon (uuid, major, minor, measuredPower, callback) {
|
|
115
166
|
if (this.state !== 'poweredOn') {
|
|
116
167
|
const error = new Error('Could not start advertising, state is ' + this.state + ' (not poweredOn)');
|
|
@@ -144,14 +195,18 @@ class Bleno extends EventEmitter {
|
|
|
144
195
|
}
|
|
145
196
|
}
|
|
146
197
|
|
|
198
|
+
startAdvertisingIBeaconAsync (uuid, major, minor, measuredPower) {
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
this.startAdvertisingIBeacon(uuid, major, minor, measuredPower, (error) => {
|
|
201
|
+
if (error) reject(error);
|
|
202
|
+
else resolve();
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
147
207
|
onAdvertisingStart (error) {
|
|
148
208
|
debug('advertisingStart: ' + error);
|
|
149
|
-
|
|
150
|
-
if (error) {
|
|
151
|
-
this.emit('advertisingStartError', error);
|
|
152
|
-
} else {
|
|
153
|
-
this.emit('advertisingStart', error);
|
|
154
|
-
}
|
|
209
|
+
this.emit('advertisingStart', error);
|
|
155
210
|
}
|
|
156
211
|
|
|
157
212
|
startAdvertisingWithEIRData (advertisementData, scanData, callback) {
|
|
@@ -177,6 +232,15 @@ class Bleno extends EventEmitter {
|
|
|
177
232
|
}
|
|
178
233
|
}
|
|
179
234
|
|
|
235
|
+
startAdvertisingWithEIRDataAsync (advertisementData, scanData) {
|
|
236
|
+
return new Promise((resolve, reject) => {
|
|
237
|
+
this.startAdvertisingWithEIRData(advertisementData, scanData, (error) => {
|
|
238
|
+
if (error) reject(error);
|
|
239
|
+
else resolve();
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
180
244
|
stopAdvertising (callback) {
|
|
181
245
|
if (typeof callback === 'function') {
|
|
182
246
|
this.once('advertisingStop', callback);
|
|
@@ -184,6 +248,15 @@ class Bleno extends EventEmitter {
|
|
|
184
248
|
this._bindings.stopAdvertising();
|
|
185
249
|
}
|
|
186
250
|
|
|
251
|
+
stopAdvertisingAsync () {
|
|
252
|
+
return new Promise((resolve, reject) => {
|
|
253
|
+
this.stopAdvertising((error) => {
|
|
254
|
+
if (error) reject(error);
|
|
255
|
+
else resolve();
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
187
260
|
onAdvertisingStop () {
|
|
188
261
|
debug('advertisingStop');
|
|
189
262
|
this.emit('advertisingStop');
|
|
@@ -196,6 +269,15 @@ class Bleno extends EventEmitter {
|
|
|
196
269
|
this._bindings.setServices(services);
|
|
197
270
|
}
|
|
198
271
|
|
|
272
|
+
setServicesAsync (services) {
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
274
|
+
this.setServices(services, (error) => {
|
|
275
|
+
if (error) reject(error);
|
|
276
|
+
else resolve();
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
199
281
|
onServicesSet (error) {
|
|
200
282
|
debug('servicesSet');
|
|
201
283
|
|
|
@@ -206,9 +288,9 @@ class Bleno extends EventEmitter {
|
|
|
206
288
|
}
|
|
207
289
|
}
|
|
208
290
|
|
|
209
|
-
disconnect () {
|
|
210
|
-
debug('disconnect');
|
|
211
|
-
this._bindings.disconnect();
|
|
291
|
+
disconnect (handle = null) {
|
|
292
|
+
debug('disconnect ' + (handle ? handle : 'all'));
|
|
293
|
+
this._bindings.disconnect(handle);
|
|
212
294
|
}
|
|
213
295
|
|
|
214
296
|
stop () {
|
|
@@ -224,6 +306,15 @@ class Bleno extends EventEmitter {
|
|
|
224
306
|
this._bindings.updateRssi();
|
|
225
307
|
}
|
|
226
308
|
|
|
309
|
+
updateRssiAsync () {
|
|
310
|
+
return new Promise((resolve, reject) => {
|
|
311
|
+
this.updateRssi((error) => {
|
|
312
|
+
if (error) reject(error);
|
|
313
|
+
else resolve();
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
227
318
|
onRssiUpdate (rssi) {
|
|
228
319
|
this.emit('rssiUpdate', rssi);
|
|
229
320
|
}
|
package/lib/characteristic.js
CHANGED
|
@@ -45,6 +45,9 @@ class Characteristic extends EventEmitter {
|
|
|
45
45
|
this.on('unsubscribe', this.onUnsubscribe.bind(this));
|
|
46
46
|
this.on('notify', this.onNotify.bind(this));
|
|
47
47
|
this.on('indicate', this.onIndicate.bind(this));
|
|
48
|
+
|
|
49
|
+
this._maxValueSizes = new Map();
|
|
50
|
+
this._updateValueCallbacks = new Map();
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
toString () {
|
|
@@ -57,28 +60,42 @@ class Characteristic extends EventEmitter {
|
|
|
57
60
|
});
|
|
58
61
|
}
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
getMaxValueSize (connection) {
|
|
64
|
+
return this._maxValueSizes.get(connection);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
onReadRequest (connection, offset, callback) {
|
|
61
68
|
callback(this.RESULT_UNLIKELY_ERROR, null);
|
|
62
69
|
}
|
|
63
70
|
|
|
64
|
-
onWriteRequest (data, offset, withoutResponse, callback) {
|
|
71
|
+
onWriteRequest (connection, data, offset, withoutResponse, callback) {
|
|
65
72
|
callback(this.RESULT_UNLIKELY_ERROR);
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
onSubscribe (maxValueSize, updateValueCallback) {
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
75
|
+
onSubscribe (connection, maxValueSize, updateValueCallback) {
|
|
76
|
+
this._maxValueSizes.set(connection, maxValueSize);
|
|
77
|
+
this._updateValueCallbacks.set(connection, updateValueCallback);
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
onUnsubscribe () {
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
80
|
+
onUnsubscribe (connection) {
|
|
81
|
+
this._maxValueSizes.delete(connection);
|
|
82
|
+
this._updateValueCallbacks.delete(connection);
|
|
76
83
|
}
|
|
77
84
|
|
|
78
|
-
onNotify () {
|
|
85
|
+
onNotify (connection) {
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
onIndicate () {
|
|
88
|
+
onIndicate (connection) {
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
notify (data, connection = null) {
|
|
92
|
+
if (connection && this._updateValueCallbacks.has(connection)) {
|
|
93
|
+
this._updateValueCallbacks.get(connection)(data);
|
|
94
|
+
} else if (!connection) {
|
|
95
|
+
for (const callback of this._updateValueCallbacks.values()) {
|
|
96
|
+
callback(data);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
82
99
|
}
|
|
83
100
|
}
|
|
84
101
|
|
|
@@ -15,11 +15,11 @@ class AclStream extends EventEmitter {
|
|
|
15
15
|
this._hci.queueAclDataPkt(this._handle, cid, data);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
push (cid, data) {
|
|
18
|
+
push (handle, cid, data) {
|
|
19
19
|
if (data) {
|
|
20
|
-
this.emit('data', cid, data);
|
|
20
|
+
this.emit('data', handle, cid, data);
|
|
21
21
|
} else {
|
|
22
|
-
this.emit('end');
|
|
22
|
+
this.emit('end', handle);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|