Skip to content

Commit

Permalink
Merge branch 'master' into linkstats-debug
Browse files Browse the repository at this point in the history
  • Loading branch information
JyeSmith authored Feb 20, 2024
2 parents c95e89d + b4ad5ce commit 064a04f
Show file tree
Hide file tree
Showing 65 changed files with 2,565 additions and 704 deletions.
1 change: 1 addition & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ python/__pycache__/
*.pyc
super_defines.txt
include/WebContent.h
include/flashdiscrim.h
.DS_Store
1 change: 1 addition & 0 deletions src/html/hardware.html
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ <h1><b>ExpressLRS</b></h1>
</td><td>How the power level is set</td></tr>
<tr><td></td><td>Power Value(s)</td><td><input size='40' id='power_values' name='power_values' type='text' class='array'/></td><td>Comma-separated list of values that set the power output (if using a DAC these are the DAC values)</td></tr>
<tr><td></td><td>Secondary Power Value(s)</td><td><input size='40' id='power_values2' name='power_values2' type='text' class='array'/></td><td>Comma-separated list of values that set the power output (if using a DAC then these set the Semtech power output)</td></tr>
<tr><td></td><td>Dual Power Value(s)</td><td><input size='40' id='power_values_dual' name='power_values_dual' type='text' class='array'/></td><td>Comma-separated list of values that set the higher frequency power output of a dual band Tx/Rx</td></tr>

<tr><td colspan='2'><b>Radio Power Detection</td></tr>
<tr><td></td><td>PDET pin<img class="icon-analog"/></td><td><input size='3' id='power_pdet' name='power_pdet' type='text'/></td><td>Analog input (up to 1.1V) connected to 'power detect' pin on PA for adjustment of the power output</td></tr>
Expand Down
50 changes: 38 additions & 12 deletions src/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,38 @@ <h1><b>ExpressLRS</b></h1>
<div class="mui-panel mui-col-sm-10 mui-col-sm-offset-1">

<ul class="mui-tabs__bar mui-tabs__bar--justified">
<li class="mui--is-active"><a data-mui-toggle="tab" data-mui-controls="pane-justified-1">Options</a></li>
@@if not isTX:
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-3">Model</a></li>
@@end
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-1">Options</a></li>
<li><a id="network-tab" data-mui-toggle="tab" data-mui-controls="pane-justified-4">WiFi</a></li>
@@if isTX:
<li id="button-tab"><a data-mui-toggle="tab" data-mui-controls="pane-justified-3">Buttons</a></li>
@@end
@@if not isTX:
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-3">Model</a></li>
@@end
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-2">Update</a></li>
</ul>

<div class="mui-tabs__pane mui--is-active" id="pane-justified-1">
<div class="mui-tabs__pane" id="pane-justified-1">
<div class="mui-panel">
<h2>Runtime Options</h2>
This form <b>overrides</b> the options provided when the firmware was flashed. These changes will persist across reboots, but <b>will be reset</b> when the firmware is reflashed.
@@if isTX:
Note: The Binding phrase is <b>not</b> remembered, it is a temporary field used to generate the binding UID.
<br/>
<br/>
<br/><br/>
<div class="mui-textfield">
<input type="text" id="phrase" name="phrase" placeholder="Binding Phrase" />
<label for="phrase">Binding Phrase</label>
</div>
<form id='upload_options' method='POST' action="/options">
<input type="hidden" id="flash-discriminator" name="flash-discriminator"/>
<input type="hidden" id="wifi-ssid" name="wifi-ssid"/>
<input type="hidden" id='wifi-password' name='wifi-password'/>
<div class="mui-textfield">
<label for='uid'><span id="uid-text"></span></label>
<span class="badge" id="uid-type"></span>
<input size='40' id='uid' name='uid' type='text' class='array' readonly/>
</div>
@@else:
<br/><br/>
<form id='upload_options' method='POST' action="/options">
@@end
@@if sx127x:
<div class="mui-select">
<select id='domain' name='domain'>
Expand Down Expand Up @@ -110,8 +111,12 @@ <h2>Runtime Options</h2>
<div id="reset-options" style="display: none;">
<a class="mui-btn mui-btn--small mui-btn--danger">Reset runtime options to defaults</a>
</div>
<input type="hidden" id="flash-discriminator" name="flash-discriminator"/>
<input type="hidden" id="wifi-ssid" name="wifi-ssid"/>
<input type="hidden" id='wifi-password' name='wifi-password'/>
</form>
</div>
@@if isTX:
<div class="mui-panel">
<h2>Import/Export</h2>
<br/>
Expand All @@ -127,6 +132,7 @@ <h2>Import/Export</h2>
</button>
</div>
</div>
@@end
</div>

