Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add manual connection option #3703

Merged
merged 2 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
"portsSelectManual": {
"message": "Manual Selection"
},
"portsSelectNone": {
"message": "No connection available"
},
"portsSelectVirtual": {
"message": "Virtual Mode (Experimental)",
"description": "Configure a Virtual Flight Controller without the need of a physical FC."
Expand Down Expand Up @@ -113,6 +116,10 @@
"message": "Use mDNS Browser Device discovery on network (experimental)",
"description": "Enable mDNS Browser Device discovery in PortHandler (experimental)"
},
"showManualMode": {
"message": "Enable manual connection mode",
"description": "Text for the option to enable or disable manual connection mode"
},
"showVirtualMode": {
"message": "Enable virtual connection mode",
"description": "Text for the option to enable or disable the virtual FC"
Expand Down
112 changes: 59 additions & 53 deletions src/js/port_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { generateVirtualApiVersions, getTextWidth } from './utils/common';
import { get as getConfig } from "./ConfigStorage";
import serial from "./serial";
import MdnsDiscovery from "./mdns_discovery";
import $ from 'jquery';
import { isWeb } from "./utils/isWeb";

const TIMEOUT_CHECK = 500 ; // With 250 it seems that it produces a memory leak and slowdown in some versions, reason unknown
Expand All @@ -18,6 +17,7 @@ export const usbDevices = { filters: [
] };

const PortHandler = new function () {
this.currentPorts = [];
this.initialPorts = false;
this.port_detected_callbacks = [];
this.port_removed_callbacks = [];
Expand All @@ -26,6 +26,7 @@ const PortHandler = new function () {
this.showAllSerialDevices = false;
this.useMdnsBrowser = false;
this.showVirtualMode = false;
this.showManualMode = false;
};

PortHandler.initialize = function () {
Expand Down Expand Up @@ -56,6 +57,7 @@ PortHandler.reinitialize = function () {
}

this.showVirtualMode = getConfig('showVirtualMode').showVirtualMode;
this.showManualMode = getConfig('showManualMode').showManualMode;
this.showAllSerialDevices = getConfig('showAllSerialDevices').showAllSerialDevices;
this.useMdnsBrowser = getConfig('useMdnsBrowser').useMdnsBrowser;

Expand Down Expand Up @@ -86,10 +88,10 @@ PortHandler.check_serial_devices = function () {
const self = this;

serial.getDevices(function(cp) {
let currentPorts = [];
self.currentPorts = [];

if (self.useMdnsBrowser) {
currentPorts = [
self.currentPorts = [
...cp,
...(MdnsDiscovery.mdnsBrowser.services?.filter(s => s.txt?.vendor === 'elrs' && s.txt?.type === 'rx' && s.ready === true)
.map(s => s.addresses.map(a => ({
Expand All @@ -101,36 +103,35 @@ PortHandler.check_serial_devices = function () {
}))).flat() ?? []),
].filter(Boolean);
} else {
currentPorts = cp;
self.currentPorts = cp;
}

// auto-select port (only during initialization)
if (!self.initialPorts) {
currentPorts = self.updatePortSelect(currentPorts);
self.selectPort(currentPorts);
self.initialPorts = currentPorts;
self.updatePortSelect(self.currentPorts);
self.selectActivePort();
self.initialPorts = self.currentPorts;
GUI.updateManualPortVisibility();
} else {
self.removePort(currentPorts);
self.detectPort(currentPorts);
self.removePort();
self.detectPort();
}
});
};

PortHandler.check_usb_devices = function (callback) {
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();
let usbText;
if (result[0].productName) {
usbText = (`DFU - ${result[0].productName}`);
} else {
usbText = "DFU";
}

const productName = result[0].productName;
const usbText = productName ? `DFU - ${productName}` : 'DFU';

self.portPickerElement.append($('<option/>', {
value: "DFU",
Expand Down Expand Up @@ -176,21 +177,17 @@ PortHandler.check_usb_devices = function (callback) {
});
};

PortHandler.removePort = function(currentPorts) {
PortHandler.removePort = function() {
const self = this;
const removePorts = self.array_difference(self.initialPorts, currentPorts);
const removePorts = self.array_difference(self.initialPorts, self.currentPorts);

if (removePorts.length) {
console.log(`PortHandler - Removed: ${JSON.stringify(removePorts)}`);
self.port_available = false;
// disconnect "UI" - routine can't fire during atmega32u4 reboot procedure !!!
if (GUI.connected_to) {
for (let i = 0; i < removePorts.length; i++) {
if (removePorts[i].path === GUI.connected_to) {
$('div.connect_controls a.connect').click();
$('div.connect_controls a.connect.active').click();
}
}
if (removePorts.some(port => port.path === GUI.connected_to)) {
$('div.connect_controls a.connect').click();
$('div.connect_controls a.connect.active').click();
}
// trigger callbacks (only after initialization)
for (let i = (self.port_removed_callbacks.length - 1); i >= 0; i--) {
Expand All @@ -208,26 +205,26 @@ PortHandler.removePort = function(currentPorts) {
self.port_removed_callbacks.splice(index, 1);
}
}
for (let i = 0; i < removePorts.length; i++) {
self.initialPorts.splice(self.initialPorts.indexOf(removePorts[i]), 1);
for (const port of removePorts) {
self.initialPorts.splice(self.initialPorts.indexOf(port, 1));
}
self.updatePortSelect(self.initialPorts);
self.portPickerElement.trigger('change');
}
};

PortHandler.detectPort = function(currentPorts) {
PortHandler.detectPort = function() {
const self = this;
const newPorts = self.array_difference(currentPorts, self.initialPorts);
const newPorts = self.array_difference(self.currentPorts, self.initialPorts);

if (newPorts.length) {
currentPorts = self.updatePortSelect(currentPorts);
self.updatePortSelect(self.currentPorts);
console.log(`PortHandler - Found: ${JSON.stringify(newPorts)}`);

if (newPorts.length === 1) {
self.portPickerElement.val(newPorts[0].path);
} else if (newPorts.length > 1) {
self.selectPort(currentPorts);
self.selectActivePort();
}

self.port_available = true;
Expand All @@ -239,11 +236,9 @@ PortHandler.detectPort = function(currentPorts) {
self.portPickerElement.trigger('change');

// auto-connect if enabled
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) {
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to && GUI.active_tab !== 'firmware_flasher') {
// start connect procedure. We need firmware flasher protection over here
if (GUI.active_tab !== 'firmware_flasher') {
$('div.connect_controls a.connect').click();
}
$('div.connect_controls a.connect').click();
}
// trigger callbacks
for (let i = (self.port_detected_callbacks.length - 1); i >= 0; i--) {
Expand All @@ -261,7 +256,7 @@ PortHandler.detectPort = function(currentPorts) {
self.port_detected_callbacks.splice(index, 1);
}
}
self.initialPorts = currentPorts;
self.initialPorts = self.currentPorts;
}
};

Expand All @@ -274,20 +269,24 @@ PortHandler.sortPorts = function(ports) {
});
};

PortHandler.addNoPortSelection = function() {
if (!this.showVirtualMode && !this.showManualMode) {
this.portPickerElement.append($("<option/>", {
value: 'none',
text: i18n.getMessage('portsSelectNone'),
}));
}
};

PortHandler.updatePortSelect = function (ports) {
ports = this.sortPorts(ports);
this.portPickerElement.empty();

for (let i = 0; i < ports.length; i++) {
let portText;
if (ports[i].displayName) {
portText = (`${ports[i].path} - ${ports[i].displayName}`);
} else {
portText = ports[i].path;
}
for (const port of ports) {
const portText = port.displayName ? `${port.path} - ${port.displayName}` : port.path;

this.portPickerElement.append($("<option/>", {
value: ports[i].path,
value: port.path,
text: portText,
/**
* @deprecated please avoid using `isDFU` and friends for new code.
Expand All @@ -307,20 +306,27 @@ PortHandler.updatePortSelect = function (ports) {
}));
}

this.portPickerElement.append($("<option/>", {
value: 'manual',
text: i18n.getMessage('portsSelectManual'),
/**
* @deprecated please avoid using `isDFU` and friends for new code.
*/
data: {isManual: true},
}));
if (this.showManualMode) {
this.portPickerElement.append($("<option/>", {
value: 'manual',
text: i18n.getMessage('portsSelectManual'),
/**
* @deprecated please avoid using `isDFU` and friends for new code.
*/
data: {isManual: true},
}));
}

if (!ports.length) {
this.addNoPortSelection();
}

this.setPortsInputWidth();
return ports;
this.currentPorts = ports;
};

PortHandler.selectPort = function(ports) {
PortHandler.selectActivePort = function() {
const ports = this.currentPorts;
const OS = GUI.operating_system;
for (let i = 0; i < ports.length; i++) {
const portName = ports[i].displayName;
Expand Down
Loading