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:
@@ -1043,7 +1043,12 @@ void execute_config(void) __banked
|
|||||||
config_done:
|
config_done:
|
||||||
// Start saving commands to cmd_history
|
// Start saving commands to cmd_history
|
||||||
save_cmd = 1;
|
save_cmd = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_command_history(void) __banked
|
||||||
|
{
|
||||||
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
|
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
|
||||||
cmd_history[cmd_history_ptr] = 0;
|
cmd_history[cmd_history_ptr] = 0;
|
||||||
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 cmd_parser(void) __banked;
|
||||||
void execute_config(void) __banked;
|
void execute_config(void) __banked;
|
||||||
void print_sw_version(void) __banked;
|
void print_sw_version(void) __banked;
|
||||||
|
void clear_command_history(void) __banked;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../config.txt
|
|
||||||
+2
-1
@@ -49,7 +49,8 @@ async function fetchCmdLog() {
|
|||||||
console.log("CMD-Log: ", response);
|
console.log("CMD-Log: ", response);
|
||||||
const t = await response.text();
|
const t = await response.text();
|
||||||
return t;
|
return t;
|
||||||
} catch(error) {
|
} catch(err) {
|
||||||
console.error("Error: ", err);
|
console.error("Error: ", err);
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -6,8 +6,9 @@ ul {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 12%;
|
width: 12%;
|
||||||
height: 100%;
|
height: calc(100% - 50px);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
top: 50px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+53
-17
@@ -3,34 +3,70 @@
|
|||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<title>System Settings</title>
|
<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>
|
</head>
|
||||||
<body>
|
<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>
|
<nav id="sidebar"></nav>
|
||||||
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
||||||
<div id="ports"></div>
|
<div id="ports"></div>
|
||||||
<h1>System Settings</h1>
|
|
||||||
<div class="row">
|
<div id="system-tab" class="tab-content active">
|
||||||
<div class="lcol"> <label for="ip">IP address:</label></div>
|
<h1>System Settings</h1>
|
||||||
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
<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>
|
||||||
<div class="row">
|
|
||||||
<div class="lcol"> <label for="netmask">Netmask:</label></div>
|
<div id="advanced-tab" class="tab-content">
|
||||||
<div class="rcol"><input id="netmask" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
<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>
|
||||||
<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>
|
</div>
|
||||||
<script src="/config.js"></script>
|
<script src="/config.js"></script>
|
||||||
<script src="/system.js"></script>
|
<script src="/system.js"></script>
|
||||||
<script src="/navigation.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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+55
-1
@@ -42,6 +42,7 @@ async function sendConfig(c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function flashSave() {
|
async function flashSave() {
|
||||||
fetchConfig().then((s) => {
|
fetchConfig().then((s) => {
|
||||||
parseConf(s);
|
parseConf(s);
|
||||||
@@ -53,6 +54,39 @@ async function flashSave() {
|
|||||||
sendConfig(body);
|
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() {
|
function fetchIP() {
|
||||||
@@ -65,12 +99,32 @@ function fetchIP() {
|
|||||||
document.getElementById("netmask").value=s.ip_netmask;
|
document.getElementById("netmask").value=s.ip_netmask;
|
||||||
document.getElementById("gw").value=s.ip_gateway;
|
document.getElementById("gw").value=s.ip_gateway;
|
||||||
clearInterval(systemInterval);
|
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.open("GET", `/information.json`, true);
|
||||||
xhttp.send();
|
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() {
|
window.addEventListener("load", function() {
|
||||||
systemInterval = setInterval(fetchIP, 1000);
|
systemInterval = setInterval(fetchIP, 1000);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -301,6 +301,8 @@ uint8_t stream_upload(uint16_t bptr)
|
|||||||
print_string("Checksum incorrect!");
|
print_string("Checksum incorrect!");
|
||||||
}
|
}
|
||||||
print_string("\nUpload to flash done, will reset!\n");
|
print_string("\nUpload to flash done, will reset!\n");
|
||||||
|
// close connection to avoid retries by browser
|
||||||
|
uip_close();
|
||||||
reset_chip();
|
reset_chip();
|
||||||
}
|
}
|
||||||
// Make sure there is a 0 at the end of the uploaded data
|
// 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);
|
flash_write_bytes(flash_buf);
|
||||||
if (bptr >= uip_len)
|
if (bptr >= uip_len)
|
||||||
return 0;
|
return 0;
|
||||||
|
if(!verify_crc)
|
||||||
|
//ugly hack to signal connection finished after config upload.
|
||||||
|
uip_close();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (p[bptr] == boundary[bindex]) {
|
if (p[bptr] == boundary[bindex]) {
|
||||||
@@ -593,6 +598,13 @@ void httpd_appcall(void)
|
|||||||
send_config();
|
send_config();
|
||||||
} else if (is_word(q, "/cmd_log")) {
|
} else if (is_word(q, "/cmd_log")) {
|
||||||
send_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 {
|
} else {
|
||||||
send_not_found();
|
send_not_found();
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-14
@@ -676,26 +676,45 @@ void send_status(void)
|
|||||||
void send_config(void)
|
void send_config(void)
|
||||||
{
|
{
|
||||||
dbg_string("send_config called\n");
|
dbg_string("send_config called\n");
|
||||||
__xdata uint32_t pos = CONFIG_START; // 70000 , 6c000 / 0xc000 = 9
|
__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];
|
||||||
|
|
||||||
extern __xdata uint16_t len_left = CONFIG_LEN;
|
|
||||||
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
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)) {
|
// Scan through config to find the end of valid data (null terminator)
|
||||||
cont_len = len_left - (TCP_OUTBUF_SIZE - slen);
|
do {
|
||||||
len_left = TCP_OUTBUF_SIZE - slen;
|
flash_region.addr = pos;
|
||||||
cont_addr = len_left;
|
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.addr = CONFIG_START;
|
||||||
flash_region.len = len_left;
|
flash_region.len = valid_len;
|
||||||
flash_read_bulk(outbuf + slen);
|
flash_read_bulk(outbuf + slen);
|
||||||
slen += len_left;
|
slen += valid_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_cmd_log(void)
|
void send_cmd_log(void)
|
||||||
|
|||||||
Reference in New Issue
Block a user