mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #102 from TylerDurden-23/opt-system-settings
Add startup config editor to system settings menu
This commit is contained in:
+6
-1
@@ -1043,7 +1043,12 @@ void execute_config(void) __banked
|
||||
config_done:
|
||||
// Start saving commands to cmd_history
|
||||
save_cmd = 1;
|
||||
}
|
||||
|
||||
void clear_command_history(void) __banked
|
||||
{
|
||||
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
|
||||
cmd_history[cmd_history_ptr] = 0;
|
||||
cmd_history_ptr = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -12,4 +12,5 @@ uint8_t cmd_tokenize(void) __banked;
|
||||
void cmd_parser(void) __banked;
|
||||
void execute_config(void) __banked;
|
||||
void print_sw_version(void) __banked;
|
||||
void clear_command_history(void) __banked;
|
||||
#endif
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../config.txt
|
||||
+2
-1
@@ -49,7 +49,8 @@ async function fetchCmdLog() {
|
||||
console.log("CMD-Log: ", response);
|
||||
const t = await response.text();
|
||||
return t;
|
||||
} catch(error) {
|
||||
} catch(err) {
|
||||
console.error("Error: ", err);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -6,8 +6,9 @@ ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 12%;
|
||||
height: 100%;
|
||||
height: calc(100% - 50px);
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
||||
+53
-17
@@ -3,34 +3,70 @@
|
||||
<head>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<title>System Settings</title>
|
||||
<style>
|
||||
.tab-bar { display: flex; border-bottom: 2px solid #226; margin-bottom: 0; margin-left: 16%; padding: 1px 16px; padding-bottom: 0; }
|
||||
.tab-btn { padding: 10px 20px; background-color: #ddf; border: none; cursor: pointer; font-size: 1em; border-radius: 8px 8px 0 0; margin-right: 4px; }
|
||||
.tab-btn:hover { background-color: #aaf; }
|
||||
.tab-btn.active { background-color: #aaf; font-weight: bold; border-bottom: 2px solid #aaf; margin-bottom: -2px; }
|
||||
.tab-content { display: none; }
|
||||
.tab-content.active { display: block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="tab-bar">
|
||||
<button class="tab-btn active" onclick="openTab(event, 'system-tab')">System</button>
|
||||
<button class="tab-btn" onclick="openTab(event, 'advanced-tab')">Advanced</button>
|
||||
</div>
|
||||
<nav id="sidebar"></nav>
|
||||
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
||||
<div id="ports"></div>
|
||||
<h1>System Settings</h1>
|
||||
<div class="row">
|
||||
<div class="lcol"> <label for="ip">IP address:</label></div>
|
||||
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||
|
||||
<div id="system-tab" class="tab-content active">
|
||||
<h1>System Settings</h1>
|
||||
<div class="row">
|
||||
<div class="lcol"> <label for="ip">IP address:</label></div>
|
||||
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="lcol"> <label for="netmask">Netmask:</label></div>
|
||||
<div class="rcol"><input id="netmask" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
||||
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||
</div>
|
||||
<br/>
|
||||
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
||||
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
||||
<br/>
|
||||
Save all current settings to Flash:<br/>
|
||||
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="lcol"> <label for="netmask">Netmask:</label></div>
|
||||
<div class="rcol"><input id="netmask" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||
|
||||
<div id="advanced-tab" class="tab-content">
|
||||
<h1>Advanced Settings</h1>
|
||||
<div class="lcol"> <label for="config_display">Startup configuration:</label></div>
|
||||
<textarea id="config_display" rows="8" cols="60"></textarea>
|
||||
<br/><br/>
|
||||
Be careful when saving the directly edited startup configuration, you can lock yourself out:<br/>
|
||||
<input style="width:40%;" class="action" id="clear_config" onclick="clearConfig();" type="button" value="Clear Startup Config">
|
||||
<br/>
|
||||
<input style="width:40%;" class="action" id="flash_startup_sub" onclick="flashStartupSave();" type="button" value="Save Startup Settings to Flash">
|
||||
<br/>
|
||||
<input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
||||
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||
</div>
|
||||
<br/><br/>
|
||||
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
||||
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
||||
<br/><br/>
|
||||
Save all current settings to Flash:<br/>
|
||||
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
||||
|
||||
</div>
|
||||
<script src="/config.js"></script>
|
||||
<script src="/system.js"></script>
|
||||
<script src="/navigation.js"></script>
|
||||
<script>
|
||||
function openTab(evt, tabId) {
|
||||
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
||||
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById(tabId).classList.add('active');
|
||||
evt.currentTarget.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+55
-1
@@ -42,6 +42,7 @@ async function sendConfig(c) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function flashSave() {
|
||||
fetchConfig().then((s) => {
|
||||
parseConf(s);
|
||||
@@ -53,6 +54,39 @@ async function flashSave() {
|
||||
sendConfig(body);
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
fetchIP();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async function flashStartupSave() {
|
||||
var configContent = document.getElementById("config_display").value;
|
||||
console.log("CONFIGURATION to save: ", configContent);
|
||||
sendConfig(configContent);
|
||||
// Clear the command log 1 second after initiating the config save
|
||||
setTimeout(() => {
|
||||
fetch('/cmd_log_clear', { method: 'GET' })
|
||||
.then(response => console.log('Command log cleared', response))
|
||||
.catch(err => console.error('Error clearing command log:', err));
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function clearConfig() {
|
||||
document.getElementById("config_display").value = "";
|
||||
|
||||
// Validate and populate with current IP settings
|
||||
for (let i=0; i<3; i++) {
|
||||
if (!checkIp(document.getElementById(ips[i]).value))
|
||||
return;
|
||||
}
|
||||
|
||||
var configLines = "";
|
||||
for (let i=0; i<3; i++){
|
||||
var cmd = ips[i]+' '+document.getElementById(ips[i]).value;
|
||||
configLines += cmd + "\n";
|
||||
}
|
||||
|
||||
document.getElementById("config_display").value = configLines;
|
||||
}
|
||||
|
||||
function fetchIP() {
|
||||
@@ -65,12 +99,32 @@ function fetchIP() {
|
||||
document.getElementById("netmask").value=s.ip_netmask;
|
||||
document.getElementById("gw").value=s.ip_gateway;
|
||||
clearInterval(systemInterval);
|
||||
// Fetch and populate the config textbox
|
||||
fetchConfig().then((configText) => {
|
||||
let fullConfig = configText;
|
||||
// Fetch and append cmd_log
|
||||
//return fetchCmdLog().then((cmdLogText) => {
|
||||
// if (cmdLogText) {
|
||||
// fullConfig = fullConfig + cmdLogText;
|
||||
// }
|
||||
document.getElementById("config_display").value = fullConfig;
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", `/information.json`, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function resetSwitch() {
|
||||
if (!confirm('Are you sure you want to reset the switch?')) {
|
||||
return;
|
||||
}
|
||||
fetch('/reset', { method: 'GET' }).catch(() => {});
|
||||
setTimeout(() => {
|
||||
alert('Switch is resetting. Please wait and refresh the page.');
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
systemInterval = setInterval(fetchIP, 1000);
|
||||
});
|
||||
|
||||
@@ -301,6 +301,8 @@ uint8_t stream_upload(uint16_t bptr)
|
||||
print_string("Checksum incorrect!");
|
||||
}
|
||||
print_string("\nUpload to flash done, will reset!\n");
|
||||
// close connection to avoid retries by browser
|
||||
uip_close();
|
||||
reset_chip();
|
||||
}
|
||||
// Make sure there is a 0 at the end of the uploaded data
|
||||
@@ -310,6 +312,9 @@ uint8_t stream_upload(uint16_t bptr)
|
||||
flash_write_bytes(flash_buf);
|
||||
if (bptr >= uip_len)
|
||||
return 0;
|
||||
if(!verify_crc)
|
||||
//ugly hack to signal connection finished after config upload.
|
||||
uip_close();
|
||||
return 1;
|
||||
}
|
||||
if (p[bptr] == boundary[bindex]) {
|
||||
@@ -593,6 +598,13 @@ void httpd_appcall(void)
|
||||
send_config();
|
||||
} else if (is_word(q, "/cmd_log")) {
|
||||
send_cmd_log();
|
||||
} else if (is_word(q, "/cmd_log_clear")) {
|
||||
clear_command_history();
|
||||
send_mtu(); // dummy response
|
||||
} else if (is_word(q, "/reset")) {
|
||||
uip_close();
|
||||
delay(1000); //wait for the close packet to be sent, otherwise the browser will retry
|
||||
reset_chip();
|
||||
} else {
|
||||
send_not_found();
|
||||
}
|
||||
|
||||
+35
-16
@@ -676,26 +676,45 @@ void send_status(void)
|
||||
void send_config(void)
|
||||
{
|
||||
dbg_string("send_config called\n");
|
||||
__xdata uint32_t pos = CONFIG_START; // 70000 , 6c000 / 0xc000 = 9
|
||||
|
||||
extern __xdata uint16_t len_left = CONFIG_LEN;
|
||||
__xdata uint32_t pos = CONFIG_START;
|
||||
__xdata uint16_t valid_len = 0;
|
||||
__xdata uint16_t len_left = CONFIG_LEN;
|
||||
__xdata uint8_t flash_buf[256];
|
||||
|
||||
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
||||
while (read_flash((CONFIG_START-CODE0_SIZE) / CODE_BANK_SIZE + 1,
|
||||
(__code uint8_t *) (((CONFIG_START + len_left - CODE0_SIZE) % CODE_BANK_SIZE) + CODE0_SIZE + len_left)) == 0xff) {
|
||||
dbg_short(len_left);
|
||||
len_left--;
|
||||
}
|
||||
len_left++;
|
||||
|
||||
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
||||
cont_len = len_left - (TCP_OUTBUF_SIZE - slen);
|
||||
len_left = TCP_OUTBUF_SIZE - slen;
|
||||
cont_addr = len_left;
|
||||
|
||||
// Scan through config to find the end of valid data (null terminator)
|
||||
do {
|
||||
flash_region.addr = pos;
|
||||
flash_region.len = (len_left > 256) ? 256 : len_left;
|
||||
flash_read_bulk(flash_buf);
|
||||
|
||||
// Look for null terminator in this chunk
|
||||
for (uint16_t i = 0; i < flash_region.len; i++) {
|
||||
if (flash_buf[i] == 0) {
|
||||
// Found end of valid data
|
||||
valid_len += i;
|
||||
goto found_end;
|
||||
}
|
||||
}
|
||||
|
||||
valid_len += flash_region.len;
|
||||
len_left -= flash_region.len;
|
||||
pos += flash_region.len;
|
||||
} while (len_left > 0);
|
||||
|
||||
found_end:
|
||||
// Now send the valid data
|
||||
if (valid_len > (TCP_OUTBUF_SIZE - slen)) {
|
||||
cont_len = valid_len - (TCP_OUTBUF_SIZE - slen);
|
||||
valid_len = TCP_OUTBUF_SIZE - slen;
|
||||
cont_addr = valid_len;
|
||||
}
|
||||
|
||||
flash_region.addr = CONFIG_START;
|
||||
flash_region.len = len_left;
|
||||
flash_region.len = valid_len;
|
||||
flash_read_bulk(outbuf + slen);
|
||||
slen += len_left;
|
||||
slen += valid_len;
|
||||
}
|
||||
|
||||
void send_cmd_log(void)
|
||||
|
||||
Reference in New Issue
Block a user