mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Add support for dynamically regenerated web-pages. Limit to 1 concurrent TCP connection for now.
This commit is contained in:
@@ -10,10 +10,15 @@ SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
|||||||
|
|
||||||
all: $(SUBDIRS) rtlplayground.bin
|
all: $(SUBDIRS) rtlplayground.bin
|
||||||
|
|
||||||
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c
|
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c
|
||||||
OBJS = ${SRCS:.c=.rel}
|
OBJS = ${SRCS:.c=.rel}
|
||||||
OBJS += uip/timer.rel uip/uip-fw.rel uip/uip-neighbor.rel uip/uip-split.rel uip/uip.rel uip/uip_arp.rel uip/uiplib.rel httpd/httpd.rel
|
OBJS += uip/timer.rel uip/uip-fw.rel uip/uip-neighbor.rel uip/uip-split.rel uip/uip.rel uip/uip_arp.rel uip/uiplib.rel httpd/httpd.rel httpd/page_impl.rel
|
||||||
|
|
||||||
|
html_data.c html_data.h: html tools
|
||||||
|
tools/fileadder -a -s -b BANK1 -d html -p html_data
|
||||||
|
|
||||||
|
httpd: html_data.h
|
||||||
|
$(MAKE) -C $@
|
||||||
|
|
||||||
$(SUBDIRS):
|
$(SUBDIRS):
|
||||||
$(MAKE) -C $@
|
$(MAKE) -C $@
|
||||||
@@ -21,6 +26,7 @@ $(SUBDIRS):
|
|||||||
clean:
|
clean:
|
||||||
-make -C uip clean
|
-make -C uip clean
|
||||||
-make -C httpd clean
|
-make -C httpd clean
|
||||||
|
-rm html_data.c html_data.c
|
||||||
if [ -e rtlplayground.bin ]; then rm rtlplayground.bin; fi
|
if [ -e rtlplayground.bin ]; then rm rtlplayground.bin; fi
|
||||||
if [ -e rtlplayground.asm ]; then rm rtlplayground.asm; fi
|
if [ -e rtlplayground.asm ]; then rm rtlplayground.asm; fi
|
||||||
-rm *.ihx *.lk *.lst *.map *.mem *.rel *.rst *.sym *.bin
|
-rm *.ihx *.lk *.lst *.map *.mem *.rel *.rst *.sym *.bin
|
||||||
@@ -45,6 +51,8 @@ rtlplayground.ihx: crtstart.rel $(OBJS)
|
|||||||
cat $< >> $@
|
cat $< >> $@
|
||||||
truncate --size=16K $@
|
truncate --size=16K $@
|
||||||
dd if=$< skip=80 bs=1024 >>$@
|
dd if=$< skip=80 bs=1024 >>$@
|
||||||
|
tools/fileadder -s -d config.txt $@
|
||||||
|
tools/fileadder -a -s -d html -p html_data $@
|
||||||
|
|
||||||
.PHONY: clean all $(SUBDIRS)
|
.PHONY: clean all $(SUBDIRS)
|
||||||
.PRECIOUS: %.rel %.ihx .img
|
.PRECIOUS: %.rel %.ihx .img
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ CC_FLAGS = -mmcs51 -I. -I../uip
|
|||||||
ASM = sdas8051
|
ASM = sdas8051
|
||||||
AFLAGS= -plosgff
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
SRCS = httpd.c
|
SRCS = httpd.c page_impl.c
|
||||||
OBJS = ${SRCS:.c=.rel}
|
OBJS = ${SRCS:.c=.rel}
|
||||||
|
|
||||||
all: $(OBJS)
|
all: $(OBJS)
|
||||||
|
|||||||
+136
-21
@@ -1,23 +1,29 @@
|
|||||||
|
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
#include "../rtl837x_common.h"
|
#include "../rtl837x_common.h"
|
||||||
|
#include "../rtl837x_flash.h"
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
|
#include "../html_data.h"
|
||||||
|
|
||||||
|
#define CMARK_S 6
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
|
|
||||||
static __code uint8_t page_main[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n"
|
extern __code struct f_data f_data[];
|
||||||
"\r\n<!DOCTYPE html>"
|
extern __code fcall_ptr f_calls[];
|
||||||
"<html>"
|
|
||||||
" <head>"
|
|
||||||
" <title>FreeSwitchOS Main Page</title>"
|
|
||||||
" </head>"
|
|
||||||
" <body>"
|
|
||||||
" <h1>Port configuration:</h1>"
|
|
||||||
" <p>TBD</p>"
|
|
||||||
" </body>"
|
|
||||||
"</html>\r\n";
|
|
||||||
|
|
||||||
__xdata uint8_t outbuf[2048];
|
__xdata uint8_t outbuf[2048];
|
||||||
|
__xdata uint8_t entry;
|
||||||
|
__xdata uint16_t slen;
|
||||||
|
__xdata uint16_t o_idx;
|
||||||
|
__xdata uint16_t mpos;
|
||||||
|
__xdata uint16_t len_left;
|
||||||
|
|
||||||
|
#define TSTATE_NONE 0
|
||||||
|
#define TSTATE_TX 1
|
||||||
|
#define TSTATE_ACKED 2
|
||||||
|
#define TSTATE_CLOSED 3
|
||||||
|
|
||||||
|
|
||||||
inline uint8_t is_space(uint8_t c)
|
inline uint8_t is_space(uint8_t c)
|
||||||
{
|
{
|
||||||
@@ -27,8 +33,27 @@ inline uint8_t is_space(uint8_t c)
|
|||||||
|
|
||||||
void httpd_init(void) __banked
|
void httpd_init(void) __banked
|
||||||
{
|
{
|
||||||
|
__xdata struct httpd_state *s = &(uip_conn->appstate);
|
||||||
// Start listening to port 80
|
// Start listening to port 80
|
||||||
uip_listen(HTONS(80));
|
uip_listen(HTONS(80));
|
||||||
|
s->tstate = TSTATE_CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t find_entry(uint8_t *e)
|
||||||
|
{
|
||||||
|
register uint8_t i, j;
|
||||||
|
|
||||||
|
for (i = 0; f_data[i].len; i++) {
|
||||||
|
j = 0;
|
||||||
|
while (f_data[i].file[j] && (f_data[i].file[j] == e[j])) {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if ((!f_data[i].file[j]) && (!e[j])) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -37,19 +62,46 @@ void httpd_appcall(void)
|
|||||||
__xdata struct httpd_state *s = &(uip_conn->appstate);
|
__xdata struct httpd_state *s = &(uip_conn->appstate);
|
||||||
|
|
||||||
write_char('P');
|
write_char('P');
|
||||||
if(uip_connected()) {
|
if(uip_connected() && s->tstate == TSTATE_CLOSED) {
|
||||||
print_string("Connected...\n");
|
print_string("Connected...\n");
|
||||||
s->transmitted = 0;
|
s->tstate = TSTATE_NONE;
|
||||||
} else if (uip_closed()) {
|
} else if (uip_closed()) {
|
||||||
print_string("Connection closed\n");
|
print_string("Connection closed\n");
|
||||||
|
s->tstate = TSTATE_CLOSED;
|
||||||
} else if (uip_poll()) {
|
} else if (uip_poll()) {
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
if (s->transmitted)
|
if (s->tstate == TSTATE_ACKED) {
|
||||||
|
print_string("Closing because everything has been transmitted\n");
|
||||||
uip_close();
|
uip_close();
|
||||||
|
}
|
||||||
// write_char('p');
|
// write_char('p');
|
||||||
} else if (uip_newdata()) {
|
} else if (uip_acked() && s->tstate == TSTATE_TX) {
|
||||||
|
print_string("ACK\n");
|
||||||
|
if (slen > uip_mss()) {
|
||||||
|
slen -= uip_mss();
|
||||||
|
o_idx += uip_mss();
|
||||||
|
} else {
|
||||||
|
slen = 0;
|
||||||
|
o_idx += slen;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->tstate = TSTATE_ACKED;
|
||||||
|
|
||||||
|
if (slen > uip_mss()) {
|
||||||
|
print_string("Sending A: "); print_short(slen); write_char('\n');
|
||||||
|
uip_send(outbuf + o_idx, uip_mss());
|
||||||
|
print_string("Sending A done\n");
|
||||||
|
s->tstate = TSTATE_TX;
|
||||||
|
} else if (slen > 0) {
|
||||||
|
print_string("Sending B: "); print_short(slen); write_char('\n');
|
||||||
|
uip_send(outbuf + o_idx, slen);
|
||||||
|
print_string("Sending B done\n");
|
||||||
|
s->tstate = TSTATE_TX;
|
||||||
|
}
|
||||||
|
} else if (uip_newdata() && s->tstate != TSTATE_TX) {
|
||||||
write_char('<'); print_short(uip_len); write_char('\n');
|
write_char('<'); print_short(uip_len); write_char('\n');
|
||||||
__xdata uint8_t *p = uip_appdata;
|
__xdata uint8_t *p = uip_appdata;
|
||||||
|
p[uip_len] = 0;
|
||||||
while (*p)
|
while (*p)
|
||||||
write_char(*p++);
|
write_char(*p++);
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
@@ -63,13 +115,76 @@ void httpd_appcall(void)
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
print_string_x(q);
|
print_string_x(q);
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
// For now, we do not have anything to send...
|
|
||||||
uip_len = strlen(page_main);
|
s->tstate = TSTATE_NONE;
|
||||||
strtox(outbuf, page_main);
|
entry = find_entry(q);
|
||||||
s->transmitted = 1;
|
print_string("Entry is: "); print_byte(entry); write_char('\n');
|
||||||
uip_send(outbuf, uip_len);
|
if (entry == 0xff) {
|
||||||
|
print_string("Not found\n");
|
||||||
|
slen = strtox(outbuf, "HTTP/1.1 404 Not found\r\nContent-Type: text/html\r\n\r\n");
|
||||||
|
print_string("slen: "); print_short(slen); write_char('\n');
|
||||||
|
slen += strtox(outbuf + slen, "<!DOCTYPE HTML PUBLIC>\n<title>404 Not Found</title>\n<h1>Not Found</h1>\n");
|
||||||
|
} else {
|
||||||
|
print_string("Have entry\n");
|
||||||
|
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
|
||||||
|
slen += strtox(outbuf + slen, f_data[entry].mime);
|
||||||
|
slen += strtox(outbuf + slen, "\r\n\r\n");
|
||||||
|
len_left = f_data[entry].len;
|
||||||
|
if (f_data[entry].mime[0] == 't' && f_data[entry].mime[5] == 'h') {
|
||||||
|
print_string("MIME is html len is "); print_short(len_left); write_char('\n');
|
||||||
|
mpos = 0;
|
||||||
|
flash_find_mark(f_data[entry].start, 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_read_bulk(outbuf + slen, f_data[entry].start + f_data[entry].len - len_left, 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_find_mark(f_data[entry].start + mpos, len_left, "#{");
|
||||||
|
}
|
||||||
|
print_string("At end mpos: "); print_short(mpos); write_char('\n');
|
||||||
|
flash_read_bulk(outbuf + slen, f_data[entry].start + f_data[entry].len - len_left, len_left);
|
||||||
|
slen += len_left;
|
||||||
|
} else {
|
||||||
|
print_string("MIME: "); print_string(f_data[entry].mime); write_char('\n');
|
||||||
|
flash_read_bulk(outbuf + slen, f_data[entry].start, len_left);
|
||||||
|
slen += len_left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_string("slen: "); print_short(slen); write_char('\n');
|
||||||
|
o_idx = 0;
|
||||||
|
if (slen > uip_mss()) {
|
||||||
|
print_string("Sending a: "); print_short(slen); write_char('\n');
|
||||||
|
uip_send(outbuf + o_idx, uip_mss());
|
||||||
|
print_string("Sending a done\n");
|
||||||
|
} else {
|
||||||
|
print_string("Sending b: "); print_short(slen); write_char('\n');
|
||||||
|
uip_send(outbuf + o_idx, slen);
|
||||||
|
print_string("Sending b done\n");
|
||||||
|
}
|
||||||
|
s->tstate = TSTATE_TX;
|
||||||
} else if (uip_rexmit()) { // Connection established, need to rexmit?
|
} else if (uip_rexmit()) { // Connection established, need to rexmit?
|
||||||
write_char('r');
|
print_string("RETRANSMIT requested\n");
|
||||||
|
if (slen > uip_mss()) {
|
||||||
|
print_string("Sending C: "); print_short(slen); write_char('\n');
|
||||||
|
uip_send(outbuf + o_idx, uip_mss());
|
||||||
|
print_string("Sending C done\n");
|
||||||
|
} else if (slen > 0) {
|
||||||
|
print_string("Sending D: "); print_short(slen); write_char('\n');
|
||||||
|
uip_send(outbuf + o_idx, slen);
|
||||||
|
print_string("Sending D done\n");
|
||||||
|
}
|
||||||
|
s->tstate = TSTATE_TX;
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
} else {
|
} else {
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
allocated together with each TCP connection. One application state
|
allocated together with each TCP connection. One application state
|
||||||
for each TCP connection. */
|
for each TCP connection. */
|
||||||
typedef struct httpd_state {
|
typedef struct httpd_state {
|
||||||
char transmitted;
|
uint8_t tstate;
|
||||||
} uip_tcp_appstate_t;
|
} uip_tcp_appstate_t;
|
||||||
|
|
||||||
/* Finally we define the application function to be called by uIP. */
|
/* Finally we define the application function to be called by uIP. */
|
||||||
|
|||||||
+5
-5
@@ -90,25 +90,25 @@ typedef uint16_t u16_t;
|
|||||||
typedef unsigned short uip_stats_t;
|
typedef unsigned short uip_stats_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of TCP connections.
|
* Maximum number of TCP connections. TODO: Increase this, but also make the socket state/buffer per-connection.
|
||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#define UIP_CONF_MAX_CONNECTIONS 40
|
#define UIP_CONF_MAX_CONNECTIONS 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of listening TCP ports.
|
* Maximum number of listening TCP ports. TODO: increase this!
|
||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#define UIP_CONF_MAX_LISTENPORTS 40
|
#define UIP_CONF_MAX_LISTENPORTS 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* uIP buffer size.
|
* uIP buffer size.
|
||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#define UIP_CONF_BUFFER_SIZE 2000
|
#define UIP_CONF_BUFFER_SIZE 2200
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CPU byte order.
|
* CPU byte order.
|
||||||
|
|||||||
Reference in New Issue
Block a user