Adding initial http daemon implementation

This commit is contained in:
logicog
2025-07-13 12:03:40 +02:00
parent e2716da6c8
commit d66931acdf
11 changed files with 154 additions and 154 deletions
+4 -3
View File
@@ -1,18 +1,18 @@
BOOTLOADER_ADDRESS=0x100 BOOTLOADER_ADDRESS=0x100
CC = sdcc CC = sdcc
CC_FLAGS = -mmcs51 -Ihello-world -Iuip CC_FLAGS = -mmcs51 -Ihttpd -Iuip
ASM = sdas8051 ASM = sdas8051
AFLAGS= -plosgff AFLAGS= -plosgff
SUBDIRS := uip hello-world SUBDIRS := uip httpd
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS)) SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
all: $(SUBDIRS) rtlplayground.bin injector all: $(SUBDIRS) rtlplayground.bin injector
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
OBJS = ${SRCS:.c=.rel} OBJS = ${SRCS:.c=.rel}
OBJS += uip/psock.rel 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 hello-world/hello-world.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
$(SUBDIRS): $(SUBDIRS):
@@ -20,6 +20,7 @@ $(SUBDIRS):
clean: clean:
make -C uip clean make -C uip clean
make -C httpd clean
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
-108
View File
@@ -1,108 +0,0 @@
/**
* \addtogroup helloworld
* @{
*/
/**
* \file
* An example of how to write uIP applications
* with protosockets.
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* This is a short example of how to write uIP applications using
* protosockets.
*/
/*
* We define the application state (struct hello_world_state) in the
* hello-world.h file, so we need to include it here. We also include
* uip.h (since this cannot be included in hello-world.h) and
* <string.h>, since we use the memcpy() function in the code.
*/
#include "hello-world.h"
#include "../rtl837x_common.h"
#include "uip.h"
#pragma codeseg BANK1
/*
* Declaration of the protosocket function that handles the connection
* (defined at the end of the code).
*/
static uint8_t handle_connection(__xdata struct hello_world_state *s);
/*---------------------------------------------------------------------------*/
/*
* The initialization function. We must explicitly call this function
* from the system initialization code, some time after uip_init() is
* called.
*/
void
hello_world_init(void)
{
/* We start to listen for connections on TCP port 1000. */
uip_listen(HTONS(1000));
}
/*---------------------------------------------------------------------------*/
/*
* In hello-world.h we have defined the UIP_APPCALL macro to
* hello_world_appcall so that this funcion is uIP's application
* function. This function is called whenever an uIP event occurs
* (e.g. when a new connection is established, new data arrives, sent
* data is acknowledged, data needs to be retransmitted, etc.).
*/
void
hello_world_appcall(void)
{
/*
* The uip_conn structure has a field called "appstate" that holds
* the application state of the connection. We make a pointer to
* this to access it easier.
*/
__xdata struct hello_world_state *s = &(uip_conn->appstate);
/*
* If a new connection was just established, we should initialize
* the protosocket in our applications' state structure.
*/
if(uip_connected()) {
PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
}
/*
* Finally, we run the protosocket function that actually handles
* the communication. We pass it a pointer to the application state
* of the current connection.
*/
write_char('A');
handle_connection(s);
}
/*---------------------------------------------------------------------------*/
/*
* This is the protosocket function that handles the communication. A
* protosocket function must always return an int, but must never
* explicitly return - all return statements are hidden in the PSOCK
* macros.
*/
static uint8_t
handle_connection(__xdata struct hello_world_state *s)
{
__xdata char buf[100];
PSOCK_BEGIN(&s->p);
strtox(buf, "Hello. What is your name?\n");
// PSOCK_SEND_STR(&s->p, &buf[0]);
// PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n");
PSOCK_READTO(&s->p, '\n');
// strncpy(s->name, s->inputbuffer, sizeof(s->name));
strtox(buf, "Name: ");
// PSOCK_SEND_STR(&s->p, &buf[0]);
// PSOCK_SEND_STR(&s->p, s->name);
PSOCK_CLOSE(&s->p);
PSOCK_END(&s->p);
}
/*---------------------------------------------------------------------------*/
+6 -4
View File
@@ -3,19 +3,21 @@ CC_FLAGS = -mmcs51 -I. -I../uip
ASM = sdas8051 ASM = sdas8051
AFLAGS= -plosgff AFLAGS= -plosgff
SRCS = hello-world.c SRCS = httpd.c
OBJS = ${SRCS:.c=.rel} OBJS = ${SRCS:.c=.rel}
all: $(OBJS) all: $(OBJS)
%.rel: %.c %.asm: %.c
$(CC) $(CC_FLAGS) -c $< $(CC) $(CC_FLAGS) -c -S $<
%.rel: %.asm %.rel: %.asm
./treatasm.py $^ >$^.new
mv $^.new $^
${ASM} ${AFLAGS} $^ ${ASM} ${AFLAGS} $^
clean: clean:
rm *.ihx *.lk *.lst *.map *.mem *.rel *.rst *.sym *.bin rm .asm *.lst *.rel *.rst *.sym
.PHONY: all clean .PHONY: all clean
+77
View File
@@ -0,0 +1,77 @@
#include "httpd.h"
#include "../rtl837x_common.h"
#include "uip.h"
#pragma codeseg BANK1
static __code uint8_t page_main[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n"
"\r\n<!DOCTYPE html>"
"<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];
inline uint8_t is_space(uint8_t c)
{
return c == ' ' || c == '\t';
}
void httpd_init(void) __banked
{
// Start listening to port 80
uip_listen(HTONS(80));
}
void httpd_appcall(void)
{
__xdata struct httpd_state *s = &(uip_conn->appstate);
write_char('P');
if(uip_connected()) {
print_string("Connected...\n");
s->transmitted = 0;
} else if (uip_closed()) {
print_string("Connection closed\n");
} else if (uip_poll()) {
uip_len = 0;
if (s->transmitted)
uip_close();
// write_char('p');
} else if (uip_newdata()) {
write_char('<'); print_short(uip_len); write_char('\n');
__xdata uint8_t *p = uip_appdata;
while (*p)
write_char(*p++);
write_char('\n');
p = uip_appdata;
if (p[0] == 'G' && p[1] == 'E' && p[2] == 'T' && p[3] == ' ')
print_string("GET request ");
p += 4;
__xdata uint8_t *q = p;
while (!is_space(*p))
p++;
*p = '\0';
print_string_x(q);
write_char('\n');
// For now, we do not have anything to send...
uip_len = strlen(page_main);
strtox(outbuf, page_main);
s->transmitted = 1;
uip_send(outbuf, uip_len);
} else if (uip_rexmit()) { // Connection established, need to rexmit?
write_char('r');
uip_len = 0;
} else {
uip_len = 0;
}
}
+6 -33
View File
@@ -1,24 +1,3 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup helloworld Hello, world
* @{
*
* A small example showing how to write applications with
* \ref psock "protosockets".
*/
/**
* \file
* Header file for an example of how to write uIP applications
* with protosockets.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __HELLO_WORLD_H__ #ifndef __HELLO_WORLD_H__
#define __HELLO_WORLD_H__ #define __HELLO_WORLD_H__
@@ -27,26 +6,20 @@
u16_t datatypes. */ u16_t datatypes. */
#include "uipopt.h" #include "uipopt.h"
#include "psock.h"
/* Next, we define the uip_tcp_appstate_t datatype. This is the state /* Next, we define the uip_tcp_appstate_t datatype. This is the state
of our application, and the memory required for this state is of our application, and the memory required for this state is
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 hello_world_state { typedef struct httpd_state {
struct psock p; char transmitted;
char inputbuffer[10];
char name[40];
} 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. */
void hello_world_appcall(void); void httpd_appcall(void);
#ifndef UIP_APPCALL #ifndef UIP_APPCALL
#define UIP_APPCALL hello_world_appcall #define UIP_APPCALL httpd_appcall
#endif /* UIP_APPCALL */ #endif /* UIP_APPCALL */
void hello_world_init(void); void httpd_init(void) __banked;
#endif /* __HELLO_WORLD_H__ */ #endif
/** @} */
/** @} */
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/python
import re
import sys
isBanked = False
regex_bank = re.compile(r'^\s*\.area\s+BANK\d+\s*\(CODE\)')
regex_const = re.compile(r'^\s*\.area\s+CONST\s*\(CODE\)')
regex_area = re.compile(r'^\s*\.area\s+\(CODE\)')
with open(sys.argv[1], "r") as file:
for line in file:
line = line.rstrip()
bmatch = re.search(regex_bank, line)
if bmatch:
isBanked = True
print(line)
else:
cmatch = re.search(regex_const, line)
if not isBanked or not cmatch:
print(line)
amatch = re.search(regex_area, line)
if amatch:
isBanked = False
print(line)
+1
View File
@@ -59,5 +59,6 @@ uint16_t strlen(register __code const char *s);
uint16_t strlen_x(register __xdata const char *s); uint16_t strlen_x(register __xdata const char *s);
void strtox(register __xdata uint8_t *dst, register __code const char *s); void strtox(register __xdata uint8_t *dst, register __code const char *s);
void tcpip_output(void); void tcpip_output(void);
void print_string_x(__xdata char *p);
#endif #endif
+11
View File
@@ -154,6 +154,12 @@ void print_string(__code char *p)
write_char(*p++); write_char(*p++);
} }
void print_string_x(__xdata char *p)
{
while (*p)
write_char(*p++);
}
void memcpy(__xdata void * __xdata dst, __xdata const void * __xdata src, uint16_t len) void memcpy(__xdata void * __xdata dst, __xdata const void * __xdata src, uint16_t len)
{ {
@@ -197,6 +203,9 @@ uint16_t strlen_x(register __xdata const char *s)
uint16_t l = 0; uint16_t l = 0;
while (s[l]) while (s[l])
l++; l++;
write_char(';');
print_short(l);
write_char(';');
return l; return l;
} }
@@ -855,6 +864,7 @@ void handle_tx(void)
for(uint8_t i = 0; i < UIP_CONNS; i++) { for(uint8_t i = 0; i < UIP_CONNS; i++) {
uip_periodic(i); uip_periodic(i);
if(uip_len > 0) { if(uip_len > 0) {
write_char('.'); print_short(i);
uip_arp_out(); uip_arp_out();
tcpip_output(); tcpip_output();
} }
@@ -1588,6 +1598,7 @@ void bootloader(void)
vlan_setup(); vlan_setup();
uip_init(); uip_init();
uip_arp_init(); uip_arp_init();
httpd_init();
was_offline = 1; was_offline = 1;
+2 -2
View File
@@ -1,9 +1,9 @@
CC = sdcc CC = sdcc
CC_FLAGS = -mmcs51 -I. -I../hello-world CC_FLAGS = -mmcs51 -I. -I../httpd
ASM = sdas8051 ASM = sdas8051
AFLAGS= -plosgff AFLAGS= -plosgff
SRCS = psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c
OBJS = ${SRCS:.c=.rel} OBJS = ${SRCS:.c=.rel}
all: $(OBJS) all: $(OBJS)
+1 -1
View File
@@ -148,7 +148,7 @@ typedef unsigned short uip_stats_t;
/* Here we include the header file for the application(s) we use in /* Here we include the header file for the application(s) we use in
our project. */ our project. */
/*#include "smtp.h"*/ /*#include "smtp.h"*/
#include "hello-world.h" #include "httpd.h"
/*#include "telnetd.h"*/ /*#include "telnetd.h"*/
/*#include "webserver.h" */ /*#include "webserver.h" */
/*#include "dhcpc.h"*/ /*#include "dhcpc.h"*/
+21 -3
View File
@@ -690,7 +690,9 @@ uip_process(u8_t flag) __banked
if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
!uip_outstanding(uip_connr)) { !uip_outstanding(uip_connr)) {
uip_flags = UIP_POLL; uip_flags = UIP_POLL;
write_char('B');
UIP_APPCALL(); UIP_APPCALL();
write_char('b');
goto appsend; goto appsend;
} }
goto drop; goto drop;
@@ -742,7 +744,9 @@ uip_process(u8_t flag) __banked
UIP_TIMEDOUT to inform the application that the UIP_TIMEDOUT to inform the application that the
connection has timed out. */ connection has timed out. */
uip_flags = UIP_TIMEDOUT; uip_flags = UIP_TIMEDOUT;
write_char('C');
UIP_APPCALL(); UIP_APPCALL();
write_char('c');
/* We also send a reset packet to the remote host. */ /* We also send a reset packet to the remote host. */
BUF->flags = TCP_RST | TCP_ACK; BUF->flags = TCP_RST | TCP_ACK;
@@ -781,6 +785,7 @@ uip_process(u8_t flag) __banked
the code for sending out the packet (the apprexmit the code for sending out the packet (the apprexmit
label). */ label). */
uip_flags = UIP_REXMIT; uip_flags = UIP_REXMIT;
write_char('R');
UIP_APPCALL(); UIP_APPCALL();
goto apprexmit; goto apprexmit;
@@ -993,8 +998,6 @@ uip_process(u8_t flag) __banked
uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
// ICMPBUF->proto = 0x06; //BUG: Only for testing...
UIP_STAT(++uip_stat.icmp.sent); UIP_STAT(++uip_stat.icmp.sent);
goto send; goto send;
@@ -1166,6 +1169,7 @@ uip_process(u8_t flag) __banked
/* Start of TCP input header processing code. */ /* Start of TCP input header processing code. */
// BUG: We need to reimplement this with RTL837x TCP checksum checking // BUG: We need to reimplement this with RTL837x TCP checksum checking
// i.e. figure out which bit in the RX-tag states the checksum is correct
// if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP // if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
// checksum. */ // checksum. */
// UIP_STAT(++uip_stat.tcp.drop); // UIP_STAT(++uip_stat.tcp.drop);
@@ -1381,7 +1385,9 @@ uip_process(u8_t flag) __banked
uip_connr->tcpstateflags = UIP_CLOSED; uip_connr->tcpstateflags = UIP_CLOSED;
UIP_LOG("tcp: got reset, aborting connection."); UIP_LOG("tcp: got reset, aborting connection.");
uip_flags = UIP_ABORT; uip_flags = UIP_ABORT;
write_char('F');
UIP_APPCALL(); UIP_APPCALL();
write_char('f');
goto drop; goto drop;
} }
/* Calculated the length of the data, if the application has sent /* Calculated the length of the data, if the application has sent
@@ -1470,7 +1476,7 @@ uip_process(u8_t flag) __banked
uip_add_rcv_nxt(uip_len); uip_add_rcv_nxt(uip_len);
} }
uip_slen = 0; uip_slen = 0;
UIP_APPCALL(); UIP_APPCALL(); // UIP_CONNECTED
goto appsend; goto appsend;
} }
goto drop; goto drop;
@@ -1525,12 +1531,16 @@ uip_process(u8_t flag) __banked
uip_connr->len = 0; uip_connr->len = 0;
uip_len = 0; uip_len = 0;
uip_slen = 0; uip_slen = 0;
write_char('H');
UIP_APPCALL(); UIP_APPCALL();
write_char('h');
goto appsend; goto appsend;
} }
/* Inform the application that the connection failed */ /* Inform the application that the connection failed */
uip_flags = UIP_ABORT; uip_flags = UIP_ABORT;
write_char('I');
UIP_APPCALL(); UIP_APPCALL();
write_char('I');
/* The connection is closed after we send the RST */ /* The connection is closed after we send the RST */
uip_conn->tcpstateflags = UIP_CLOSED; uip_conn->tcpstateflags = UIP_CLOSED;
goto reset; goto reset;
@@ -1557,7 +1567,9 @@ uip_process(u8_t flag) __banked
if(uip_len > 0) { if(uip_len > 0) {
uip_flags |= UIP_NEWDATA; uip_flags |= UIP_NEWDATA;
} }
write_char('J');
UIP_APPCALL(); UIP_APPCALL();
write_char('j');
uip_connr->len = 1; uip_connr->len = 1;
uip_connr->tcpstateflags = UIP_LAST_ACK; uip_connr->tcpstateflags = UIP_LAST_ACK;
uip_connr->nrtx = 0; uip_connr->nrtx = 0;
@@ -1715,7 +1727,9 @@ uip_process(u8_t flag) __banked
if(uip_flags & UIP_ACKDATA) { if(uip_flags & UIP_ACKDATA) {
uip_connr->tcpstateflags = UIP_CLOSED; uip_connr->tcpstateflags = UIP_CLOSED;
uip_flags = UIP_CLOSE; uip_flags = UIP_CLOSE;
write_char('L');
UIP_APPCALL(); UIP_APPCALL();
write_char('l');
} }
break; break;
@@ -1736,7 +1750,9 @@ uip_process(u8_t flag) __banked
} }
uip_add_rcv_nxt(1); uip_add_rcv_nxt(1);
uip_flags = UIP_CLOSE; uip_flags = UIP_CLOSE;
write_char('M');
UIP_APPCALL(); UIP_APPCALL();
write_char('m');
goto tcp_send_ack; goto tcp_send_ack;
} else if(uip_flags & UIP_ACKDATA) { } else if(uip_flags & UIP_ACKDATA) {
uip_connr->tcpstateflags = UIP_FIN_WAIT_2; uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
@@ -1757,7 +1773,9 @@ uip_process(u8_t flag) __banked
uip_connr->timer = 0; uip_connr->timer = 0;
uip_add_rcv_nxt(1); uip_add_rcv_nxt(1);
uip_flags = UIP_CLOSE; uip_flags = UIP_CLOSE;
write_char('N');
UIP_APPCALL(); UIP_APPCALL();
write_char('n');
goto tcp_send_ack; goto tcp_send_ack;
} }
if(uip_len > 0) { if(uip_len > 0) {