parent
09355c25d0
commit
88f5c7d863
|
@ -47,6 +47,9 @@
|
||||||
</config-file>
|
</config-file>
|
||||||
<resource-file src="usb_device_filter.xml" target="app/src/main/res/xml/usb_device_filter.xml"/>
|
<resource-file src="usb_device_filter.xml" target="app/src/main/res/xml/usb_device_filter.xml"/>
|
||||||
<resource-file src="manifest.json" target="app/src/main/assets/www/manifest.json"/>
|
<resource-file src="manifest.json" target="app/src/main/assets/www/manifest.json"/>
|
||||||
|
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
|
||||||
|
<application android:usesCleartextTraffic="true" />
|
||||||
|
</edit-config>
|
||||||
</platform>
|
</platform>
|
||||||
<platform name="ios">
|
<platform name="ios">
|
||||||
<allow-intent href="itms:*"/>
|
<allow-intent href="itms:*"/>
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const MDNS_INTERVAL = 10000;
|
||||||
|
const TCP_CHECK_INTERVAL = 5000;
|
||||||
|
const TCP_TIMEOUT = 2000;
|
||||||
|
|
||||||
|
const MdnsDiscovery = new function() {
|
||||||
|
this.mdnsBrowser = {
|
||||||
|
services: [],
|
||||||
|
browser: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.tcpCheckLock = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
MdnsDiscovery.initialize = function() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
if (GUI.isCordova()) {
|
||||||
|
const zeroconf = cordova.plugins.zeroconf;
|
||||||
|
|
||||||
|
function reinit() {
|
||||||
|
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 (action === 'resolved' && service.name.includes("elrs_rx")) {
|
||||||
|
console.log("Zeroconf Service Changed", service);
|
||||||
|
self.mdnsBrowser.services.push({
|
||||||
|
addresses: service.ipv4Addresses,
|
||||||
|
txt: service.txtRecord,
|
||||||
|
fqdn: `${service.name}._http._tcp.local.`,
|
||||||
|
ready: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (action === 'added' && service.name.includes("elrs_rx")) {
|
||||||
|
//restart zeroconf if service ip doesn't arrive in 1000ms
|
||||||
|
setTimeout(() => {
|
||||||
|
if (self.mdnsBrowser.services.length === 0 || self.mdnsBrowser.services.filter(s => s.fqdn === `${service.name}._http._tcp.local.`)[0].ready === false) {
|
||||||
|
zeroconf.close();
|
||||||
|
reinit();
|
||||||
|
}
|
||||||
|
},1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
reinit();
|
||||||
|
} else {
|
||||||
|
const bonjour = require('bonjour')();
|
||||||
|
|
||||||
|
self.mdnsBrowser.browser = bonjour.find({ type: 'http' }, service => {
|
||||||
|
console.log("Found HTTP service", service);
|
||||||
|
self.mdnsBrowser.services.push({
|
||||||
|
addresses: service.addresses,
|
||||||
|
txt: service.txt,
|
||||||
|
fqdn: service.fqdn,
|
||||||
|
ready: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if (GUI.isCordova() && self.mdnsBrowser.services.length > 0) {
|
||||||
|
//ping removed services and enable them if they are online
|
||||||
|
const inactiveServices = self.mdnsBrowser.services.filter(s => s.ready === false);
|
||||||
|
inactiveServices.forEach(function (service) {
|
||||||
|
$.ajax({
|
||||||
|
url: `http://${service.addresses[0]}`,
|
||||||
|
success: () => {
|
||||||
|
self.mdnsBrowser.services = self.mdnsBrowser.services
|
||||||
|
.map(s => {
|
||||||
|
if (s.fqdn === service.fqdn) {
|
||||||
|
return {...s, ready: true};
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: () => {},
|
||||||
|
timeout: TCP_TIMEOUT,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (!GUI.connected_to && self.mdnsBrowser.browser) {
|
||||||
|
self.mdnsBrowser.browser.update();
|
||||||
|
}
|
||||||
|
}, MDNS_INTERVAL);
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
self.tcpCheck();
|
||||||
|
}, TCP_CHECK_INTERVAL);
|
||||||
|
};
|
||||||
|
|
||||||
|
MdnsDiscovery.tcpCheck = function() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
if (!self.tcpCheckLock) {
|
||||||
|
self.tcpCheckLock = true;
|
||||||
|
if (PortHandler.initialPorts?.length > 0) {
|
||||||
|
const tcpPorts = PortHandler.initialPorts.filter(p => p.path.startsWith('tcp://'));
|
||||||
|
tcpPorts.forEach(function (port) {
|
||||||
|
const removePort = () => {
|
||||||
|
if (GUI.isCordova()) {
|
||||||
|
//disable offline services instead of removing them
|
||||||
|
self.mdnsBrowser.services = self.mdnsBrowser.services
|
||||||
|
.map(s => {
|
||||||
|
if (s.fqdn === port.fqdn) {
|
||||||
|
return {...s, ready: false};
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.mdnsBrowser.browser._removeService(port.fqdn);
|
||||||
|
self.mdnsBrowser.services = self.mdnsBrowser.services.filter(s => s.fqdn !== port.fqdn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
url: `http://${port.path.split('//').pop()}`,
|
||||||
|
error: removePort,
|
||||||
|
timeout: TCP_TIMEOUT,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,9 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const TIMEOUT_CHECK = 500 ; // With 250 it seems that it produces a memory leak and slowdown in some versions, reason unknown
|
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: [
|
const usbDevices = { filters: [
|
||||||
{'vendorId': 1155, 'productId': 57105}, // STM Device in DFU Mode || Digital Radio in USB mode
|
{'vendorId': 1155, 'productId': 57105}, // STM Device in DFU Mode || Digital Radio in USB mode
|
||||||
|
@ -21,102 +18,16 @@ const PortHandler = new function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
PortHandler.initialize = function () {
|
PortHandler.initialize = function () {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
const portPickerElementSelector = "div#port-picker #port";
|
const portPickerElementSelector = "div#port-picker #port";
|
||||||
this.portPickerElement = $(portPickerElementSelector);
|
self.portPickerElement = $(portPickerElementSelector);
|
||||||
this.selectList = document.querySelector(portPickerElementSelector);
|
self.selectList = document.querySelector(portPickerElementSelector);
|
||||||
this.initialWidth = this.selectList.offsetWidth + 12;
|
self.initialWidth = self.selectList.offsetWidth + 12;
|
||||||
|
|
||||||
// fill dropdown with version numbers
|
// fill dropdown with version numbers
|
||||||
generateVirtualApiVersions();
|
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);
|
|
||||||
|
|
||||||
this.reinitialize(); // just to prevent code redundancy
|
this.reinitialize(); // just to prevent code redundancy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,6 +38,7 @@ PortHandler.reinitialize = function () {
|
||||||
}
|
}
|
||||||
this.showVirtualMode = ConfigStorage.get('showVirtualMode').showVirtualMode;
|
this.showVirtualMode = ConfigStorage.get('showVirtualMode').showVirtualMode;
|
||||||
this.showAllSerialDevices = ConfigStorage.get('showAllSerialDevices').showAllSerialDevices;
|
this.showAllSerialDevices = ConfigStorage.get('showAllSerialDevices').showAllSerialDevices;
|
||||||
|
|
||||||
this.check(); // start listening, check after TIMEOUT_CHECK ms
|
this.check(); // start listening, check after TIMEOUT_CHECK ms
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,7 +53,7 @@ PortHandler.check = function () {
|
||||||
self.check_serial_devices();
|
self.check_serial_devices();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.usbCheckLoop = setTimeout(function () {
|
self.usbCheckLoop = setTimeout(() => {
|
||||||
self.check();
|
self.check();
|
||||||
}, TIMEOUT_CHECK);
|
}, TIMEOUT_CHECK);
|
||||||
};
|
};
|
||||||
|
@ -153,7 +65,7 @@ PortHandler.check_serial_devices = function () {
|
||||||
|
|
||||||
let currentPorts = [
|
let currentPorts = [
|
||||||
...cp,
|
...cp,
|
||||||
...(self.mdnsBrowser?.services?.filter(s => s.txt.vendor === 'elrs' && s.txt.type === 'rx')
|
...(MdnsDiscovery.mdnsBrowser.services?.filter(s => s.txt.vendor === 'elrs' && s.txt.type === 'rx' && s.ready === true)
|
||||||
.map(s => s.addresses.map(a => ({
|
.map(s => s.addresses.map(a => ({
|
||||||
path: `tcp://${a}`,
|
path: `tcp://${a}`,
|
||||||
displayName: `${s.txt.target} - ${s.txt.version}`,
|
displayName: `${s.txt.target} - ${s.txt.version}`,
|
||||||
|
@ -239,7 +151,8 @@ PortHandler.removePort = function(currentPorts) {
|
||||||
if (GUI.connected_to) {
|
if (GUI.connected_to) {
|
||||||
for (let i = 0; i < removePorts.length; i++) {
|
for (let i = 0; i < removePorts.length; i++) {
|
||||||
if (removePorts[i].path === GUI.connected_to) {
|
if (removePorts[i].path === GUI.connected_to) {
|
||||||
$('div#header_btns a.connect').click();
|
$('div.connect_controls a.connect').click();
|
||||||
|
$('div.connect_controls a.connect.active').click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +206,7 @@ PortHandler.detectPort = function(currentPorts) {
|
||||||
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) {
|
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) {
|
||||||
// start connect procedure. We need firmware flasher protection over here
|
// start connect procedure. We need firmware flasher protection over here
|
||||||
if (GUI.active_tab !== 'firmware_flasher') {
|
if (GUI.active_tab !== 'firmware_flasher') {
|
||||||
$('div#header_btns a.connect').click();
|
$('div.connect_controls a.connect').click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// trigger callbacks
|
// trigger callbacks
|
||||||
|
|
|
@ -145,6 +145,7 @@ function initializeSerialBackend() {
|
||||||
ConfigStorage.set({'auto_connect': GUI.auto_connect});
|
ConfigStorage.set({'auto_connect': GUI.auto_connect});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MdnsDiscovery.initialize();
|
||||||
PortHandler.initialize();
|
PortHandler.initialize();
|
||||||
PortUsage.initialize();
|
PortUsage.initialize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
<script type="text/javascript" src="./js/port_usage.js"></script>
|
<script type="text/javascript" src="./js/port_usage.js"></script>
|
||||||
<script type="text/javascript" src="./js/serial.js"></script>
|
<script type="text/javascript" src="./js/serial.js"></script>
|
||||||
<script type="text/javascript" src="./js/gui.js"></script>
|
<script type="text/javascript" src="./js/gui.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/mdns_discovery.js"></script>
|
||||||
<script type="text/javascript" src="./js/huffman.js"></script>
|
<script type="text/javascript" src="./js/huffman.js"></script>
|
||||||
<script type="text/javascript" src="./js/default_huffman_tree.js"></script>
|
<script type="text/javascript" src="./js/default_huffman_tree.js"></script>
|
||||||
<script type="text/javascript" src="./js/model.js"></script>
|
<script type="text/javascript" src="./js/model.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue