From b28b5cb6b7e974835b7d4584b79a14a0661446ec Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Fri, 27 Sep 2019 09:16:27 -0700 Subject: [PATCH] better flow + handle unclosed connection (#921) * better flow + handle unclosed connection * more checks --- editor/deploy.ts | 27 ++++++++++++++++++++------- editor/extension.ts | 5 +++-- libs/core/input.ts | 4 ++-- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/editor/deploy.ts b/editor/deploy.ts index efcad389..ad952de8 100644 --- a/editor/deploy.ts +++ b/editor/deploy.ts @@ -65,9 +65,12 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO { } async readSerialAsync() { + if (this._reader) return; + this._reader = this.port.readable.getReader(); let buffer: Uint8Array; - while (!!this._reader) { + const reader = this._reader; + while (reader === this._reader) { // will change if we recycle the connection const { done, value } = await this._reader.read() if (!buffer) buffer = value; else { // concat @@ -112,8 +115,18 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO { throw new Error(lf("error on brick ({0})", msg)) } + private close() { + if (this.port.readable) {// it's open + this.port.close(); + this._reader = undefined; + this._writer = undefined; + } + } + async reconnectAsync(): Promise { - if (!this._reader) { + if (!this.port.readable) { + this._reader = undefined; + this._writer = undefined; await this.port.open(this.options); this.readSerialAsync(); } @@ -121,9 +134,7 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO { } async disconnectAsync(): Promise { - this.port.close(); - this._reader = undefined; - this._writer = undefined; + this.close(); return Promise.resolve(); } @@ -157,7 +168,7 @@ export function initAsync(): Promise { useHID = true; } - if(WebSerialPackageIO.isSupported()) + if (WebSerialPackageIO.isSupported()) pxt.tickEvent("bluetooth.supported"); return Promise.resolve(); @@ -171,6 +182,8 @@ export function enableWebSerial() { initPromise = undefined; useWebSerial = WebSerialPackageIO.isSupported(); useHID = useWebSerial; + if (useWebSerial) + initHidAsync().done(); } let initPromise: Promise @@ -185,7 +198,7 @@ function initHidAsync() { // needs to run within a click handler useHID = false; useWebSerial = false; // cleanup - let p = ev3 ? ev3.disconnectAsync().catch(e => {}) : Promise.resolve(); + let p = ev3 ? ev3.disconnectAsync().catch(e => { }) : Promise.resolve(); return p.then(() => Promise.reject(err)) }) } else { diff --git a/editor/extension.ts b/editor/extension.ts index db05a0e9..5954ca87 100644 --- a/editor/extension.ts +++ b/editor/extension.ts @@ -80,7 +80,6 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P className: "bluetooth focused", onclick: () => { pxt.tickEvent("bluetooth.enable"); - enableWebSerial(); confirmAsync({ header: lf("Bluetooth enabled"), hasCloseIcon: true, @@ -93,7 +92,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P }], htmlBody: `

-${lf("Please download again to send your code to the EV3 over Bluetooth.")} +${lf("Download again to send your code to the EV3 over Bluetooth. Make sure to stop your program!")}

${lf("You will be prompted to select a serial port.")} @@ -101,6 +100,8 @@ ${lf("On Windows, look for 'Standard Serial over Bluetooth link'.")} ${lf("If you have paired multiple EV3, you might have to try out multiple ports until you find the correct one.")}

` + }).then(() => { + enableWebSerial(); }) } } : undefined, downloadAgain ? { diff --git a/libs/core/input.ts b/libs/core/input.ts index a33f8310..110f6170 100644 --- a/libs/core/input.ts +++ b/libs/core/input.ts @@ -310,7 +310,7 @@ void cUiUpdatePower(void) // TODO? for now assume touch sensorInfo.devType = DAL.DEVICE_TYPE_TOUCH } else if (newConn == DAL.CONN_NONE || newConn == 0) { - control.dmesg(`disconnect at port ${sensorInfo.port}`) + //control.dmesg(`disconnect at port ${sensorInfo.port}`) } else { control.dmesg(`unknown connection type: ${newConn} at ${sensorInfo.port}`) } @@ -328,7 +328,7 @@ void cUiUpdatePower(void) if (numChanged == 0 && nonActivated == 0) return - control.dmesg(`updating sensor status`) + //control.dmesg(`updating sensor status`) nonActivated = 0; for (const sensorInfo of sensorInfos) { if (sensorInfo.devType == DAL.DEVICE_TYPE_IIC_UNKNOWN) {