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
scanning for elrs network devices with crsf msp frame capability #2922
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would any of these logs be useful for the UI layer? E.G. https://github.com/betaflight/betaflight-configurator/blob/master/src/js/msp/MSPHelper.js#L2940 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. totaly, i will change it, so that those logs go to the GUI as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please change in follow up patch. |
||
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() ?? []), | ||
chmelevskij marked this conversation as resolved.
Show resolved
Hide resolved
|
||
].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; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please keep the pinned dependencies as they are not related to this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you install it from master, 2.6.12 vue gets installed together with 2.6.14 vue-template-compiler. This just fixed both to the same version, so nothing breaks.