33 */
44
55import { FileTransferClient } from '../common/ble-file-transfer.js' ;
6- import { CONNTYPE , CONNSTATE } from '../constants.js' ;
6+ import { CONNTYPE } from '../constants.js' ;
77import { Workflow } from './workflow.js' ;
88import { GenericModal , DeviceInfoModal } from '../common/dialogs.js' ;
9- import { sleep , getUrlParam } from '../common/utilities.js' ;
9+ import { sleep } from '../common/utilities.js' ;
1010
1111const bleNusServiceUUID = 'adaf0001-4369-7263-7569-74507974686e' ;
1212const bleNusCharRXUUID = 'adaf0002-4369-7263-7569-74507974686e' ;
@@ -63,23 +63,23 @@ class BLEWorkflow extends Workflow {
6363 bond : btnBond
6464 } ;
6565
66- btnRequestBluetoothDevice . addEventListener ( 'click' , async ( event ) => {
67- await this . onRequestBluetoothDeviceButtonClick ( event ) ;
68- } ) ;
69- btnBond . addEventListener ( 'click' , async ( event ) => {
70- await this . onBond ( event ) ;
71- } ) ;
72- btnReconnect . addEventListener ( 'click' , async ( event ) => {
73- await this . reconnectButtonHandler ( event ) ;
74- } ) ;
66+ btnRequestBluetoothDevice . addEventListener ( 'click' , this . onRequestBluetoothDeviceButtonClick . bind ( this ) ) ;
67+ btnBond . addEventListener ( 'click' , this . onBond . bind ( this ) ) ;
68+ btnReconnect . addEventListener ( 'click' , this . reconnectButtonHandler . bind ( this ) ) ;
7569
70+ // Check if Web Bluetooth is available
7671 if ( ! ( await this . available ( ) instanceof Error ) ) {
7772 let stepOne ;
7873 if ( stepOne = modal . querySelector ( '.step:first-of-type' ) ) {
7974 stepOne . classList . add ( "hidden" ) ;
8075 }
81- const devices = await navigator . bluetooth . getDevices ( ) ;
82- this . connectionStep ( devices . length > 0 ? 2 : 1 ) ;
76+ try {
77+ const devices = await navigator . bluetooth . getDevices ( ) ;
78+ console . log ( devices ) ;
79+ this . connectionStep ( devices . length > 0 ? 2 : 1 ) ;
80+ } catch ( e ) {
81+ console . log ( "New Permissions backend for Web Bluetooth not enabled. Go to chrome://flags/#enable-web-bluetooth-new-permissions-backend to enable." , e ) ;
82+ }
8383 } else {
8484 modal . querySelectorAll ( '.step:not(:first-of-type)' ) . forEach ( ( stepItem ) => {
8585 stepItem . classList . add ( "hidden" ) ;
@@ -92,7 +92,9 @@ class BLEWorkflow extends Workflow {
9292
9393 async onSerialReceive ( e ) { ;
9494 // TODO: Make use of super.onSerialReceive() so that title can be extracted
95- this . writeToTerminal ( this . decoder . decode ( e . target . value . buffer , { stream : true } ) ) ;
95+ let output = this . decoder . decode ( e . target . value . buffer , { stream : true } ) ;
96+ console . log ( output ) ;
97+ this . writeToTerminal ( output ) ;
9698 }
9799
98100 async connectToSerial ( ) {
@@ -102,6 +104,8 @@ class BLEWorkflow extends Workflow {
102104 this . txCharacteristic = await this . serialService . getCharacteristic ( bleNusCharTXUUID ) ;
103105 this . rxCharacteristic = await this . serialService . getCharacteristic ( bleNusCharRXUUID ) ;
104106
107+ // Remove any existing event listeners to prevent multiple reads
108+ this . txCharacteristic . removeEventListener ( 'characteristicvaluechanged' , this . onSerialReceive . bind ( this ) ) ;
105109 this . txCharacteristic . addEventListener ( 'characteristicvaluechanged' , this . onSerialReceive . bind ( this ) ) ;
106110 await this . txCharacteristic . startNotifications ( ) ;
107111 return true ;
@@ -118,92 +122,102 @@ class BLEWorkflow extends Workflow {
118122 console . log ( 'Getting existing permitted Bluetooth devices...' ) ;
119123 const devices = await navigator . bluetooth . getDevices ( ) ;
120124
121- console . log ( '> Got ' + devices . length + ' Bluetooth devices .' ) ;
125+ console . log ( '> Found ' + devices . length + ' Bluetooth device(s) .' ) ;
122126 // These devices may not be powered on or in range, so scan for
123127 // advertisement packets from them before connecting.
124128 for ( const device of devices ) {
125129 await this . connectToBluetoothDevice ( device ) ;
126130 }
127131 }
128132 catch ( error ) {
129- console . log ( 'Argh! ' + error ) ;
133+ console . error ( error ) ;
134+ await this . _showMessage ( error ) ;
130135 }
131136 }
132137 }
133138
139+ // Bring up a dialog to request a device
140+ async requestDevice ( ) {
141+ return navigator . bluetooth . requestDevice ( {
142+ filters : [ { services : [ 0xfebb ] } , ] , // <- Prefer filters to save energy & show relevant devices.
143+ optionalServices : [ 0xfebb , bleNusServiceUUID ]
144+ } ) ;
145+ }
146+
134147 async connectToBluetoothDevice ( device ) {
135148 const abortController = new AbortController ( ) ;
136149
137- device . addEventListener ( 'advertisementreceived' , async ( event ) => {
150+ async function onAdvertisementReceived ( event ) {
138151 console . log ( '> Received advertisement from "' + device . name + '"...' ) ;
139152 // Stop watching advertisements to conserve battery life.
140153 abortController . abort ( ) ;
141154 console . log ( 'Connecting to GATT Server from "' + device . name + '"...' ) ;
142155 try {
143- await this . showBusy ( device . gatt . connect ( ) ) ;
156+ await device . gatt . connect ( ) ;
157+ } catch ( error ) {
158+ await this . _showMessage ( "Failed to connect to device. Try forgetting device from OS bluetooth devices and try again." ) ;
159+ }
160+ if ( device . gatt . connected ) {
144161 console . log ( '> Bluetooth device "' + device . name + ' connected.' ) ;
145162 await this . switchToDevice ( device ) ;
163+ } else {
164+ console . log ( 'Unable to connect to bluetooth device "' + device . name + '.' ) ;
146165 }
147- catch ( error ) {
148- console . log ( 'Argh! ' + error ) ;
149- }
150- } , { once : true } ) ;
166+ }
151167
152- //await this.showBusy(device.gatt.connect());
153- await navigator . bluetooth . requestDevice ( {
154- filters : [ { services : [ 0xfebb ] } , ] , // <- Prefer filters to save energy & show relevant devices.
155- optionalServices : [ 0xfebb , bleNusServiceUUID ]
156- } ) ;
168+ device . removeEventListener ( 'advertisementreceived' , onAdvertisementReceived . bind ( this ) ) ;
169+ device . addEventListener ( 'advertisementreceived' , onAdvertisementReceived . bind ( this ) ) ;
157170
158171 this . debugLog ( "connecting to " + device . name ) ;
159172 try {
160173 console . log ( 'Watching advertisements from "' + device . name + '"...' ) ;
161174 await device . watchAdvertisements ( { signal : abortController . signal } ) ;
162175 }
163176 catch ( error ) {
164- console . log ( 'Argh! ' + error ) ;
177+ console . error ( error ) ;
178+ await this . _showMessage ( error ) ;
165179 }
166180 }
167181
168182 // Request Bluetooth Device
169183 async onRequestBluetoothDeviceButtonClick ( e ) {
170- try {
184+ // try {
171185 console . log ( 'Requesting any Bluetooth device...' ) ;
172186 this . debugLog ( "Requesting device. Cancel if empty and try existing" ) ;
173- let device = await navigator . bluetooth . requestDevice ( {
174- filters : [ { services : [ 0xfebb ] } , ] , // <- Prefer filters to save energy & show relevant devices.
175- optionalServices : [ 0xfebb , bleNusServiceUUID ]
176- } ) ;
187+ let device = await this . requestDevice ( ) ;
177188
178- await this . showBusy ( device . gatt . connect ( ) ) ;
179189 console . log ( '> Requested ' + device . name ) ;
190+ await device . gatt . connect ( ) ;
180191
181192 await this . switchToDevice ( device ) ;
182- }
193+ /* }
183194 catch (error) {
184- console . log ( 'Argh: ' + error ) ;
195+ console.error(error);
196+ await this._showMessage(error);
185197 this.debugLog('No device selected. Try to connect to existing.');
186- }
198+ }*/
187199 }
188200
189201 async switchToDevice ( device ) {
190202 console . log ( device ) ;
191203 this . bleDevice = device ;
204+ this . bleDevice . removeEventListener ( "gattserverdisconnected" , this . onDisconnected . bind ( this ) ) ;
192205 this . bleDevice . addEventListener ( "gattserverdisconnected" , this . onDisconnected . bind ( this ) ) ;
193206 this . bleServer = this . bleDevice . gatt ;
194207 console . log ( "connected" , this . bleServer ) ;
195208 let services ;
196209
197- try {
210+ console . log ( device . gatt . connected ) ;
211+ //try {
198212 services = await this . bleServer . getPrimaryServices ( ) ;
199- } catch ( e ) {
213+ /* } catch (e) {
200214 console.log(e, e.stack);
201- }
215+ }*/
202216 console . log ( services ) ;
203217
204218 console . log ( 'Initializing File Transfer Client...' ) ;
205219 this . initFileClient ( new FileTransferClient ( this . bleDevice , 65536 ) ) ;
206- this . debugLog ( "connected" ) ;
220+ await this . fileHelper . bond ( ) ;
207221 await this . connectToSerial ( ) ;
208222
209223 // Enable/Disable UI buttons
@@ -256,15 +270,17 @@ class BLEWorkflow extends Workflow {
256270 if ( result = await super . connect ( ) instanceof Error ) {
257271 return result ;
258272 }
273+ // Is this a new connection?
259274 if ( ! this . bleDevice ) {
260275 let devices = await navigator . bluetooth . getDevices ( ) ;
261276 for ( const device of devices ) {
262277 await this . connectToBluetoothDevice ( device ) ;
263278 }
264279 }
265280
281+ // Do we have a connection now but still need to connect serial?
266282 if ( this . bleDevice && ! this . bleServer ) {
267- await await this . showBusy ( this . bleDevice . gatt . connect ( ) ) ;
283+ await this . showBusy ( this . bleDevice . gatt . connect ( ) ) ;
268284 this . switchToDevice ( this . bleDevice ) ;
269285 }
270286 }
0 commit comments