From ac27e8f5c1e0c4372bd7ae5dfd43de6a30fb750e Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Mon, 3 Jun 2024 18:24:47 +0200 Subject: [PATCH] Add web API support for flashing (#3996) * add web API support for flashing * Fixes per review * Refactor some function --- src/js/msp/MSPConnector.js | 112 +-- src/js/port_handler.js | 104 +-- src/js/protocols/stm32.js | 903 ------------------------ src/js/protocols/stm32usbdfu.js | 1164 ------------------------------- src/js/protocols/webstm32.js | 953 +++++++++++++++++++++++++ src/js/tabs/firmware_flasher.js | 67 +- src/js/usb_shim.js | 5 - 7 files changed, 1067 insertions(+), 2241 deletions(-) delete mode 100644 src/js/protocols/stm32.js delete mode 100644 src/js/protocols/stm32usbdfu.js create mode 100644 src/js/protocols/webstm32.js delete mode 100644 src/js/usb_shim.js diff --git a/src/js/msp/MSPConnector.js b/src/js/msp/MSPConnector.js index 92b65a5ab4..d69ce0d853 100644 --- a/src/js/msp/MSPConnector.js +++ b/src/js/msp/MSPConnector.js @@ -6,43 +6,40 @@ import MSP from "../msp"; import FC from "../fc"; import MSPCodes from "./MSPCodes"; import CONFIGURATOR from "../data_storage"; -import serial from "../serial"; +import serial from "../webSerial"; import { gui_log } from "../gui_log"; /** * This seems to be mainly used in firmware flasher parts. */ -const MSPConnectorImpl = function () { - this.baud = undefined; - this.port = undefined; - this.onConnectCallback = undefined; - this.onTimeoutCallback = undefined; - this.onDisconnectCallback = undefined; -}; - -MSPConnectorImpl.prototype.connect = function (port, baud, onConnectCallback, onTimeoutCallback, onFailureCallback) { - - const self = this; - self.port = port; - self.baud = baud; - self.onConnectCallback = onConnectCallback; - self.onTimeoutCallback = onTimeoutCallback; - self.onFailureCallback = onFailureCallback; - - serial.connect(self.port, {bitrate: self.baud}, function (openInfo) { - if (openInfo) { - const disconnectAndCleanup = function() { - serial.disconnect(function(result) { - console.log('Disconnected'); - MSP.clearListeners(); +function readSerialAdapter(e) { + read_serial(e.detail.buffer); +} - self.onTimeoutCallback(); - }); +function disconnectAndCleanup() { + serial.disconnect((result) => { + console.log('Disconnected', result); - MSP.disconnect_cleanup(); - }; + MSP.clearListeners(); + this.onTimeoutCallback(); + }); + + MSP.disconnect_cleanup(); +} + +class MSPConnectorImpl { + constructor() { + this.baud = undefined; + this.port = undefined; + this.onConnectCallback = undefined; + this.onTimeoutCallback = undefined; + this.onDisconnectCallback = undefined; + } + + handleConnect(openInfo) { + if (openInfo) { FC.resetState(); // disconnect after 10 seconds with error if we don't get IDENT data @@ -54,37 +51,68 @@ MSPConnectorImpl.prototype.connect = function (port, baud, onConnectCallback, on } }, 10000); - serial.onReceive.addListener(read_serial); + serial.removeEventListener('receive', readSerialAdapter); + serial.addEventListener('receive', readSerialAdapter); const mspHelper = new MspHelper(); MSP.listen(mspHelper.process_data.bind(mspHelper)); - MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () { + MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, () => { CONFIGURATOR.connectionValid = true; GUI.timeout_remove('msp_connector'); console.log('Connected'); - self.onConnectCallback(); + this.onConnectCallback(); }); } else { gui_log(i18n.getMessage('serialPortOpenFail')); - self.onFailureCallback(); + this.onFailureCallback(); } - }); -}; + } + + handleDisconnect (detail) { + console.log('Disconnected', detail); + + serial.removeEventListener('receive', readSerialAdapter); -MSPConnectorImpl.prototype.disconnect = function(onDisconnectCallback) { - self.onDisconnectCallback = onDisconnectCallback; + // Calling in case event listeners were not removed + serial.removeEventListener('connect', (e) => this.handleConnect(e.detail)); + serial.removeEventListener('disconnect', (e) => this.handleDisconnect(e)); - serial.disconnect(function (result) { MSP.clearListeners(); - console.log('Disconnected'); + MSP.disconnect_cleanup(); + } - self.onDisconnectCallback(result); - }); + connect(port, baud, onConnectCallback, onTimeoutCallback, onFailureCallback) { - MSP.disconnect_cleanup(); -}; + this.port = port; + this.baud = baud; + this.onConnectCallback = onConnectCallback; + this.onTimeoutCallback = onTimeoutCallback; + this.onFailureCallback = onFailureCallback; + + serial.removeEventListener('connect', (e) => this.handleConnect(e.detail)); + serial.addEventListener('connect', (e) => this.handleConnect(e.detail), { once: true }); + + serial.removeEventListener('disconnect', (e) => this.handleDisconnect(e)); + serial.addEventListener('disconnect', (e) => this.handleDisconnect(e), { once: true }); + + serial.connect(this.port, { baudRate: this.baud }); + } + + disconnect(onDisconnectCallback) { + this.onDisconnectCallback = onDisconnectCallback; + + serial.disconnect((result) => { + MSP.clearListeners(); + console.log('Disconnected', result); + + this.onDisconnectCallback(result); + }); + + MSP.disconnect_cleanup(); + } +} export default MSPConnectorImpl; diff --git a/src/js/port_handler.js b/src/js/port_handler.js index 7ebb3ec6a5..80233bf426 100644 --- a/src/js/port_handler.js +++ b/src/js/port_handler.js @@ -1,15 +1,7 @@ -import GUI from "./gui"; -import FC from "./fc"; -import { i18n } from "./localization"; import { get as getConfig } from "./ConfigStorage"; -import { isWeb } from "./utils/isWeb"; -import { usbDevices } from "./usb_devices"; -import { serialShim } from "./serial_shim.js"; -import { usbShim } from "./usb_shim.js"; import { EventBus } from "../components/eventBus"; - -const serial = serialShim(); -const usb = usbShim(); +import serial from "./webSerial"; +import usb from "./protocols/webusbdfu"; const DEFAULT_PORT = 'noselection'; const DEFAULT_BAUDS = 115200; @@ -92,22 +84,18 @@ PortHandler.onChangeSelectedPort = function(port) { this.portPicker.selectedPort = port; }; -PortHandler.updateCurrentSerialPortsList = function () { - return serial.getDevices() - .then((ports) => { - const orderedPorts = this.sortPorts(ports); - this.portAvailable = orderedPorts.length > 0; - this.currentSerialPorts = orderedPorts; - }); +PortHandler.updateCurrentSerialPortsList = async function () { + const ports = await serial.getDevices(); + const orderedPorts = this.sortPorts(ports); + this.portAvailable = orderedPorts.length > 0; + this.currentSerialPorts = orderedPorts; }; -PortHandler.updateCurrentUsbPortsList = function () { - return usb.getDevices() - .then((ports) => { - const orderedPorts = this.sortPorts(ports); - this.dfuAvailable = orderedPorts.length > 0; - this.currentUsbPorts = orderedPorts; - }); +PortHandler.updateCurrentUsbPortsList = async function () { + const ports = await usb.getDevices(); + const orderedPorts = this.sortPorts(ports); + this.dfuAvailable = orderedPorts.length > 0; + this.currentUsbPorts = orderedPorts; }; PortHandler.sortPorts = function(ports) { @@ -149,7 +137,7 @@ PortHandler.selectActivePort = function(suggestedDevice) { selectedPort = suggestedDevice.path; } - // Return some serial port that is recognized by the filter + // Return some usb port that is recognized by the filter if (!selectedPort) { selectedPort = this.currentUsbPorts.find(device => deviceFilter.some(filter => device.displayName.includes(filter))); if (selectedPort) { @@ -157,7 +145,7 @@ PortHandler.selectActivePort = function(suggestedDevice) { } } - // Return some usb port that is recognized by the filter + // Return some serial port that is recognized by the filter if (!selectedPort) { selectedPort = this.currentSerialPorts.find(device => deviceFilter.some(filter => device.displayName.includes(filter))); if (selectedPort) { @@ -186,70 +174,6 @@ PortHandler.selectActivePort = function(suggestedDevice) { // TODO all the methods from here need to be refactored or removed ************************************/ -PortHandler.check_usb_devices = function (callback) { - - // TODO needs USB code refactor for web - if (isWeb()) { - return; - } - - const self = this; - - chrome.usb.getDevices(usbDevices, function (result) { - - const dfuElement = self.portPickerElement.children("[value='DFU']"); - if (result.length) { - // Found device in DFU mode, add it to the list - if (!dfuElement.length) { - self.portPickerElement.empty(); - - const productName = result[0].productName; - const usbText = productName ? `DFU - ${productName}` : 'DFU'; - - self.portPickerElement.append($('