Socket server test

main.cpp

Committer:
infinnovation
Date:
2016-09-16
Revision:
7:b4f40e054a9e
Parent:
6:9c7707692925

File content as of revision 7:b4f40e054a9e:

//-----------------------------------------------------------------------
//      Test TCP socket behaviour
//-----------------------------------------------------------------------
#include "mbed.h"
#include "EthernetInterface.h"
#include "lwip/stats.h"

#ifndef SRV_PORT
#define SRV_PORT 7
#endif

#define TICK 1                          // Enable 1-second tick thread
#define CONSOLE 0                       // Enable interactive statistics
#define CONSOLE_WAIT_READABLE 0         // Non-blocking getc (#2515)
#define CONSOLE_YIELD 0                 // 0 = busy-wait until time slice
#undef WAIT_BEFORE_RECV                 // pause before each recv()
#define ECHO_BUF_SIZE 1000              // How much to recv() before send()

Serial pc(USBTX, USBRX);
EthernetInterface eth;

void banner(void)
{
    printf("== socket-test %s ==\n", __DATE__);
    printf("SRV_PORT: %d\n", SRV_PORT);
    printf("NUM_NETCONN: %d\n", MEMP_NUM_NETCONN);
    printf("TICK: %d\n", TICK);
    printf("CONSOLE: %d\n", CONSOLE);
#if CONSOLE
    printf("CONSOLE_WAIT_READABLE: %d\n", CONSOLE_WAIT_READABLE);
    printf("CONSOLE_YIELD: %d\n", CONSOLE_YIELD);
#endif
#ifdef WAIT_BEFORE_RECV
    printf("WAIT_BEFORE_RECV: %g\n", WAIT_BEFORE_RECV);
#endif
    printf("ECHO_BUF_SIZE: %d\n", ECHO_BUF_SIZE);
}

#if CONSOLE
Thread console_thread;

void console_run(void)
{
    int i;
    while (true) {
#if CONSOLE_WAIT_READABLE
        while (! pc.readable()) {
#if CONSOLE_YIELD
            Thread::yield();
#endif
        }
#endif
        int c = pc.getc();
        switch (c) {
        default: printf("lwip statistics: *=all"
                        " l=LINK a=ETHARP"
                        " i=IP f=IPFRAG c=ICMP g=IGMP"
                        " u=UDP t=TCP"
                        " h=HEAP m=MEMP* p=PCB n=NETBUF/NETCONN"
                        " s=SYS\n"); break;
        case '*': stats_display(); break;
        case 'l': LINK_STATS_DISPLAY(); break;
        case 'a': ETHARP_STATS_DISPLAY(); break;
        case 'f': IPFRAG_STATS_DISPLAY(); break;
        case 'i': IP_STATS_DISPLAY(); break;
        case 'c': ICMP_STATS_DISPLAY(); break;
        case 'g': IGMP_STATS_DISPLAY(); break;
        case 'u': UDP_STATS_DISPLAY(); break;
        case 't': TCP_STATS_DISPLAY(); break;
        case 'h': MEM_STATS_DISPLAY(); break;
        case 'm': for (i=0; i < MEMP_MAX; i++) MEMP_STATS_DISPLAY(i); break;
        case 'p':
            MEMP_STATS_DISPLAY(MEMP_UDP_PCB);
            MEMP_STATS_DISPLAY(MEMP_TCP_PCB);
            MEMP_STATS_DISPLAY(MEMP_TCP_PCB_LISTEN);
            break;
        case 'n':
            MEMP_STATS_DISPLAY(MEMP_NETBUF);
            MEMP_STATS_DISPLAY(MEMP_NETCONN);
            break;
        case 's': SYS_STATS_DISPLAY(); break;
        }
    }
}
#endif

#if TICK
Thread tick_thread;

void tick_run(void)
{
    while (true) {
        printf("tick\n");
        wait(1.0);
        printf("tock\n");
        wait(1.0);
    }
}
#endif

void echo_conn_run(TCPSocket *sock)
{
    static char buf[ECHO_BUF_SIZE];
    int ret;
    while (true) {
#ifdef WAIT_BEFORE_RECV
        wait(WAIT_BEFORE_RECV);
#endif
        ret = sock->recv(buf, sizeof(buf));
        if (ret < 0) {
            printf("recv: %d\n", ret);
            break;
        } else if (ret == 0) {
            printf("recv: EOF\r\n");
            break;
        } else {
            int size = ret;
            putchar('<'); fflush(stdout);
            ret = sock->send(buf, size);
            if (ret < 0) {
                printf("send: %d\n", ret);
                break;
            } else if (ret < size) {
                printf("send: only %d sent\n", ret);
            } else {
                putchar('>'); fflush(stdout);
            }
        }
    }
    delete sock;
}

void echo_srv_run(TCPServer *srv)
{
    int err;
    while (true) {
        TCPSocket *sock = new TCPSocket;
        err = srv->accept(sock);
        if (err) error("accept: %d\r\n", err);
        printf("accepted connection\r\n");
        Thread *conn_thread = new Thread;
        conn_thread->start(Callback<void()>(sock, echo_conn_run));
    }
}

int main(void)
{
    int err;
    banner();
    stats_init();
#if TICK
    tick_thread.start(tick_run);
#endif
#if CONSOLE
    console_thread.start(console_run);
#endif
    err = eth.connect();
    if (err) error("connect: %d\n", err);
    printf("ip %s\r\n", eth.get_ip_address());
    TCPServer srv;
    err = srv.open(&eth);
    if (err) error("open: %d\r\n", err);
    err = srv.bind(SRV_PORT);
    if (err) error("bind: %d\r\n", err);
    err = srv.listen(0);
    if (err) error("listen: %d\r\n", err);
    Thread srv_thread;
    srv_thread.start(Callback<void()>(&srv, echo_srv_run));

    while (true) {
        wait(1.0);
    }
}