From 884bc18a619afbef8bd2e0b8d325d3724d0a29a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 5 Oct 2025 15:47:14 +0200 Subject: [PATCH] Remove flash_read_bulk(), refactor website and execute_config(). flash_read_bulk() is kind of a printf function. But did not work as well. flash_read_bulk() was used in the http generation so this needed to be changed as well. For the website we decided that we are going to use CSR(Client Side Rendering). So every HTML and JS files are now static. Variables are fetched via json calls and output is render on the client side. Also usefull for the future when we want a REST like API. execute_config() was also using flash_read_bulk(). This have been replaced with flash_read_bulk() and parsing the flash_buf buffer. --- cmd_parser.c | 56 +++++++++++++++++++---------- html/index.html | 47 +++++++++++++++---------- html/main_info.js | 22 ++++++++++++ httpd/httpd.c | 50 +++++--------------------- httpd/page_impl.c | 25 ++++++------- httpd/page_impl.h | 1 + rtl837x_flash.c | 89 +++-------------------------------------------- rtl837x_flash.h | 1 - tools/fileadder.c | 6 ++-- tools/httpd_sim.c | 12 +++++++ 10 files changed, 132 insertions(+), 177 deletions(-) create mode 100644 html/main_info.js diff --git a/cmd_parser.c b/cmd_parser.c index ee06b95..1f9ad4c 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -628,24 +628,44 @@ void cmd_parser(void) __banked } } +#define FLASH_READ_BURST_SIZE 0x100; void execute_config(void) __banked { - __xdata uint32_t pos = CONFIG_START; - __xdata uint16_t len_left = CONFIG_LEN; - do { - flash_addr = pos; - flash_find_mark("\n", len_left); - if (mpos != 0xffff) { - __xdata uint16_t len = len_left - mpos; - flash_addr = pos; - flash_read_bulk(&cmd_buffer[0], len > SBUF_SIZE ? SBUF_SIZE : len); - cmd_buffer[len > SBUF_SIZE ? SBUF_SIZE : len] = '\0'; - len++; - pos += len; - len_left -= len; - if (len && !cmd_tokenize()) - cmd_parser(); - } - } while (mpos != 0xffff); -} + memcpyc(flash_buf, "test", 5); + print_string_x(flash_buf); + __xdata uint32_t pos = CONFIG_START; + __xdata uint16_t len_left = CONFIG_LEN; + do { + flash_region.addr = pos; + flash_region.len = FLASH_READ_BURST_SIZE; + write_char('-'); print_long(flash_region.addr); write_char(':'); print_short(flash_region.len); write_char('\n'); + + flash_read_bulk(flash_buf); + + uint8_t cfg_idx = 0; + uint8_t c = 0; + do { + for (uint8_t cmd_idx = 0; cmd_idx < (SBUF_SIZE - 1); cmd_idx++) { + c = flash_buf[cfg_idx++]; + print_byte(c); + + if (c == 0 || c == '\n') { + cmd_buffer[cmd_idx] = '\0'; + write_char('\n'); write_char('#'); print_short(cfg_idx); write_char('-'); print_short(cmd_idx); write_char('-'); print_string_x(cmd_buffer); write_char('\n'); + if (cmd_idx && !cmd_tokenize()) + cmd_parser(); + if (c == 0) + return; + break; + } + + cmd_buffer[cmd_idx] = c; + } + write_char('N'); + } while(cfg_idx); + + len_left -= FLASH_READ_BURST_SIZE; + pos += FLASH_READ_BURST_SIZE; + } while(len_left); +} diff --git a/html/index.html b/html/index.html index 485e607..f9f94c6 100644 --- a/html/index.html +++ b/html/index.html @@ -1,24 +1,35 @@ - - - - - FreeSwitchOS Main Page - - - -
+ + + + + + + FreeSwitchOS Main Page + + + + +

Switch Configuration

- - - #{html_index} +
Setting
+ + + + +
Settings
-
- +
+ + diff --git a/html/main_info.js b/html/main_info.js new file mode 100644 index 0000000..1d9d7ee --- /dev/null +++ b/html/main_info.js @@ -0,0 +1,22 @@ +document.addEventListener("DOMContentLoaded", function () { + fetch('/information.json') + .then(response => response.json()) + .then(data => { + const tableBody = document.getElementById('infoTable').querySelector('tbody'); + + // Create table rows + for (const [key, value] of Object.entries(data)) { + const row = document.createElement('tr'); + const cellKey = document.createElement('td'); + const cellValue = document.createElement('td'); + + cellKey.textContent = key; + cellValue.textContent = value; + + row.appendChild(cellKey); + row.appendChild(cellValue); + tableBody.appendChild(row); + } + }) + .catch(error => console.error('Error fetching the data:', error)); +}); diff --git a/httpd/httpd.c b/httpd/httpd.c index 434ec2f..cf396a3 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -15,7 +15,6 @@ #pragma codeseg BANK1 extern __code struct f_data f_data[]; -extern __code fcall_ptr f_calls[]; extern __code char * __code mime_strings[]; extern __xdata struct flash_region_t flash_region; @@ -407,6 +406,8 @@ void httpd_appcall(void) print_string("Not file entry\n"); if (!strcmp(q, "/status.json")) { send_status(); + } else if (!strcmp(q, "/information.json")) { + send_basic_info(); } else if (!strcmp(q, "/vlan.json")) { parse_short(q + 15); send_vlan(short_parsed); @@ -419,47 +420,14 @@ void httpd_appcall(void) print_string("Have entry\n"); slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: "); slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]); - slen += strtox(outbuf + slen, "\r\nCache-Control: max-age=2592000"); - slen += strtox(outbuf + slen, "\r\n\r\n"); + slen += strtox(outbuf + slen, "\r\nCache-Control: max-age=2592000\r\n\r\n"); len_left = f_data[entry].len; - if (f_data[entry].mime == mime_HTML) { - print_string("MIME is html len is "); print_short(len_left); write_char('\n'); - mpos = 0; - flash_addr = f_data[entry].start; - flash_find_mark("#{", len_left); - print_string("mpos: "); print_short(mpos); write_char('\n'); - while (mpos != 0xffff) { - print_string("Entry-len:"); print_short(len_left); write_char('\n'); - mpos = len_left - mpos; - print_string("l/pos: "); print_short(mpos); write_char('\n'); - flash_addr = f_data[entry].start + f_data[entry].len - len_left; - flash_read_bulk(outbuf + slen, mpos + CMARK_S); // call marker is e.g. #{001} - slen += mpos; - write_char('@'); write_char(outbuf[slen + 2]); write_char(outbuf[slen + 3]); write_char(outbuf[slen + 4]); - fcall_ptr ptr = f_calls[(outbuf[slen + 2] - '0') * 100 + (outbuf[slen + 3]-'0') * 10 + outbuf[slen + 4] - '0']; - slen -= CMARK_S; // Overwrite marker with generated html - print_string("Call location is: "); print_short((uint16_t)ptr); write_char('\n'); -// f_calls[outbuf[slen + 2] * 100 + outbuf[slen + 3] * 10 + outbuf[slen + 4]](); - ptr(); - print_string("call done\n"); - mpos += CMARK_S; - len_left -= mpos; - flash_region.addr = f_data[entry].start + mpos; - flash_addr = f_data[entry].start + f_data[entry].len - len_left; - flash_find_mark("#{"); - print_string("mpos now: "); print_short(mpos); write_char('\n'); - } - print_string("At end mpos: "); print_short(mpos); write_char('\n'); - flash_addr = f_data[entry].start + f_data[entry].len - len_left; - flash_read_bulk(outbuf + slen, len_left); - slen += len_left; - } else { - print_string("MIME: "); print_string(mime_strings[f_data[entry].mime]); write_char('\n'); - flash_region.addr = f_data[entry].start; - flash_region.len = len_left; - flash_read_bulk(outbuf + slen, len_left); - slen += len_left; - } + + print_string("MIME: "); print_string(mime_strings[f_data[entry].mime]); write_char('\n'); + flash_region.addr = f_data[entry].start; + flash_region.len = len_left; + flash_read_bulk(outbuf + slen); + slen += len_left; } do_send: print_string("slen: "); print_short(slen); write_char('\n'); diff --git a/httpd/page_impl.c b/httpd/page_impl.c index 89ae166..3a66242 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -27,6 +27,7 @@ extern __xdata uint8_t isRTL8373; extern __xdata uint8_t sfp_pins_last; extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE]; +__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"; /* Convert only the lower nibble to ascii HEX char. For convenience the upper nibble is masked out. @@ -133,40 +134,40 @@ void reg_to_html(register uint16_t reg) sfr_data_to_html(); } - -uint16_t html_index(void) +void send_basic_info(void) { - print_string("html_index called\n"); - slen += strtox(outbuf + slen, "IP Address"); + slen = strtox(outbuf, HTTP_RESPONCE_JSON); + print_string("send_basic_info called\n"); + slen += strtox(outbuf + slen, "{\"ip_address\":\""); itoa_html(uip_hostaddr[0]); char_to_html('.'); itoa_html(uip_hostaddr[0] >> 8); char_to_html('.'); itoa_html(uip_hostaddr[1]); char_to_html('.'); itoa_html(uip_hostaddr[1] >> 8); - slen += strtox(outbuf + slen, "Gateway"); + slen += strtox(outbuf + slen, "\",\"ip_gateway\":\""); itoa_html(uip_draddr[0]); char_to_html('.'); itoa_html(uip_draddr[0] >> 8); char_to_html('.'); itoa_html(uip_draddr[1]); char_to_html('.'); itoa_html(uip_draddr[1] >> 8); - slen += strtox(outbuf + slen, "Netmask"); + slen += strtox(outbuf + slen, "\",\"ip_netmask\":\""); itoa_html(uip_netmask[0]); char_to_html('.'); itoa_html(uip_netmask[0] >> 8); char_to_html('.'); itoa_html(uip_netmask[1]); char_to_html('.'); itoa_html(uip_netmask[1] >> 8); - slen += strtox(outbuf + slen, "MAC Address"); + slen += strtox(outbuf + slen, "\",\"mac_address\":\""); byte_to_html(uip_ethaddr.addr[0]); char_to_html(':'); byte_to_html(uip_ethaddr.addr[1]); char_to_html(':'); byte_to_html(uip_ethaddr.addr[2]); char_to_html(':'); byte_to_html(uip_ethaddr.addr[3]); char_to_html(':'); byte_to_html(uip_ethaddr.addr[4]); char_to_html(':'); byte_to_html(uip_ethaddr.addr[5]); - slen += strtox(outbuf + slen, ""); - return 0; + slen += strtox(outbuf + slen, "\",\"sw_ver\":\"v0.1-ge4c48586\",\"hw_ver\":\"SWGT024-V2.0\"}"); + // slen += strtox(outbuf + slen, "\"}"); } void send_vlan(__xdata uint16_t vlan) { - slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"); + slen = strtox(outbuf, HTTP_RESPONCE_JSON); print_string("sending VLAN\n"); //{"members":"0x00060011"} slen += strtox(outbuf + slen, "{\"members\":\"0x"); @@ -187,7 +188,7 @@ void send_vlan(__xdata uint16_t vlan) void send_counters(char port) { print_string("send_counters called: "); print_byte(port); write_char('\n'); - slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"); + slen = strtox(outbuf, HTTP_RESPONCE_JSON); print_string("sending counters\n"); port--; @@ -209,7 +210,7 @@ void send_counters(char port) void send_status(void) { - slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"); + slen = strtox(outbuf, HTTP_RESPONCE_JSON); print_string("sending status\n"); char_to_html('['); diff --git a/httpd/page_impl.h b/httpd/page_impl.h index c643140..16f776e 100644 --- a/httpd/page_impl.h +++ b/httpd/page_impl.h @@ -4,5 +4,6 @@ void send_counters(char port); void send_status(void); void send_vlan(register uint16_t vlan); +void send_basic_info(void); #endif diff --git a/rtl837x_flash.c b/rtl837x_flash.c index 2530452..c4bf5af 100644 --- a/rtl837x_flash.c +++ b/rtl837x_flash.c @@ -16,6 +16,7 @@ __xdata struct flash_region_t flash_region; // For the flash commands, see e.g. Windbond W25Q32JV datasheet #define CMD_WRITE_STATUS 0x01 #define CMD_PAGE_PROGRAM 0x02 +#define CMD_READ 0x03 #define CMD_WRITE_ENABLE 0x06 #define CMD_FREAD 0x0b #define CMD_SECTOR_ERASE 0x20 @@ -248,9 +249,11 @@ void flash_read_bulk(__xdata uint8_t *dst) SFR_FLASH_DUMMYCYCLES = 4; } else { SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = CMD_FREAD; // Fast read - SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read? + SFR_FLASH_CMD_R = CMD_READ; + SFR_FLASH_DUMMYCYCLES = 0; } + + // Read 4 bytes while (1) { SFR_FLASH_ADDR16 = flash_region.addr >> 16; @@ -280,88 +283,6 @@ void flash_read_bulk(__xdata uint8_t *dst) } -void flash_find_mark(__code uint8_t *mark, __xdata uint16_t len) -{ - __xdata uint16_t status; - do { - status = flash_read_status(); - } while (status & 0x1); - - // Set fast read mode - if (dio_enabled) { - SFR_FLASH_MODEB = 0x18; - SFR_FLASH_CMD_R = CMD_FREAD_DIO; - SFR_FLASH_DUMMYCYCLES = 4; - } else { - SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = CMD_FREAD; // Fast read - SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read? - } - - __xdata uint8_t i = 0; - __xdata uint8_t l = 0; - __xdata uint8_t k; - - // Calculate the length - while (mark[i++]) - l++; - - if (l >= 12) { - mpos = 0xffff; - return; - } - - i = 0; - SFR_FLASH_TCONF = 4; - while (len) { - SFR_FLASH_ADDR16 = flash_addr >> 16; - SFR_FLASH_ADDR8 = flash_addr >> 8; - SFR_FLASH_ADDR0 = flash_addr; - flash_addr += 4; - - SFR_FLASH_EXEC_GO = 1; - while(SFR_FLASH_EXEC_BUSY); - markbuf[i++] = SFR_FLASH_DATA0; - if (len != 1) { - markbuf[i++] = SFR_FLASH_DATA8; - if (len != 2) { - markbuf[i++] = SFR_FLASH_DATA16; - if (len != 3) { - markbuf[i++] = SFR_FLASH_DATA24; - } else { - markbuf[i++] = 0; - } - } else { - markbuf[i++] = 0; - } - } else { - markbuf[i++] = 0; - } - - len -= len >= 4? 4 : len; - uint8_t j = 0; - k = (i + 13 - l) & 0xf; - i &= 0xf; - while (mark[j] && (k != ((i) & 0xf))) { - if (mark[j] != markbuf[k]) { - k = k - j + 17; - j = 0; - } else { - k++; - j++; - } - k &= 0xf; - } - if (!mark[j]) { - mpos = len + l + ((4 - ( k & 0x3)) & 0x3); - return; - } - } - mpos = 0xffff; - return; -} - - void flash_read_security(uint32_t addr, uint8_t len) { while (flash_read_status() & 0x1); diff --git a/rtl837x_flash.h b/rtl837x_flash.h index 43a1948..fb0ada6 100644 --- a/rtl837x_flash.h +++ b/rtl837x_flash.h @@ -10,5 +10,4 @@ void flash_read_security(uint32_t addr, uint8_t len); void flash_sector_erase(uint32_t addr); void flash_read_bulk(__xdata uint8_t *dst); void flash_write_bytes(__xdata uint8_t *ptr); -void flash_find_mark( __code uint8_t *mark, __xdata uint16_t len); #endif diff --git a/tools/fileadder.c b/tools/fileadder.c index 84a2865..7b739d8 100644 --- a/tools/fileadder.c +++ b/tools/fileadder.c @@ -270,7 +270,7 @@ int main(int argc, char **argv) defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "typedef enum mime_type_e {\n mime_HTML = 0,\n mime_SVG,\n mime_ICO,\n mime_PNG,\n mime_JS,\n mime_CSS,\n mime_TXT\n} mime_type_t;\n\n"); defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "struct f_data {\n __code char *file;\n uint32_t start;\n uint16_t len;\n mime_type_t mime;\n};\n\n"); - defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "typedef uint16_t (* fcall_ptr)(void);\n\n"); + // defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "typedef uint16_t (* fcall_ptr)(void);\n\n"); ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "// This file is automatically generated, do not edit!\n\n"); if (arguments.prefix) @@ -280,7 +280,7 @@ int main(int argc, char **argv) ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, " __code char * __code mime_strings[] = {\n \"text/html\",\n \"image/svg+xml\",\n" " \"image/svg+xml\",\n \"image/png\",\n \"text/javascript\",\n \"text/css\",\n \"text/plain\"};\n\n"); ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "__code struct f_data f_data[] = {\n"); - fbuf_p += snprintf(&fbuf[fbuf_p], DEF_SIZE - fbuf_p, "\n__code fcall_ptr f_calls[] = {\n"); + // fbuf_p += snprintf(&fbuf[fbuf_p], DEF_SIZE - fbuf_p, "\n__code fcall_ptr f_calls[] = {\n"); // Now that the beginning of the buffer is filled with out image, optionally resize the image if (filesize) @@ -335,7 +335,7 @@ int main(int argc, char **argv) } ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, " {0, 0, 0}\n};\n"); - fbuf_p += snprintf(&fbuf[fbuf_p], DEF_SIZE - fbuf_p, "};\n"); + // fbuf_p += snprintf(&fbuf[fbuf_p], DEF_SIZE - fbuf_p, "};\n"); defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#endif\n"); if (filesize) { diff --git a/tools/httpd_sim.c b/tools/httpd_sim.c index 2a4f8d1..9c54444 100644 --- a/tools/httpd_sim.c +++ b/tools/httpd_sim.c @@ -67,6 +67,13 @@ char *getMime(const char *name) return "text/plain"; } +void send_basic_info(int socket) +{ + char *response = "HTTP/1.1 200 OK\r\n" + "Content-Type: application/json; charset=UTF-8\r\n\r\n" + "{\"ip_address\":\"192.168.10.247\",\"ip_gateway\":\"192.168.2.22\",\"ip_netmask\":\"255.255.255.0\",\"mac_address\":\"1c:2a:a3:23:00:02\",\"sw_ver\":\"v0.1-ge4c48586\",\"hw_ver\":\"SWGT024-V2.0\"}"; + write(socket, response, strlen(response)); +} void send_vlan(int s, int vlan) { @@ -249,6 +256,11 @@ void launch(struct Server *server) send_status(new_socket); goto done; } + if (!strncmp(&buffer[4], "/information.json", 12)) { + printf("Status request\n"); + send_basic_info(new_socket); + goto done; + } if (!strncmp(&buffer[4], "/vlan.json?vid=", 15)) { int vlan = atoi(&buffer[19]); printf("VLAN request for %d\n", vlan);