Socket server test

Committer:
infinnovation
Date:
Mon Oct 03 13:11:32 2016 +0000
Revision:
9:c0f8b718f7d4
Parent:
7:b4f40e054a9e
Tests for lwip-config PR

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Colin Hogben 6:9c7707692925 1 //-----------------------------------------------------------------------
Colin Hogben 6:9c7707692925 2 // Test TCP socket behaviour
Colin Hogben 6:9c7707692925 3 //-----------------------------------------------------------------------
Colin Hogben 5:2c2f993df16b 4 #include "mbed.h"
Colin Hogben 5:2c2f993df16b 5 #include "EthernetInterface.h"
Colin Hogben 5:2c2f993df16b 6 #include "lwip/stats.h"
Colin Hogben 5:2c2f993df16b 7
Colin Hogben 5:2c2f993df16b 8 #ifndef SRV_PORT
Colin Hogben 6:9c7707692925 9 #define SRV_PORT 7
Colin Hogben 5:2c2f993df16b 10 #endif
Colin Hogben 5:2c2f993df16b 11
Colin Hogben 6:9c7707692925 12 #define TICK 1 // Enable 1-second tick thread
Colin Hogben 6:9c7707692925 13 #define CONSOLE 0 // Enable interactive statistics
Colin Hogben 6:9c7707692925 14 #define CONSOLE_WAIT_READABLE 0 // Non-blocking getc (#2515)
Colin Hogben 6:9c7707692925 15 #define CONSOLE_YIELD 0 // 0 = busy-wait until time slice
Colin Hogben 6:9c7707692925 16 #undef WAIT_BEFORE_RECV // pause before each recv()
Colin Hogben 6:9c7707692925 17 #define ECHO_BUF_SIZE 1000 // How much to recv() before send()
Colin Hogben 6:9c7707692925 18
Colin Hogben 5:2c2f993df16b 19 Serial pc(USBTX, USBRX);
Colin Hogben 5:2c2f993df16b 20 EthernetInterface eth;
Colin Hogben 5:2c2f993df16b 21
Colin Hogben 6:9c7707692925 22 void banner(void)
Colin Hogben 6:9c7707692925 23 {
Colin Hogben 6:9c7707692925 24 printf("== socket-test %s ==\n", __DATE__);
Colin Hogben 6:9c7707692925 25 printf("SRV_PORT: %d\n", SRV_PORT);
infinnovation 7:b4f40e054a9e 26 printf("NUM_NETCONN: %d\n", MEMP_NUM_NETCONN);
Colin Hogben 6:9c7707692925 27 printf("TICK: %d\n", TICK);
Colin Hogben 6:9c7707692925 28 printf("CONSOLE: %d\n", CONSOLE);
Colin Hogben 6:9c7707692925 29 #if CONSOLE
Colin Hogben 6:9c7707692925 30 printf("CONSOLE_WAIT_READABLE: %d\n", CONSOLE_WAIT_READABLE);
Colin Hogben 6:9c7707692925 31 printf("CONSOLE_YIELD: %d\n", CONSOLE_YIELD);
Colin Hogben 6:9c7707692925 32 #endif
Colin Hogben 6:9c7707692925 33 #ifdef WAIT_BEFORE_RECV
Colin Hogben 6:9c7707692925 34 printf("WAIT_BEFORE_RECV: %g\n", WAIT_BEFORE_RECV);
Colin Hogben 6:9c7707692925 35 #endif
Colin Hogben 6:9c7707692925 36 printf("ECHO_BUF_SIZE: %d\n", ECHO_BUF_SIZE);
Colin Hogben 6:9c7707692925 37 }
Colin Hogben 6:9c7707692925 38
Colin Hogben 6:9c7707692925 39 #if CONSOLE
Colin Hogben 5:2c2f993df16b 40 Thread console_thread;
Colin Hogben 5:2c2f993df16b 41
Colin Hogben 6:9c7707692925 42 void console_run(void)
Colin Hogben 5:2c2f993df16b 43 {
Colin Hogben 5:2c2f993df16b 44 int i;
Colin Hogben 5:2c2f993df16b 45 while (true) {
Colin Hogben 6:9c7707692925 46 #if CONSOLE_WAIT_READABLE
Colin Hogben 6:9c7707692925 47 while (! pc.readable()) {
Colin Hogben 6:9c7707692925 48 #if CONSOLE_YIELD
Colin Hogben 6:9c7707692925 49 Thread::yield();
Colin Hogben 6:9c7707692925 50 #endif
Colin Hogben 6:9c7707692925 51 }
Colin Hogben 6:9c7707692925 52 #endif
Colin Hogben 5:2c2f993df16b 53 int c = pc.getc();
Colin Hogben 5:2c2f993df16b 54 switch (c) {
Colin Hogben 5:2c2f993df16b 55 default: printf("lwip statistics: *=all"
Colin Hogben 5:2c2f993df16b 56 " l=LINK a=ETHARP"
Colin Hogben 5:2c2f993df16b 57 " i=IP f=IPFRAG c=ICMP g=IGMP"
Colin Hogben 5:2c2f993df16b 58 " u=UDP t=TCP"
Colin Hogben 5:2c2f993df16b 59 " h=HEAP m=MEMP* p=PCB n=NETBUF/NETCONN"
Colin Hogben 5:2c2f993df16b 60 " s=SYS\n"); break;
Colin Hogben 5:2c2f993df16b 61 case '*': stats_display(); break;
Colin Hogben 5:2c2f993df16b 62 case 'l': LINK_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 63 case 'a': ETHARP_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 64 case 'f': IPFRAG_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 65 case 'i': IP_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 66 case 'c': ICMP_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 67 case 'g': IGMP_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 68 case 'u': UDP_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 69 case 't': TCP_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 70 case 'h': MEM_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 71 case 'm': for (i=0; i < MEMP_MAX; i++) MEMP_STATS_DISPLAY(i); break;
Colin Hogben 5:2c2f993df16b 72 case 'p':
Colin Hogben 5:2c2f993df16b 73 MEMP_STATS_DISPLAY(MEMP_UDP_PCB);
Colin Hogben 5:2c2f993df16b 74 MEMP_STATS_DISPLAY(MEMP_TCP_PCB);
Colin Hogben 5:2c2f993df16b 75 MEMP_STATS_DISPLAY(MEMP_TCP_PCB_LISTEN);
Colin Hogben 5:2c2f993df16b 76 break;
Colin Hogben 5:2c2f993df16b 77 case 'n':
Colin Hogben 5:2c2f993df16b 78 MEMP_STATS_DISPLAY(MEMP_NETBUF);
Colin Hogben 5:2c2f993df16b 79 MEMP_STATS_DISPLAY(MEMP_NETCONN);
Colin Hogben 5:2c2f993df16b 80 break;
Colin Hogben 5:2c2f993df16b 81 case 's': SYS_STATS_DISPLAY(); break;
Colin Hogben 5:2c2f993df16b 82 }
Colin Hogben 5:2c2f993df16b 83 }
Colin Hogben 5:2c2f993df16b 84 }
Colin Hogben 6:9c7707692925 85 #endif
Colin Hogben 5:2c2f993df16b 86
Colin Hogben 6:9c7707692925 87 #if TICK
Colin Hogben 6:9c7707692925 88 Thread tick_thread;
Colin Hogben 6:9c7707692925 89
Colin Hogben 6:9c7707692925 90 void tick_run(void)
Colin Hogben 5:2c2f993df16b 91 {
Colin Hogben 6:9c7707692925 92 while (true) {
Colin Hogben 6:9c7707692925 93 printf("tick\n");
Colin Hogben 6:9c7707692925 94 wait(1.0);
Colin Hogben 6:9c7707692925 95 printf("tock\n");
Colin Hogben 6:9c7707692925 96 wait(1.0);
Colin Hogben 6:9c7707692925 97 }
Colin Hogben 6:9c7707692925 98 }
Colin Hogben 6:9c7707692925 99 #endif
Colin Hogben 6:9c7707692925 100
Colin Hogben 6:9c7707692925 101 void echo_conn_run(TCPSocket *sock)
Colin Hogben 6:9c7707692925 102 {
Colin Hogben 6:9c7707692925 103 static char buf[ECHO_BUF_SIZE];
Colin Hogben 5:2c2f993df16b 104 int ret;
Colin Hogben 5:2c2f993df16b 105 while (true) {
Colin Hogben 6:9c7707692925 106 #ifdef WAIT_BEFORE_RECV
Colin Hogben 6:9c7707692925 107 wait(WAIT_BEFORE_RECV);
Colin Hogben 6:9c7707692925 108 #endif
Colin Hogben 5:2c2f993df16b 109 ret = sock->recv(buf, sizeof(buf));
Colin Hogben 5:2c2f993df16b 110 if (ret < 0) {
Colin Hogben 6:9c7707692925 111 printf("recv: %d\n", ret);
Colin Hogben 6:9c7707692925 112 break;
Colin Hogben 5:2c2f993df16b 113 } else if (ret == 0) {
Colin Hogben 5:2c2f993df16b 114 printf("recv: EOF\r\n");
Colin Hogben 5:2c2f993df16b 115 break;
Colin Hogben 5:2c2f993df16b 116 } else {
Colin Hogben 6:9c7707692925 117 int size = ret;
Colin Hogben 5:2c2f993df16b 118 putchar('<'); fflush(stdout);
Colin Hogben 6:9c7707692925 119 ret = sock->send(buf, size);
Colin Hogben 5:2c2f993df16b 120 if (ret < 0) {
Colin Hogben 6:9c7707692925 121 printf("send: %d\n", ret);
Colin Hogben 6:9c7707692925 122 break;
Colin Hogben 6:9c7707692925 123 } else if (ret < size) {
Colin Hogben 6:9c7707692925 124 printf("send: only %d sent\n", ret);
Colin Hogben 5:2c2f993df16b 125 } else {
Colin Hogben 5:2c2f993df16b 126 putchar('>'); fflush(stdout);
Colin Hogben 5:2c2f993df16b 127 }
Colin Hogben 5:2c2f993df16b 128 }
Colin Hogben 5:2c2f993df16b 129 }
Colin Hogben 6:9c7707692925 130 delete sock;
Colin Hogben 5:2c2f993df16b 131 }
Colin Hogben 5:2c2f993df16b 132
Colin Hogben 6:9c7707692925 133 void echo_srv_run(TCPServer *srv)
Colin Hogben 5:2c2f993df16b 134 {
Colin Hogben 5:2c2f993df16b 135 int err;
Colin Hogben 5:2c2f993df16b 136 while (true) {
Colin Hogben 5:2c2f993df16b 137 TCPSocket *sock = new TCPSocket;
Colin Hogben 5:2c2f993df16b 138 err = srv->accept(sock);
Colin Hogben 5:2c2f993df16b 139 if (err) error("accept: %d\r\n", err);
Colin Hogben 5:2c2f993df16b 140 printf("accepted connection\r\n");
Colin Hogben 5:2c2f993df16b 141 Thread *conn_thread = new Thread;
Colin Hogben 6:9c7707692925 142 conn_thread->start(Callback<void()>(sock, echo_conn_run));
Colin Hogben 5:2c2f993df16b 143 }
Colin Hogben 5:2c2f993df16b 144 }
Colin Hogben 5:2c2f993df16b 145
Colin Hogben 5:2c2f993df16b 146 int main(void)
Colin Hogben 5:2c2f993df16b 147 {
Colin Hogben 5:2c2f993df16b 148 int err;
Colin Hogben 6:9c7707692925 149 banner();
Colin Hogben 5:2c2f993df16b 150 stats_init();
Colin Hogben 6:9c7707692925 151 #if TICK
Colin Hogben 6:9c7707692925 152 tick_thread.start(tick_run);
Colin Hogben 6:9c7707692925 153 #endif
Colin Hogben 6:9c7707692925 154 #if CONSOLE
Colin Hogben 6:9c7707692925 155 console_thread.start(console_run);
Colin Hogben 6:9c7707692925 156 #endif
Colin Hogben 5:2c2f993df16b 157 err = eth.connect();
Colin Hogben 5:2c2f993df16b 158 if (err) error("connect: %d\n", err);
Colin Hogben 5:2c2f993df16b 159 printf("ip %s\r\n", eth.get_ip_address());
Colin Hogben 5:2c2f993df16b 160 TCPServer srv;
Colin Hogben 5:2c2f993df16b 161 err = srv.open(&eth);
Colin Hogben 5:2c2f993df16b 162 if (err) error("open: %d\r\n", err);
Colin Hogben 5:2c2f993df16b 163 err = srv.bind(SRV_PORT);
Colin Hogben 5:2c2f993df16b 164 if (err) error("bind: %d\r\n", err);
Colin Hogben 5:2c2f993df16b 165 err = srv.listen(0);
Colin Hogben 5:2c2f993df16b 166 if (err) error("listen: %d\r\n", err);
Colin Hogben 5:2c2f993df16b 167 Thread srv_thread;
Colin Hogben 6:9c7707692925 168 srv_thread.start(Callback<void()>(&srv, echo_srv_run));
Colin Hogben 5:2c2f993df16b 169
Colin Hogben 5:2c2f993df16b 170 while (true) {
Colin Hogben 5:2c2f993df16b 171 wait(1.0);
Colin Hogben 5:2c2f993df16b 172 }
Colin Hogben 5:2c2f993df16b 173 }