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

scanning for elrs network devices with crsf msp frame capability #2922

Merged
merged 3 commits into from Sep 17, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions cordova/config_template.xml
Expand Up @@ -7,6 +7,7 @@
<access origin="*"/>
<allow-intent href="http://*/*"/>
<allow-intent href="https://*/*"/>
<allow-intent href="tcp://*/*"/>
<allow-intent href="tel:*"/>
<allow-intent href="sms:*"/>
<allow-intent href="mailto:*"/>
Expand Down
4 changes: 3 additions & 1 deletion cordova/package_template.json
Expand Up @@ -27,6 +27,7 @@
"cordova-plugin-whitelist": "^1.3.4",
"cordova-plugin-theme-detection": "^1.2.1",
"cordova-chrome-sockets-tcp": "^1.4.0",
"cordova-plugin-zeroconf": "^1.4.2",
"bf-cordovarduino": "^1.0.0",
"@ionic-native/core": "^5.1.0",
"@ionic-native/ionic-webview": "^5.36.0",
Expand Down Expand Up @@ -56,7 +57,8 @@
"cordova-plugin-theme-detection": {},
"bf-cordova-plugin-appavailability": {},
"cordova-chrome-sockets-tcp": {},
"cordova-plugin-ionic-webview": {}
"cordova-plugin-ionic-webview": {},
"cordova-plugin-zeroconf": {}
}
}
}
6 changes: 4 additions & 2 deletions package.json
Expand Up @@ -54,6 +54,7 @@
"@fortawesome/fontawesome-free": "^5.13.0",
"@panter/vue-i18next": "^0.15.2",
"bluebird": "^3.7.2",
"bonjour": "^3.5.0",
"djv": "^2.1.4",
"dompurify": "^2.3.6",
"i18next": "^19.0.0",
Expand All @@ -66,6 +67,7 @@
"jquery-ui-npm": "^1.12.0",
"lru_map": "^0.3.3",
"marked": "^4.0.17",
"multicast-dns": "^7.2.4",
"multiple-select": "^1.5.2",
"nw-vue-devtools-prebuilt": "^0.0.10",
"object-hash": "^3.0.0",
Expand All @@ -75,7 +77,7 @@
"switchery-latest": "^0.8.2",
"three": "~0.97.0",
"universal-ga": "^1.2.0",
"vue": "2.6.12"
"vue": "^2.6.14"
Copy link
Member

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

Copy link
Member Author

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.

},
"devDependencies": {
"@babel/core": "^7.18.5",
Expand Down Expand Up @@ -139,7 +141,7 @@
"through2": "^4.0.2",
"vinyl-source-stream": "^2.0.0",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.12",
"vue-template-compiler": "^2.6.14",
chmelevskij marked this conversation as resolved.
Show resolved Hide resolved
"yarn": "^1.22.17"
},
"optionalDependencies": {
Expand Down
121 changes: 109 additions & 12 deletions src/js/port_handler.js
@@ -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
Expand Down Expand Up @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The 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();
};
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 10 additions & 10 deletions src/main.html
Expand Up @@ -159,9 +159,9 @@
</div>
<betaflight-logo
:configurator-version="CONFIGURATOR.getDisplayVersion()"
:firmware-version="FC.CONFIG.flightControllerVersion"
:firmware-id="FC.CONFIG.flightControllerIdentifier"
:hardware-id="FC.CONFIG.hardwareName"
:firmware-version="FC.CONFIG.flightControllerVersion"
:firmware-id="FC.CONFIG.flightControllerIdentifier"
:hardware-id="FC.CONFIG.hardwareName"
></betaflight-logo>
<div id="port-picker">
<div id="port-override-option">
Expand Down Expand Up @@ -218,7 +218,7 @@
<div class="battery-status"></div>
</div>
</div>
<battery-legend
<battery-legend
:voltage="FC.ANALOG.voltage"
:vbatmaxcellvoltage="FC.BATTERY_CONFIG.vbatmaxcellvoltage"
></battery-legend>
Expand Down Expand Up @@ -294,9 +294,9 @@
<div class="tab_container">
<betaflight-logo
:configurator-version="CONFIGURATOR.getDisplayVersion()"
:firmware-version="FC.CONFIG.flightControllerVersion"
:firmware-id="FC.CONFIG.flightControllerIdentifier"
:hardware-id="FC.CONFIG.hardwareName"
:firmware-version="FC.CONFIG.flightControllerVersion"
:firmware-id="FC.CONFIG.flightControllerIdentifier"
:hardware-id="FC.CONFIG.hardwareName"
></betaflight-logo>
<div id="tabs">
<ul class="mode-disconnected">
Expand Down Expand Up @@ -373,9 +373,9 @@
:cpu-load="FC.CONFIG.cpuload"

:configurator-version="CONFIGURATOR.getDisplayVersion()"
:firmware-version="FC.CONFIG.flightControllerVersion"
:firmware-id="FC.CONFIG.flightControllerIdentifier"
:hardware-id="FC.CONFIG.hardwareName"
:firmware-version="FC.CONFIG.flightControllerVersion"
:firmware-id="FC.CONFIG.flightControllerIdentifier"
:hardware-id="FC.CONFIG.hardwareName"
></status-bar>
<div id="cache">
<div class="data-loading">
Expand Down