mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-25 01:05:15 +03:00
Merge pull request #2922 from freasy/feature/mdns_check_and_resolve
This commit is contained in:
commit
8813538fef
6 changed files with 241 additions and 34 deletions
|
@ -1,6 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
const TIMEOUT_CHECK = 500 ; // With 250 it seems that it produces a memory leak and slowdown in some versions, reason unknown
|
||||
const MDNS_INTERVAL = 10000;
|
||||
const TCP_CHECK_INTERVAL = 5000;
|
||||
const TCP_TIMEOUT = 2000;
|
||||
|
||||
const usbDevices = { filters: [
|
||||
{'vendorId': 1155, 'productId': 57105}, // STM Device in DFU Mode || Digital Radio in USB mode
|
||||
|
@ -29,6 +32,94 @@ PortHandler.initialize = function () {
|
|||
// fill dropdown with version numbers
|
||||
generateVirtualApiVersions();
|
||||
|
||||
const self = this;
|
||||
|
||||
self.mdnsBrowser = {
|
||||
services: [],
|
||||
browser: null,
|
||||
init: false,
|
||||
};
|
||||
|
||||
let bonjour = {};
|
||||
|
||||
if (!self.mdnsBrowser.init) {
|
||||
if (GUI.isCordova()) {
|
||||
const zeroconf = cordova.plugins.zeroconf;
|
||||
zeroconf.registerAddressFamily = 'ipv4'; // or 'ipv6' ('any' by default)
|
||||
zeroconf.watchAddressFamily = 'ipv4'; // or 'ipv6' ('any' by default)
|
||||
zeroconf.watch("_http._tcp.", "local.", (result) => {
|
||||
const action = result.action;
|
||||
const service = result.service;
|
||||
if (['added', 'resolved'].includes(action)) {
|
||||
console.log("Zeroconf Service Changed", service);
|
||||
self.mdnsBrowser.services.push({
|
||||
addresses: service.ipv4Addresses,
|
||||
txt: service.txtRecord,
|
||||
fqdn: service.hostname,
|
||||
});
|
||||
} else {
|
||||
console.log("Zeroconf Service Removed", service);
|
||||
self.mdnsBrowser.services = mdnsBrowser.services.filter(s => s.fqdn !== service.hostname);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
bonjour = require('bonjour')();
|
||||
self.mdnsBrowser.browser = bonjour.find({ type: 'http' }, function(service) {
|
||||
console.log("Found HTTP service", service);
|
||||
self.mdnsBrowser.services.push({
|
||||
addresses: service.addresses,
|
||||
txt: service.txt,
|
||||
fqdn: service.host,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
self.mdnsBrowser.init = true;
|
||||
}
|
||||
|
||||
const tcpCheck = function() {
|
||||
if (!self.tcpCheckLock) {
|
||||
self.tcpCheckLock = true;
|
||||
if (self.initialPorts?.length > 0) {
|
||||
const tcpPorts = self.initialPorts.filter(p => p.path.startsWith('tcp://'));
|
||||
tcpPorts.forEach(function (port) {
|
||||
const removePort = () => {
|
||||
self.mdnsBrowser.services = self.mdnsBrowser.services.filter(s => s.fqdn !== port.fqdn);
|
||||
};
|
||||
$.get({
|
||||
host: port.path.split('//').pop(),
|
||||
port: 80,
|
||||
timeout: TCP_TIMEOUT,
|
||||
}, (res) => res.destroy())
|
||||
.fail(removePort);
|
||||
});
|
||||
|
||||
//timeout is 2000ms for every found port, so wait that time before checking again
|
||||
setTimeout(() => {
|
||||
self.tcpCheckLock = false;
|
||||
}, Math.min(tcpPorts.length, 1) * (TCP_TIMEOUT + 1));
|
||||
} else {
|
||||
self.tcpCheckLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
tcpCheck();
|
||||
}, TCP_CHECK_INTERVAL);
|
||||
};
|
||||
|
||||
tcpCheck();
|
||||
|
||||
if (self.mdns_timer) {
|
||||
clearInterval(self.mdns_timer);
|
||||
}
|
||||
|
||||
self.mdns_timer = setInterval(() => {
|
||||
if (!GUI.connected_to && !GUI.isCordova() && self.mdnsBrowser.browser) {
|
||||
self.mdnsBrowser.browser.update();
|
||||
}
|
||||
}, MDNS_INTERVAL);
|
||||
|
||||
// start listening, check after TIMEOUT_CHECK ms
|
||||
this.check();
|
||||
};
|
||||
|
@ -52,7 +143,19 @@ PortHandler.check = function () {
|
|||
PortHandler.check_serial_devices = function () {
|
||||
const self = this;
|
||||
|
||||
serial.getDevices(function(currentPorts) {
|
||||
serial.getDevices(function(cp) {
|
||||
|
||||
let currentPorts = [
|
||||
...cp,
|
||||
...(self.mdnsBrowser?.services?.filter(s => s.txt.vendor === 'elrs' && s.txt.type === 'rx')
|
||||
.map(s => s.addresses.map(a => ({
|
||||
path: `tcp://${a}`,
|
||||
displayName: `${s.txt.target} - ${s.txt.version}`,
|
||||
fqdn: s.fqdn,
|
||||
vendorId: 0,
|
||||
productId: 0,
|
||||
}))).flat() ?? []),
|
||||
].filter(Boolean);
|
||||
|
||||
// auto-select port (only during initialization)
|
||||
if (!self.initialPorts) {
|
||||
|
@ -128,7 +231,7 @@ PortHandler.removePort = function(currentPorts) {
|
|||
// 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] === GUI.connected_to) {
|
||||
if (removePorts[i].path === GUI.connected_to) {
|
||||
$('div#header_btns a.connect').click();
|
||||
}
|
||||
}
|
||||
|
@ -162,19 +265,13 @@ PortHandler.detectPort = function(currentPorts) {
|
|||
const newPorts = self.array_difference(currentPorts, self.initialPorts);
|
||||
|
||||
if (newPorts.length) {
|
||||
// pick last_used_port for manual tcp auto-connect or detect and select new port for serial
|
||||
currentPorts = self.updatePortSelect(currentPorts);
|
||||
console.log(`PortHandler - Found: ${JSON.stringify(newPorts)}`);
|
||||
|
||||
const result = ConfigStorage.get('last_used_port');
|
||||
if (result.last_used_port) {
|
||||
if (result.last_used_port.includes('tcp')) {
|
||||
self.portPickerElement.val('manual');
|
||||
} else if (newPorts.length === 1) {
|
||||
self.portPickerElement.val(newPorts[0].path);
|
||||
} else if (newPorts.length > 1) {
|
||||
self.selectPort(currentPorts);
|
||||
}
|
||||
if (newPorts.length === 1) {
|
||||
self.portPickerElement.val(newPorts[0].path);
|
||||
} else if (newPorts.length > 1) {
|
||||
self.selectPort(currentPorts);
|
||||
}
|
||||
|
||||
self.port_available = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue