3
3
*/
4
4
5
5
import { FileTransferClient } from '../common/ble-file-transfer.js' ;
6
- import { CONNTYPE , CONNSTATE } from '../constants.js' ;
6
+ import { CONNTYPE } from '../constants.js' ;
7
7
import { Workflow } from './workflow.js' ;
8
8
import { GenericModal , DeviceInfoModal } from '../common/dialogs.js' ;
9
- import { sleep , getUrlParam } from '../common/utilities.js' ;
9
+ import { sleep } from '../common/utilities.js' ;
10
10
11
11
const bleNusServiceUUID = 'adaf0001-4369-7263-7569-74507974686e' ;
12
12
const bleNusCharRXUUID = 'adaf0002-4369-7263-7569-74507974686e' ;
@@ -50,23 +50,23 @@ class BLEWorkflow extends Workflow {
50
50
btnBond = modal . querySelector ( '#promptBond' ) ;
51
51
btnReconnect = modal . querySelector ( '#bleReconnect' ) ;
52
52
53
- btnRequestBluetoothDevice . addEventListener ( 'click' , async ( event ) => {
54
- await this . onRequestBluetoothDeviceButtonClick ( event ) ;
55
- } ) ;
56
- btnBond . addEventListener ( 'click' , async ( event ) => {
57
- await this . onBond ( event ) ;
58
- } ) ;
59
- btnReconnect . addEventListener ( 'click' , async ( event ) => {
60
- await this . reconnectButtonHandler ( event ) ;
61
- } ) ;
53
+ btnRequestBluetoothDevice . addEventListener ( 'click' , this . onRequestBluetoothDeviceButtonClick . bind ( this ) ) ;
54
+ //btnBond.addEventListener('click', this.onBond.bind(this));
55
+ btnReconnect . addEventListener ( 'click' , this . reconnectButtonHandler . bind ( this ) ) ;
62
56
57
+ // Check if Web Bluetooth is available
63
58
if ( ! ( await this . available ( ) instanceof Error ) ) {
64
59
let stepOne ;
65
60
if ( stepOne = modal . querySelector ( '.step:first-of-type' ) ) {
66
61
stepOne . classList . add ( "hidden" ) ;
67
62
}
68
- const devices = await navigator . bluetooth . getDevices ( ) ;
69
- this . connectionStep ( devices . length > 0 ? 2 : 1 ) ;
63
+ try {
64
+ const devices = await navigator . bluetooth . getDevices ( ) ;
65
+ console . log ( devices ) ;
66
+ this . connectionStep ( devices . length > 0 ? 2 : 1 ) ;
67
+ } catch ( e ) {
68
+ console . log ( "New Permissions backend for Web Bluetooth not enabled. Go to chrome://flags/#enable-web-bluetooth-new-permissions-backend to enable." , e ) ;
69
+ }
70
70
} else {
71
71
modal . querySelectorAll ( '.step:not(:first-of-type)' ) . forEach ( ( stepItem ) => {
72
72
stepItem . classList . add ( "hidden" ) ;
@@ -79,7 +79,9 @@ class BLEWorkflow extends Workflow {
79
79
80
80
async onSerialReceive ( e ) { ;
81
81
// TODO: Make use of super.onSerialReceive() so that title can be extracted
82
- this . writeToTerminal ( this . decoder . decode ( e . target . value . buffer , { stream : true } ) ) ;
82
+ let output = this . decoder . decode ( e . target . value . buffer , { stream : true } ) ;
83
+ console . log ( output ) ;
84
+ this . writeToTerminal ( output ) ;
83
85
}
84
86
85
87
async connectToSerial ( ) {
@@ -89,6 +91,8 @@ class BLEWorkflow extends Workflow {
89
91
this . txCharacteristic = await this . serialService . getCharacteristic ( bleNusCharTXUUID ) ;
90
92
this . rxCharacteristic = await this . serialService . getCharacteristic ( bleNusCharRXUUID ) ;
91
93
94
+ // Remove any existing event listeners to prevent multiple reads
95
+ this . txCharacteristic . removeEventListener ( 'characteristicvaluechanged' , this . onSerialReceive . bind ( this ) ) ;
92
96
this . txCharacteristic . addEventListener ( 'characteristicvaluechanged' , this . onSerialReceive . bind ( this ) ) ;
93
97
await this . txCharacteristic . startNotifications ( ) ;
94
98
return true ;
@@ -105,92 +109,102 @@ class BLEWorkflow extends Workflow {
105
109
console . log ( 'Getting existing permitted Bluetooth devices...' ) ;
106
110
const devices = await navigator . bluetooth . getDevices ( ) ;
107
111
108
- console . log ( '> Got ' + devices . length + ' Bluetooth devices .' ) ;
112
+ console . log ( '> Found ' + devices . length + ' Bluetooth device(s) .' ) ;
109
113
// These devices may not be powered on or in range, so scan for
110
114
// advertisement packets from them before connecting.
111
115
for ( const device of devices ) {
112
116
await this . connectToBluetoothDevice ( device ) ;
113
117
}
114
118
}
115
119
catch ( error ) {
116
- console . log ( 'Argh! ' + error ) ;
120
+ console . error ( error ) ;
121
+ await this . _showMessage ( error ) ;
117
122
}
118
123
}
119
124
}
120
125
126
+ // Bring up a dialog to request a device
127
+ async requestDevice ( ) {
128
+ return navigator . bluetooth . requestDevice ( {
129
+ filters : [ { services : [ 0xfebb ] } , ] , // <- Prefer filters to save energy & show relevant devices.
130
+ optionalServices : [ 0xfebb , bleNusServiceUUID ]
131
+ } ) ;
132
+ }
133
+
121
134
async connectToBluetoothDevice ( device ) {
122
135
const abortController = new AbortController ( ) ;
123
136
124
- device . addEventListener ( 'advertisementreceived' , async ( event ) => {
137
+ async function onAdvertisementReceived ( event ) {
125
138
console . log ( '> Received advertisement from "' + device . name + '"...' ) ;
126
139
// Stop watching advertisements to conserve battery life.
127
140
abortController . abort ( ) ;
128
141
console . log ( 'Connecting to GATT Server from "' + device . name + '"...' ) ;
129
142
try {
130
- await this . showBusy ( device . gatt . connect ( ) ) ;
143
+ await device . gatt . connect ( ) ;
144
+ } catch ( error ) {
145
+ await this . _showMessage ( "Failed to connect to device. Try forgetting device from OS bluetooth devices and try again." ) ;
146
+ }
147
+ if ( device . gatt . connected ) {
131
148
console . log ( '> Bluetooth device "' + device . name + ' connected.' ) ;
132
149
await this . switchToDevice ( device ) ;
150
+ } else {
151
+ console . log ( 'Unable to connect to bluetooth device "' + device . name + '.' ) ;
133
152
}
134
- catch ( error ) {
135
- console . log ( 'Argh! ' + error ) ;
136
- }
137
- } , { once : true } ) ;
153
+ }
138
154
139
- //await this.showBusy(device.gatt.connect());
140
- await navigator . bluetooth . requestDevice ( {
141
- filters : [ { services : [ 0xfebb ] } , ] , // <- Prefer filters to save energy & show relevant devices.
142
- optionalServices : [ 0xfebb , bleNusServiceUUID ]
143
- } ) ;
155
+ device . removeEventListener ( 'advertisementreceived' , onAdvertisementReceived . bind ( this ) ) ;
156
+ device . addEventListener ( 'advertisementreceived' , onAdvertisementReceived . bind ( this ) ) ;
144
157
145
158
this . debugLog ( "connecting to " + device . name ) ;
146
159
try {
147
160
console . log ( 'Watching advertisements from "' + device . name + '"...' ) ;
148
161
await device . watchAdvertisements ( { signal : abortController . signal } ) ;
149
162
}
150
163
catch ( error ) {
151
- console . log ( 'Argh! ' + error ) ;
164
+ console . error ( error ) ;
165
+ await this . _showMessage ( error ) ;
152
166
}
153
167
}
154
168
155
169
// Request Bluetooth Device
156
170
async onRequestBluetoothDeviceButtonClick ( e ) {
157
- try {
171
+ // try {
158
172
console . log ( 'Requesting any Bluetooth device...' ) ;
159
173
this . debugLog ( "Requesting device. Cancel if empty and try existing" ) ;
160
- let device = await navigator . bluetooth . requestDevice ( {
161
- filters : [ { services : [ 0xfebb ] } , ] , // <- Prefer filters to save energy & show relevant devices.
162
- optionalServices : [ 0xfebb , bleNusServiceUUID ]
163
- } ) ;
174
+ let device = await this . requestDevice ( ) ;
164
175
165
- await this . showBusy ( device . gatt . connect ( ) ) ;
166
176
console . log ( '> Requested ' + device . name ) ;
177
+ await device . gatt . connect ( ) ;
167
178
168
179
await this . switchToDevice ( device ) ;
169
- }
180
+ /* }
170
181
catch (error) {
171
- console . log ( 'Argh: ' + error ) ;
182
+ console.error(error);
183
+ await this._showMessage(error);
172
184
this.debugLog('No device selected. Try to connect to existing.');
173
- }
185
+ }*/
174
186
}
175
187
176
188
async switchToDevice ( device ) {
177
189
console . log ( device ) ;
178
190
this . bleDevice = device ;
191
+ this . bleDevice . removeEventListener ( "gattserverdisconnected" , this . onDisconnected . bind ( this ) ) ;
179
192
this . bleDevice . addEventListener ( "gattserverdisconnected" , this . onDisconnected . bind ( this ) ) ;
180
193
this . bleServer = this . bleDevice . gatt ;
181
194
console . log ( "connected" , this . bleServer ) ;
182
195
let services ;
183
196
184
- try {
197
+ console . log ( device . gatt . connected ) ;
198
+ //try {
185
199
services = await this . bleServer . getPrimaryServices ( ) ;
186
- } catch ( e ) {
200
+ /* } catch (e) {
187
201
console.log(e, e.stack);
188
- }
202
+ }*/
189
203
console . log ( services ) ;
190
204
191
205
console . log ( 'Initializing File Transfer Client...' ) ;
192
206
this . initFileClient ( new FileTransferClient ( this . bleDevice , 65536 ) ) ;
193
- this . debugLog ( "connected" ) ;
207
+ await this . fileHelper . bond ( ) ;
194
208
await this . connectToSerial ( ) ;
195
209
196
210
// Enable/Disable UI buttons
@@ -243,15 +257,17 @@ class BLEWorkflow extends Workflow {
243
257
if ( result = await super . connect ( ) instanceof Error ) {
244
258
return result ;
245
259
}
260
+ // Is this a new connection?
246
261
if ( ! this . bleDevice ) {
247
262
let devices = await navigator . bluetooth . getDevices ( ) ;
248
263
for ( const device of devices ) {
249
264
await this . connectToBluetoothDevice ( device ) ;
250
265
}
251
266
}
252
267
268
+ // Do we have a connection now but still need to connect serial?
253
269
if ( this . bleDevice && ! this . bleServer ) {
254
- await await this . showBusy ( this . bleDevice . gatt . connect ( ) ) ;
270
+ await this . showBusy ( this . bleDevice . gatt . connect ( ) ) ;
255
271
this . switchToDevice ( this . bleDevice ) ;
256
272
}
257
273
}
0 commit comments