<div class="mui-tabs__pane" id="pane-justified-2">
Expand Down Expand Up @@ -210,7 +216,27 @@ <h2>PWM Output</h2>
</form>
</div>
<form class="mui-form" action='/config' id='config' method='POST'>
<div id="serial-config" style="display: block;">
<h2>Binding Phrase</h2>
<div class="mui-checkbox">
<input id="vbind" name="vbind" type="checkbox" value="1"/>
<label for="vbind">Never store bind information across reboots (volatile binding)</label>
</div>
<div id="bindphrase">
Enter a new binding phrase to replace the current binding information.
This will persist across reboots, but <b>will be reset</b> if the firmware is flashed with a binding phrase.
Note: The Binding phrase is not remembered, it is a temporary field used to generate the binding UID.
<br/><br/>
<div class="mui-textfield">
<input type="text" id="phrase" name="phrase" placeholder="Binding Phrase" />
<label for="phrase">Binding Phrase</label>
</div>
<div class="mui-textfield">
<label for="uid"><span id="uid-text"></span></label>
<span class="badge" id="uid-type"></span>
<input size="40" id="uid" name="uid" type="text" class="array" readonly/>
</div>
</div>
<div id="serial-config">
<h2>Serial Protocol</h2>
Set the protocol used to communicate with the flight controller or other external devices.
<br/><br/>
Expand Down Expand Up @@ -267,7 +293,7 @@ <h2>Force telemetry off</h2>
</form>
</div>
<div class="mui-panel">
<a id="reset-model" href="#">Reset all model settings to defaults.</a>
<a id="reset-model" href="#">Reset all model settings to defaults (includes binding).</a>
</div>
</div>
@@end
Expand Down
107 changes: 79 additions & 28 deletions src/html/scan.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,49 +245,66 @@ function init() {
_('modelid').value = '255';
}
};
// Start on the model tab
mui.tabs.activate('pane-justified-3');
@@else:
// Start on the options tab
mui.tabs.activate('pane-justified-1');
@@end
initOptions();
}

