/
Bluetooth.ts
102 lines (87 loc) · 3.02 KB
/
Bluetooth.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
import {IBluetooth, State} from "./IBluetooth";
import * as noble from "noble";
import {IDevice} from "./IDevice";
import {Device} from "./Device";
class Bluetooth implements IBluetooth {
private _onDiscover: (device: IDevice) => any
private _onError: (error: any) => any
private _state: State = "unknown"
private _timeout: number
private _retries = 3
public constructor(onDiscover: (device: IDevice) => any = () => {},
onError = () => {},
timeout = 500) {
this._onDiscover = onDiscover
this._onError = onError
this._timeout = timeout
}
public startScanning(serviceUUIDS?: string[]): Promise<void> {
const self = this
const uuids = serviceUUIDS || []
return new Promise<void>((resolve, reject) => {
self.enableAdapter().then(() => {
noble.startScanning(uuids, false)
noble.on("discover", (peripheral => {
self._onDiscover(new Device(
peripheral.id,
peripheral.address,
peripheral
))
}))
noble.on("error", self._onError)
self._state = "poweredOn"
resolve()
}).catch(reject)
})
}
public stopScanning(): Promise<void> {
const self = this
return new Promise<void>((resolve, reject) => {
if(self._state === "poweredOn") {
noble.stopScanning()
noble.removeListener("discover", this._onDiscover)
noble.removeListener("error", this._onError)
this._state = "disconnected"
resolve()
} else {
reject(new Error("Bluetooth is still offline."))
}
})
}
set onDiscover(callback: (device: IDevice) => any) {
this._onDiscover = callback
}
set onError(callback: (error: any) => any) {
this._onError = callback
}
set timeout(timeout: number) {
this._timeout = timeout
}
get timeout(): number {
return this._timeout
}
get state(): State {
return this._state
}
private enableAdapter(): Promise<void> {
const self = this
let interval: any
let counter = 0
return new Promise<void>((resolve, reject) => {
interval = setInterval(() => {
if (noble.state === "poweredOn") {
clearInterval(interval)
self._state = "poweredOn"
resolve()
}
if (counter === self._retries) {
clearInterval(interval)
self._state = "disconnected"
reject(new Error("Bluetooth is offline."))
}
++counter
}, this._timeout)
})
}
}
export {Bluetooth}