-
Notifications
You must be signed in to change notification settings - Fork 1
/
Peripheral.ts
164 lines (145 loc) · 3.96 KB
/
Peripheral.ts
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import { inspect } from 'util';
import { Adapter } from './Adapter';
import { AddressType } from './AddressType';
import { GattRemote } from './gatt';
import { CUSTOM, InspectOptionsStylized } from './Inspect';
/**
* The current state of the peripheral.
*/
export type PeripheralState = 'connecting' | 'connected' | 'disconnecting' | 'disconnected';
/**
* Connection options used to establish the BLE connection.
* Certain options are only supported on certain platforms / bindings.
*/
export interface ConnectOptions {
/**
* The requested MTU that is sent during the MTU negotiation. Actual mtu may be lower.
*/
mtu?: number;
/**
* The minimum connection interval.
*/
minInterval?: number;
/**
* The maximum connection interval
*/
maxInterval?: number;
/**
* The connection latency.
*/
latency?: number;
/**
* The supervision timeout.
*/
supervisionTimeout?: number;
}
/**
* Represents a peripheral that was found during scanning.
*/
export abstract class Peripheral {
/**
* The adapter that this peripheral was found by.
*/
public readonly adapter: Adapter;
/**
* The remote gatt server. Only available after connecting.
*/
protected _gatt: GattRemote;
public get gatt(): GattRemote {
if (this.state !== 'connected') {
throw new Error('GATT is only available when connected');
}
return this._gatt;
}
/**
* The unique identifier for this peripheral.
*/
public readonly uuid: string;
/**
* The MAC address type of this peripheral.
*/
public readonly addressType: AddressType;
/**
* The MAC address of this peripheral. All lowercase, with colon separator between bytes, e.g. 11:22:33:aa:bb:cc
*/
public readonly address: string;
/**
* The advertised name of the peripheral.
*/
public name: string;
/**
* Any manufacturer advertisement data received from the peripheral. Includes the company identifier.
*/
public manufacturerData: Buffer;
/**
* The current RSSI signal strength of the peripheral.
*/
public rssi: number;
protected _state: PeripheralState;
/**
* The current state of the peripheral.
*/
public get state(): PeripheralState {
return this._state;
}
public constructor(
adapter: Adapter,
uuid: string,
name: string,
addressType: AddressType,
address: string,
advertisement?: Buffer,
rssi?: number
) {
this.adapter = adapter;
this.uuid = uuid;
this.name = name;
this.addressType = addressType;
this.address = address;
this.manufacturerData = advertisement;
this.rssi = rssi;
this._state = 'disconnected';
}
/**
* Connect to this peripheral and setup GATT. Throws an error when connecting fails.
* Some connection settings may not be supported on certain platforms and wil be ignored.
* @param options The connection options.
*/
public abstract connect(options?: ConnectOptions): Promise<GattRemote>;
/**
* Disconnect from this peripheral. Does nothing if not connected. This method **never** throws an error.
* When connecting to a peripheral you should always wrap your calls in try-catch-finally and call this method at the end.
* ```
* try {
* peripheral.connect()
* } catch (err) {
* ...
* } finally {
* peripheral.disconnect();
* }```
*/
public abstract disconnect(): Promise<void>;
public toString(): string {
return JSON.stringify(this.toJSON());
}
public toJSON(): Record<string, unknown> {
return {
uuid: this.uuid,
address: this.address,
addressType: this.addressType,
rssi: this.rssi,
state: this._state,
adapter: this.adapter
};
}
public [CUSTOM](depth: number, options: InspectOptionsStylized): string {
const name = this.constructor.name;
if (depth < 0) {
return options.stylize(`[${name}]`, 'special');
}
const newOptions = { ...options, depth: options.depth === null ? null : options.depth - 1 };
const padding = ' '.repeat(name.length + 1);
const inner = inspect(this.toJSON(), newOptions).replace(/\n/g, `\n${padding}`);
return `${options.stylize(name, 'special')} ${inner}`;
}
}