function updateUIDType(uidtype) {
let bg = '';
let fg = '';
let text = uidtype;
let fg = 'white';
let desc = '';
if (!uidtype || uidtype === 'Not set') {
bg = '#D50000'; // default 'red' for 'Not set'
fg = 'white';
text = 'Not set';
desc = 'The default binding UID from the device address will be used';

if (!uidtype || uidtype.startsWith('Not set')) // TX
{
bg = '#D50000'; // red/white
uidtype = 'Not set';
desc = 'Using autogenerated binding UID';
}
if (uidtype === 'Flashed') {
else if (uidtype === 'Flashed') // TX
{
bg = '#1976D2'; // blue/white
fg = 'white';
desc = 'The binding UID was generated from a binding phrase set at flash time';
}
if (uidtype === 'Overridden') {
bg = '#689F38'; // green
if (uidtype === 'Overridden') // TX
{
bg = '#689F38'; // green/black
fg = 'black';
desc = 'The binding UID has been generated from a bind-phrase previously entered into the "binding phrase" field above';
}
if (uidtype === 'Traditional') {
bg = '#D50000'; // red
fg = 'white';
desc = 'The binding UID has been set using traditional binding method i.e. button or 3-times power cycle and bound via the Lua script';
desc = 'The binding UID has been generated from a binding phrase previously entered into the "binding phrase" field above';
}
if (uidtype === 'Modified') {
else if (uidtype === 'Modified') // edited here
{
bg = '#7c00d5'; // purple
fg = 'white';
desc = 'The binding UID has been modified, but not yet saved';
}
if (uidtype === 'On loan') {
else if (uidtype === 'Volatile') // RX
{
bg = '#FFA000'; // amber
fg = 'black';
desc = 'The binding UID has been set using the model-loan feature';
desc = 'The binding UID will be cleared on boot';
}
else // RX
{
if (_('uid').value.endsWith('0,0,0,0'))
{
bg = '#FFA000'; // amber
uidtype = 'Not bound';
desc = 'This receiver is unbound and will boot to binding mode';
}
else
{
bg = '#1976D2'; // blue/white
uidtype = 'Bound';
desc = 'This receiver is bound and will boot waiting for connection';
}
}

_('uid-type').style.backgroundColor = bg;
_('uid-type').style.color = fg;
_('uid-type').textContent = text;
_('uid-type').textContent = uidtype;
_('uid-text').textContent = desc;
}

Expand Down Expand Up @@ -355,6 +372,11 @@ function updateConfig(data, options) {
_('serial-protocol').value = data['serial-protocol'];
_('serial-protocol').onchange();
_('is-airport').onchange = _('serial-protocol').onchange;
_('vbind').checked = data.hasOwnProperty('vbind') && data['vbind'];
_('vbind').onchange = () => {
_('bindphrase').style.display = _('vbind').checked ? 'none' : 'block';
}
_('vbind').onchange();
@@end
@@if isTX:
if (data.hasOwnProperty['button-colors']) {
Expand Down Expand Up @@ -536,6 +558,7 @@ _('firmware_file').addEventListener('change', (e) => {
uploadFile();
});

@@if isTX:
_('fileselect').addEventListener('change', (e) => {
const files = e.target.files || e.dataTransfer.files;
const reader = new FileReader();
Expand Down Expand Up @@ -565,6 +588,7 @@ _('fileselect').addEventListener('change', (e) => {
}
reader.readAsText(files[0]);
}, false);
@@end

// =========================================================

Expand Down Expand Up @@ -636,9 +660,16 @@ if (_('config')) {
"serial-protocol": +_('serial-protocol').value,
"sbus-failsafe": +_('sbus-failsafe').value,
"modelid": +_('modelid').value,
"force-tlm": +_('force-tlm').checked
"force-tlm": +_('force-tlm').checked,
"vbind": +_('vbind').checked,
"uid": _('uid').value.split(',').map(Number),
});
}));
}, () => {
originalUID = _('uid').value;
originalUIDType = 'Bound';
_('phrase').value = '';
updateUIDType(originalUIDType);
}));
}

function submitOptions(e) {
Expand Down Expand Up @@ -685,11 +716,13 @@ function submitOptions(e) {
confirmText: 'Reboot',
cancelText: 'Close'
}).then((e) => {
@@if isTX:
originalUID = _('uid').value;
originalUIDType = 'Flashed';
originalUIDType = 'Overridden';
_('phrase').value = '';
updateUIDType(originalUIDType);
if (e === 'confirm') {
@@end
if (e === 'confirm') {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/reboot');
xhr.setRequestHeader('Content-Type', 'application/json');
Expand Down Expand Up @@ -996,7 +1029,25 @@ md5 = function() {
return calcMD5;
}();

function isValidUidByte(s) {
let f = parseFloat(s);
return !isNaN(f) && isFinite(s) && Number.isInteger(f) && f >= 0 && f < 256;
}

function uidBytesFromText(text) {
// If text is 4-6 numbers separated with [commas]/[spaces] use as a literal UID
// This is a strict parser to not just extract numbers from text, but only accept if text is only UID bytes
if (/^[0-9, ]+$/.test(text))
{
let asArray = text.split(',').filter(isValidUidByte).map(Number);
if (asArray.length >= 4 && asArray.length <= 6)
{
while (asArray.length < 6)
asArray.unshift(0);
return asArray;
}
}

const bindingPhraseFull = `-DMY_BINDING_PHRASE="${text}"`;
const bindingPhraseHashed = md5(bindingPhraseFull);
return bindingPhraseHashed.subarray(0, 6);
Expand All @@ -1011,7 +1062,7 @@ function initBindingPhraseGen() {
updateUIDType(originalUIDType);
}
else {
uid.value = uidBytesFromText(text);
uid.value = uidBytesFromText(text.trim());
updateUIDType('Modified');
}
}
Expand Down
Loading

0 comments on commit 064a04f

Please sign in to comment.