From 6259fcf73677f0339d71a7639ff2b85b16f3cbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Mon, 3 Sep 2012 16:16:26 +0200 Subject: [PATCH] libports: add lwIP tests for Pandaboard on foc --- libports/run/http_srv_tracing.run | 117 +++++++++ .../http_srv_tracing_nonblocking_panda.run | 75 ++++++ libports/run/http_srv_tracing_panda.run | 75 ++++++ .../src/test/lwip/http_srv_connect/Makefile | 23 ++ .../src/test/lwip/http_srv_connect/README | 2 + .../src/test/lwip/http_srv_connect/main.c | 197 ++++++++++++++++ libports/src/test/lwip/http_srv_connect/net.c | 89 +++++++ .../src/test/lwip/http_srv_tracing/main.cc | 148 ++++++++++++ .../src/test/lwip/http_srv_tracing/target.mk | 6 + .../lwip/http_srv_tracing_nonblocking/main.cc | 222 ++++++++++++++++++ .../http_srv_tracing_nonblocking/target.mk | 6 + 11 files changed, 960 insertions(+) create mode 100644 libports/run/http_srv_tracing.run create mode 100644 libports/run/http_srv_tracing_nonblocking_panda.run create mode 100644 libports/run/http_srv_tracing_panda.run create mode 100644 libports/src/test/lwip/http_srv_connect/Makefile create mode 100644 libports/src/test/lwip/http_srv_connect/README create mode 100644 libports/src/test/lwip/http_srv_connect/main.c create mode 100644 libports/src/test/lwip/http_srv_connect/net.c create mode 100644 libports/src/test/lwip/http_srv_tracing/main.cc create mode 100644 libports/src/test/lwip/http_srv_tracing/target.mk create mode 100644 libports/src/test/lwip/http_srv_tracing_nonblocking/main.cc create mode 100644 libports/src/test/lwip/http_srv_tracing_nonblocking/target.mk diff --git a/libports/run/http_srv_tracing.run b/libports/run/http_srv_tracing.run new file mode 100644 index 000000000..a5b016b5b --- /dev/null +++ b/libports/run/http_srv_tracing.run @@ -0,0 +1,117 @@ +# +# \brief Test for using the lwIP TCP/IP stack +# \author Norman Feske +# \date 2011-05-22 +# +# This test case executes a small HTTP server on Genode running on qemu. When +# the HTTP server is up, a HTTP request to the server is performed using +# 'lynx'. The response is validated against a known pattern. +# +# The test uses qemu's "-net user" option, redirecting Genode's port 80 to the +# host's port 5555. Consequently, it cannot be executed on non-qemu test +# environments (i.e., the test won't work with the Linux version of Genode). +# +# Please make sure to include a nic driver in your build configuration. E.g., +# on the x86 platform, you may enable the 'linux_drivers' repository. +# + +# +# TODO: Add support for Linux via user-level networking (using the +# tun/tap proxy driver at os/src/drivers/nic/linux) +# +if {[have_spec linux]} { + puts "Run script does not support Linux."; exit 0 } + +requires_installation_of lynx + +# +# Build +# + +build { + core init + drivers/pci drivers/timer drivers/nic + test/lwip/http_srv_tracing +} + +create_boot_directory + +# +# Generate config +# + +set config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +append_if [have_spec pci] config { + + + + } + +append config { + +} + +install_config $config + +# +# Boot modules +# + +# generic modules +set boot_modules { + core init timer + nic_drv + ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so + test-lwip_httpsrv_tracing +} + +# platform-specific modules +lappend_if [have_spec pci] boot_modules pci_drv + +build_boot_image $boot_modules + +# +# Execute test case +# + +# qemu config +append qemu_args " -m 128 -nographic -serial mon:stdio " + +append_if [have_spec x86] qemu_args " -net nic,model=e1000 " +append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 " + +append qemu_args " -net user -redir tcp:5555::80 " + +#run_genode_until {.*Sent response.*} 60 +run_genode_until forever + +# vi: set ft=tcl : diff --git a/libports/run/http_srv_tracing_nonblocking_panda.run b/libports/run/http_srv_tracing_nonblocking_panda.run new file mode 100644 index 000000000..aab9bd75b --- /dev/null +++ b/libports/run/http_srv_tracing_nonblocking_panda.run @@ -0,0 +1,75 @@ +# vi: set ft=tcl : +assert_spec foc +assert_spec platform_panda + +# +# Build +# +build { + core + init + drivers/timer + drivers/usb + test/lwip/http_srv_tracing_nonblocking +} + +create_boot_directory + +# +# Config +# +set config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# +set boot_modules { + core + init + timer + usb_drv + test-lwip_httpsrv_tracing_nob + ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so +} + +build_boot_image [join $boot_modules " "] + diff --git a/libports/run/http_srv_tracing_panda.run b/libports/run/http_srv_tracing_panda.run new file mode 100644 index 000000000..dbec42c10 --- /dev/null +++ b/libports/run/http_srv_tracing_panda.run @@ -0,0 +1,75 @@ +# vi: set ft=tcl : +assert_spec foc +assert_spec platform_panda + +# +# Build +# +build { + core + init + drivers/timer + drivers/usb + test/lwip/http_srv_tracing +} + +create_boot_directory + +# +# Config +# +set config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# +set boot_modules { + core + init + timer + usb_drv + test-lwip_httpsrv_tracing + ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so +} + +build_boot_image [join $boot_modules " "] + diff --git a/libports/src/test/lwip/http_srv_connect/Makefile b/libports/src/test/lwip/http_srv_connect/Makefile new file mode 100644 index 000000000..926c83758 --- /dev/null +++ b/libports/src/test/lwip/http_srv_connect/Makefile @@ -0,0 +1,23 @@ +TARGET = httpsrv_connect +SRC = main.c net.c + +CFLAGS = -Wall -Wextra -Wno-unused +ifeq ($(time),1) +CC_DEF += -DUGLY_MEASURE_TIME +endif +LDFLAGS = -pthread + +OBJS = $(SRC:.c=.o) + +.PHONY: clean + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ + +.c.o: + $(CC) -c $(CFLAGS) $(CC_DEF) $^ -o $@ + +clean: + -rm -rf ./$(TARGET) ./*.o diff --git a/libports/src/test/lwip/http_srv_connect/README b/libports/src/test/lwip/http_srv_connect/README new file mode 100644 index 000000000..ed7e04395 --- /dev/null +++ b/libports/src/test/lwip/http_srv_connect/README @@ -0,0 +1,2 @@ +This is just a simple test client for http_srv, that runs on the host +system. Therefore it does not use the Genode buildsystem. diff --git a/libports/src/test/lwip/http_srv_connect/main.c b/libports/src/test/lwip/http_srv_connect/main.c new file mode 100644 index 000000000..b847faccb --- /dev/null +++ b/libports/src/test/lwip/http_srv_connect/main.c @@ -0,0 +1,197 @@ +/* + * \brief Simple http_srv client + * \author Josef Soentgen + * \date 2012-8-30 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* prototypes for net.c functions */ +extern int dial(struct addrinfo*); +extern struct addrinfo *lookup(const char*, const char*, const char*); + +/* pthread error handling */ +#define handle_error_en(en, msg) \ + do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) + +/* send request, currently hardcoded and works with httpsrv test only */ +const char req[] = "GET /"; + +/* thread arguments */ +struct args { + struct addrinfo* ai; + int flags; + int count; + int verbose; +}; + +/* receive flag */ +enum { F_NONE, F_RECV }; + +/* pthread start function */ +void * +run(void *arg) +{ + char buf[1 << 20]; /* 1 MiB should be enough */ + struct args *ap = (struct args *) arg; + int count = ap->count; + int flags = ap->flags; + int verbose = ap->verbose; + int i, s, nbytes, sum_nbytes; + + for (i = 0; i < count; i++) { + s = dial(ap->ai); /* create socket and connect */ + if (s == -1) + break; + + /* only send/receive if flag is set { */ + if (flags & F_RECV) { + /* first send request and second get header */ + write(s, req, sizeof(req)); + nbytes = read(s, buf, sizeof (buf)); + + /* get data */ + sum_nbytes = 0; +#if UGLY_MEASURE_TIME + struct timeval start, end; + gettimeofday(&start, NULL); +#endif + do { + /** + * override buffer because we don't care about + * the actual data. + */ + nbytes = read(s, buf, sizeof (buf)); + sum_nbytes += nbytes; + + } while (nbytes > 0 && nbytes != -1); + + if (nbytes == -1) + perror("read"); + +#if UGLY_MEASURE_TIME + gettimeofday(&end, NULL); + int sec = end.tv_sec - start.tv_sec; + int usec = end.tv_usec - start.tv_usec; + if (usec < 0) { + usec += 1000000; + sec--; + } + + printf("time: %d ms\n", + ((sec) * 1000) + ((usec) / 1000)); +#endif + + if (verbose) + printf("bytes read: %d\n", sum_nbytes); + } + /* } */ + + close(s); + } + /* XXX s == -1 handling */ + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + struct args a; + struct addrinfo *ai; + const char *proto = "tcp", *host, *port; + int i, err, verbose = 0, flags = F_NONE, count = 1, threads = 1; + pthread_t *thread; + + if (argc < 3) { + fprintf(stderr, "usage: %s [-vr] [-c count] [-t threads] " + "[-p protocol] \n", argv[0]); + exit(1); + } + + /* argument parsing { */ + while ((i = getopt(argc, argv, "c:p:t:rv")) != -1) { + switch (i) { + case 'c': count = atoi(optarg); break; + /** + * valid values are only 'tcp' and 'udp' + */ + case 'p': proto = optarg; break; + case 't': threads = atoi(optarg); break; + /** + * If receive is specified we will read from the socket, + * just connect to the host otherwise. + */ + case 'r': flags |= F_RECV; break; + case 'v': verbose = 1; break; + default: break; + } + } + + if ((argc - optind) != 2) { + fprintf(stderr, "missing host and/or port\n"); + exit(1); + } + + host = argv[optind++]; + port = argv[optind]; + /* } */ + + /* main { */ + thread = (pthread_t *) calloc(threads, sizeof (pthread_t)); + if (thread == NULL) { + perror("calloc"); + exit(-1); + } + + /* get addrinfo once and use it for all threads */ + ai = lookup(proto, host, port); + if (ai == NULL) { + exit(-1); + } + + /* fill thread argument structure */ + a.ai = ai; + a.count = count / threads; /* XXX check if -c > -t */ + a.flags = flags; + a.verbose = verbose; + + printf("connect to '%s!%s!%s' roughly %d times, %d per thread\n", + proto, host, port, count, a.count); + + for (i = 0; i < threads; i++) { + err = pthread_create(&thread[i], NULL, run, (void*)&a); + if (err != 0) + handle_error_en(err, "pthread_create"); + } + + for (i = 0; i < threads; i++) { + err = pthread_join(thread[i], NULL); + if (err != 0) + handle_error_en(err, "pthread_create"); + } + + freeaddrinfo(ai); + free(thread); + + /* } */ + + return 0; +} diff --git a/libports/src/test/lwip/http_srv_connect/net.c b/libports/src/test/lwip/http_srv_connect/net.c new file mode 100644 index 000000000..52cdbe767 --- /dev/null +++ b/libports/src/test/lwip/http_srv_connect/net.c @@ -0,0 +1,89 @@ +/* + * \brief Simple http_srv client + * \author Josef Soentgen + * \date 2012-8-30 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include +#include +#include +#include +#include +#include + +int +dial(struct addrinfo *ai) +{ + struct addrinfo *aip; + int s, err; + + for (aip = ai; aip != NULL; aip->ai_next) { + s = socket(aip->ai_family, aip->ai_socktype, + aip->ai_protocol); + if (s == -1) { + perror("socket"); + continue; + } + + err = connect(s, aip->ai_addr, aip->ai_addrlen); + if (err != -1) + break; + + close(s); + s = -1; + } + + return s; +} + + +struct addrinfo * +lookup(const char *proto, const char *host, const char *port) +{ + struct addrinfo hints, *r; + int err, socktype, protocol; + + if (proto == NULL) { + fprintf(stderr, "protocol is not set\n"); + return NULL; + } + + /** + * actually we can simply use protcol == 0 but we + * set it explicitly anyway. + */ + if (strcmp(proto, "tcp") == 0) { + socktype = SOCK_STREAM; + protocol = IPPROTO_TCP; + } + else if (strcmp(proto, "udp") == 0) { + socktype = SOCK_DGRAM; + protocol = IPPROTO_UDP; + } + else { + fprintf(stderr, "protocol '%s' invalid\n", proto); + return NULL; + } + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = socktype; + hints.ai_flags = 0; + hints.ai_protocol = protocol; + + err = getaddrinfo(host, port, &hints, &r); + if (err != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err)); + return NULL; + } + + return r; +} diff --git a/libports/src/test/lwip/http_srv_tracing/main.cc b/libports/src/test/lwip/http_srv_tracing/main.cc new file mode 100644 index 000000000..eeb5871e9 --- /dev/null +++ b/libports/src/test/lwip/http_srv_tracing/main.cc @@ -0,0 +1,148 @@ +/* + * \brief Minimal HTTP server lwIP demonstration + * \author lwIP Team + * \author Stefan Kalkowski + * \date 2009-10-23 + * + * This small example shows how to use the LwIP in Genode directly. + * If you simply want to use LwIP's socket API, you might use + * Genode's libc together with its LwIP backend, especially useful + * when porting legacy code. + */ + +/* + * Copyright (C) 2009-2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#include +#include +#include + +/* LwIP includes */ +extern "C" { +#include +#include +} + +#include + +namespace Fiasco { +#include +} + + +//enum { FILE_SIZE = 1UL }; /* 1 Byte */ +enum { FILE_SIZE = 3072UL }; /* 3 KiB */ +//enum { FILE_SIZE = 5120UL }; /* 5 KiB */ +//enum { FILE_SIZE = 8388608UL }; /* 8 MiB */ +//enum { FILE_SIZE = 2097152UL }; /* 2 MiB */ +//enum { FILE_SIZE = 16777216UL }; /* 16 MiB */ +//enum { FILE_SIZE = 33554432UL }; /* 32 MiB */ + +const static char http_html_hdr[] = + "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"; /* HTTP response header */ + +static char http_file_data[FILE_SIZE]; + + +/** + * Handle a single client's request. + * + * \param conn socket connected to the client + */ +void http_server_serve(int conn) { + char buf[1024]; + ssize_t buflen; + + /* Read the data from the port, blocking if nothing yet there. + We assume the request (the part we care about) is in one packet */ + buflen = lwip_recv(conn, buf, 1024, 0); + //PLOG("Packet received!"); + + /* Ignore all receive errors */ + if (buflen > 0) { + + /* Is this an HTTP GET command? (only check the first 5 chars, since + there are other formats for GET, and we're keeping it very simple)*/ + if (buflen >= 5 && + buf[0] == 'G' && + buf[1] == 'E' && + buf[2] == 'T' && + buf[3] == ' ' && + buf[4] == '/' ) { + + //PLOG("Will send response"); + + /* Send http header */ + //Fiasco::fiasco_tbuf_log_3val(">> lwip_send", Genode::strlen(http_html_hdr), 0, 0); + lwip_send(conn, http_html_hdr, Genode::strlen(http_html_hdr), 0); + //Fiasco::fiasco_tbuf_log("<< lwip_send"); + + /* + unsigned int val = 0xdeadbeef; + Fiasco::fiasco_tbuf_log_3val(">> lwip_send", sizeof (unsigned int), 0, 0); + lwip_send(conn, &val, sizeof (unsigned int), 0); + Fiasco::fiasco_tbuf_log("<< lwip_send"); + */ + + lwip_send(conn, http_file_data, sizeof (http_file_data), 0); + } + } +} + +#include + +int main() +{ + int s; + + lwip_tcpip_init(); + + /* Initialize network stack and do DHCP */ + if (lwip_nic_init(0, 0, 0)) { + PERR("We got no IP address!"); + return -1; + } + + PLOG("Create new socket ..."); + if((s = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0) { + PERR("No socket available!"); + return -1; + } + + PLOG("Now, I will bind ..."); + struct sockaddr_in in_addr; + in_addr.sin_family = AF_INET; + in_addr.sin_port = htons(80); + in_addr.sin_addr.s_addr = INADDR_ANY; + if(lwip_bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) { + PERR("bind failed!"); + return -1; + } + + PLOG("Now, I will listen ..."); + if(lwip_listen(s, 5)) { + PERR("listen failed!"); + return -1; + } + + PLOG("Start the server loop ..."); + while(true) { + struct sockaddr addr; + socklen_t len = sizeof(addr); + int client = lwip_accept(s, &addr, &len); + if(client < 0) { + PWRN("Invalid socket from accept!"); + continue; + } + http_server_serve(client); + // PLOG("Sent response, closing connection"); + lwip_close(client); + } + + return 0; +} diff --git a/libports/src/test/lwip/http_srv_tracing/target.mk b/libports/src/test/lwip/http_srv_tracing/target.mk new file mode 100644 index 000000000..1d0562313 --- /dev/null +++ b/libports/src/test/lwip/http_srv_tracing/target.mk @@ -0,0 +1,6 @@ +TARGET = test-lwip_httpsrv_tracing +LIBS = cxx env lwip libc libc_log +SRC_CC = main.cc +REQUIRES = foc + +INC_DIR += $(REP_DIR)/src/lib/lwip/include diff --git a/libports/src/test/lwip/http_srv_tracing_nonblocking/main.cc b/libports/src/test/lwip/http_srv_tracing_nonblocking/main.cc new file mode 100644 index 000000000..bfc3099be --- /dev/null +++ b/libports/src/test/lwip/http_srv_tracing_nonblocking/main.cc @@ -0,0 +1,222 @@ +/* + * \brief Minimal HTTP server lwIP demonstration + * \author lwIP Team + * \author Stefan Kalkowski + * \date 2009-10-23 + * + * This small example shows how to use the LwIP in Genode directly. + * If you simply want to use LwIP's socket API, you might use + * Genode's libc together with its LwIP backend, especially useful + * when porting legacy code. + */ + +/* + * Copyright (C) 2009-2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#include +#include +#include + +/* LwIP includes */ +extern "C" { +#include +#include +} + +#include +#include + +//enum { FILE_SIZE = 8388608UL }; /* 8 MiB */ +//enum { FILE_SIZE = 2097152UL }; /* 2 MiB */ +//enum { FILE_SIZE = 16777216UL }; /* 16 MiB */ +//enum { FILE_SIZE = 33554432UL }; /* 32 MiB */ +enum { FILE_SIZE = 5120UL }; /* 5 KiB */ + +enum { MAX_CLIENTS = 1024 }; +enum { TRY_TO_CONNECT = 100 }; + +const static char http_html_hdr[] = + "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"; /* HTTP response header */ + +static char http_file_data[FILE_SIZE]; + +struct clients { + int fd; + struct sockaddr addr; + socklen_t len; +}; + +static struct clients c[MAX_CLIENTS]; + +/** + * Handle a single client's request. + * + * \param conn socket connected to the client + */ +void http_server_serve(int conn) { + char buf[1024]; + ssize_t buflen; + + /* Read the data from the port, blocking if nothing yet there. + We assume the request (the part we care about) is in one packet */ + buflen = lwip_recv(conn, buf, 1024, 0); + PLOG("Packet received!"); + + /* Ignore all receive errors */ + if (buflen > 0) { + + /* Is this an HTTP GET command? (only check the first 5 chars, since + there are other formats for GET, and we're keeping it very simple)*/ + if (buflen >= 5 && + buf[0] == 'G' && + buf[1] == 'E' && + buf[2] == 'T' && + buf[3] == ' ' && + buf[4] == '/' ) { + + PLOG("Will send response"); + + /* Send http header */ + lwip_send(conn, http_html_hdr, Genode::strlen(http_html_hdr), 0); + lwip_send(conn, http_file_data, FILE_SIZE, 0); + } + } +} + +#include + +int main() +{ + int s, c_num; + + fd_set rs, ws, es; + + lwip_tcpip_init(); + + /* Initialize network stack and do DHCP */ + if (lwip_nic_init(0, 0, 0)) { + PERR("We got no IP address!"); + return -1; + } + + PLOG("Create new socket ..."); + if((s = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0) { + PERR("No socket available!"); + return -1; + } + + PLOG("Now, I will bind to port 80 ..."); + struct sockaddr_in in_addr; + in_addr.sin_family = AF_INET; + in_addr.sin_port = htons(80); + in_addr.sin_addr.s_addr = INADDR_ANY; + memset(&(in_addr.sin_zero), '\0', 8); + + if (lwip_bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) { + PERR("bind failed!"); + return -1; + } + + PLOG("Now, I will listen ..."); + if (lwip_listen(s, 5)) { + PERR("listen failed!"); + return -1; + } + + PLOG("Make socket non-blocking ..."); + if (lwip_fcntl(s, F_SETFL, O_NONBLOCK)) { + PERR("fcntl() failed!"); + return -1; + } + + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + for (int i = 0; i < MAX_CLIENTS; i++) + c[i].fd = -1; + + c_num = 0; + + PLOG("Start the server loop ..."); + while(true) { + /* clear fds */ + FD_ZERO(&rs); + FD_ZERO(&ws); + FD_ZERO(&es); + + /* set fds */ + FD_SET(s, &rs); + for (int i = 0, num = c_num; i < MAX_CLIENTS; i++) { + if (c[i].fd != -1) { + FD_SET(c[i].fd, &rs); + + if (num > 0) + num--; + else + break; + } + } + + //PLOG("before select, c_num: %d", c_num); + int ready = lwip_select(c_num + 1, &rs, &ws, &es, &timeout); + + if (ready > 0) { + if (FD_ISSET(s, &rs)) { + for (int i = 0; i < TRY_TO_CONNECT; i++) { + int *fd = &c[c_num].fd; + struct sockaddr *addr = &c[c_num].addr; + socklen_t *len = &c[c_num].len; + + *fd = lwip_accept(s, addr, len); + + if (*fd < 0) { + /* there is currently nobody waiting */ + if (errno == EWOULDBLOCK) + break; + + //PWRN("Invalid socket from accept!"); + continue; + } + if (lwip_fcntl(*fd, F_SETFL, O_NONBLOCK)) { + //PERR("fcntl() failed"); + lwip_close(*fd); + continue; + } + + c_num++; + //PLOG("add client %d", c_num); + } + } + + for (int i = 0, num = c_num; i < MAX_CLIENTS; i++) { + int *fd = &c[i].fd; + + if (*fd != -1) { + if (FD_ISSET(*fd, &rs)) { + http_server_serve(*fd); + //PLOG("Send response, closing connection"); + lwip_close(*fd); + + c_num--; + *fd = -1; + + //PLOG("after close, c_num: %d", c_num); + } + + if (num > 0) + num--; + else + break; + } + } + } + } + + return 0; +} diff --git a/libports/src/test/lwip/http_srv_tracing_nonblocking/target.mk b/libports/src/test/lwip/http_srv_tracing_nonblocking/target.mk new file mode 100644 index 000000000..15528e663 --- /dev/null +++ b/libports/src/test/lwip/http_srv_tracing_nonblocking/target.mk @@ -0,0 +1,6 @@ +TARGET = test-lwip_httpsrv_tracing_nob +LIBS = cxx env lwip libc libc_log +SRC_CC = main.cc +REQUIRES = foc + +INC_DIR += $(REP_DIR)/src/lib/lwip/include