Network TCP/IP performance tester ported from Kai-Uwe Rommels NetIO 1.32 2012/11/22

Dependencies:   EALib EthernetInterface NTPClient mbed-rtos mbed

main.cpp

Committer:
jmehring
Date:
2015-04-21
Revision:
0:a8301fc87d39

File content as of revision 0:a8301fc87d39:


#include "mbed.h"
#include "sdram.h"

#define MEM_LIBC_MALLOC 1
#include "EthernetInterface.h"
// #include "NTPClient.h"
#include "lwip/opt.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"

// mbed stuff
DigitalOut led1(LED1);
Serial pc(USBTX, USBRX);
Timer t;
Ticker blinker;


#define DEFAULTPORT 0x494F /* "IO" */

#define INTERVAL 6

int nSizes[] = {1024, 2048, 4096, 8192, 16384, 32768};
size_t nnSizes = sizeof(nSizes) / sizeof(int);
#define NMAXSIZE 65536

int tSizes[] = {1024, 2048, 4096, 8192, 16384, 32767};
size_t ntSizes = sizeof(tSizes) / sizeof(int);
#define TMAXSIZE 65536


#define KB(nSize)   ((nSize) + 512) / 1024

typedef struct {
  uint32_t cmd;
  uint32_t data;
} CONTROL;

#define CMD_NONE  0
#define CMD_C2S   1
#define CMD_S2C   2
#define CMD_RES   3

#define CTLSIZE sizeof(CONTROL)

int nPort = DEFAULTPORT;


static void blink(void) {
    led1 = !led1;
}


static void StartTimer(void) {
    t.reset();
    t.start();
}


static float ReadTimer(void) {
    return t.read();
}


static float StopTimer(void) {
    t.stop();
    return ReadTimer();
}


static void GenerateRandomData(char *cBuffer, size_t nSize) {
    if (cBuffer != NULL) {
        size_t i;
        
        cBuffer[0] = 0;
        srand(time(NULL));
        
        for (i = 1; i < nSize; i++)
            cBuffer[i] = (char) rand();
    }
}


static char *InitBuffer(size_t nSize) {
    char *cBuffer = (char *)malloc(nSize);
    
    GenerateRandomData(cBuffer, nSize); 
    return cBuffer;
}


static int send_data(int socket, void *buffer, size_t size, int flags) {
    int rc = lwip_send(socket, buffer, size, flags);
    
    if (rc < 0) {
        printf("send error\n");
        return -1;
    }
    
    if (rc != size)
        return 1;
    
    return 0;
}


static int recv_data(int socket, void *buffer, size_t size, int flags) {
    int rc = lwip_recv(socket, buffer, size, flags);
    
    if (rc < 0) {
        printf("recv error\n");
        return -1;
    }
    
    if (rc != size)
        return 1;
    
    return 0;
}


static void netio_server (const void *arg) {
    char *cBuffer;
    CONTROL ctl;
    float nTime;
    long long nData;
    struct sockaddr_in sa_server, sa_client;
    int server, client;
    socklen_t length;
    struct timeval tv;
    fd_set fds;
    int rc;
    int nByte;

    if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) {
        printf("malloc error\n");
        return;
    }

    server = lwip_socket(AF_INET, SOCK_STREAM, 0);
    if (server < 0) {
        printf("socket error\n");
        free(cBuffer);
        return;
    }
    
    sa_server.sin_family = AF_INET;
    sa_server.sin_port = htons(nPort);
    sa_server.sin_addr.s_addr = INADDR_ANY;
    if (lwip_bind(server, (struct sockaddr *)&sa_server, sizeof(sa_server)) < 0) {
        printf("bind error\n");
        lwip_close(server);
        free(cBuffer);
        return;
    }
    
    if (lwip_listen(server, 1) != 0) {
        printf("listen error\n");
        lwip_close(server);
        free(cBuffer);
        return;
    }
    
    for (;;) {
        printf("TCP server listening.\n");
    
        FD_ZERO(&fds);
        FD_SET(server, &fds);
        tv.tv_sec  = 3600;
        tv.tv_usec = 0;
    
        if ((rc = lwip_select(FD_SETSIZE, &fds, 0, 0, &tv)) < 0) {
            printf("select error\n");
            break;
        }
    
        if (rc == 0 || FD_ISSET(server, &fds) == 0)
            continue;
    
        length = sizeof(sa_client);
        if ((client = lwip_accept(server, (struct sockaddr *) &sa_client, &length)) == -1)
            continue;
        
        printf("TCP connection established.\n");
        
        for (;;) {
            if (recv_data(client, (void *) &ctl, CTLSIZE, 0))
                break;
            
            ctl.cmd = ntohl(ctl.cmd);
            ctl.data = ntohl(ctl.data);
            
            if (ctl.cmd == CMD_C2S) {
                printf("Packet size %2uk bytes: ", KB(ctl.data));
                fflush(stdout);
                nData = 0;
                StartTimer();
                
                do {
                    for (nByte = 0; nByte < ctl.data; ) {
                        rc = lwip_recv(client, cBuffer + nByte, ctl.data - nByte, 0);
                        
                        if (rc < 0) {
                            printf("recv error\n");
                            break;
                        }
                        
                        if (rc > 0)
                            nByte += rc;
                    }
                    
                    nData += ctl.data;
                } while (cBuffer[0] == 0 && rc > 0);
                
                if ((nTime = StopTimer()) != -1) {
                    printf(" %0.2f KByte/s Rx", nData / 1024 / nTime);
                    fflush(stdout);
                }
            } else if (ctl.cmd == CMD_S2C) {
                cBuffer[0] = 0;
                nData = 0;

                StartTimer();
                
                while (ReadTimer() < INTERVAL) {
                    //GenerateRandomData(cBuffer, ctl.data);
                    
                    for (nByte = 0; nByte < ctl.data; ) {
                        rc = lwip_send(client, cBuffer + nByte, ctl.data - nByte, 0);
                        
                        if (rc < 0) {
                            printf("send error\n");
                            break;
                        }
                        
                        if (rc > 0)
                            nByte += rc;
                    }
                        
                    nData += ctl.data;
                }
                    
                cBuffer[0] = 1;
                
                if (send_data(client, cBuffer, ctl.data, 0))
                    break;
                
                if ((nTime = StopTimer()) != -1) {
                    printf(", %0.2f KByte/s Tx\n", nData / 1024 / nTime);
                }
            } else {
                // quit
                break;
            }
        }
        printf("Done.\n");

        lwip_close(client);
        
        if (rc < 0)
            break;
    }
    lwip_close(server);
    
    free(cBuffer);
}


int main() {
    pc.baud(115200);
    
    if (sdram_init() == 0) {
        printf("SDRAM initialized\n");
    } else {
        printf("Failed to initialized SDRAM\n");
    }

    blinker.attach(&blink, 0.5);
    
    EthernetInterface eth;
    eth.init(); // Use DHCP
    eth.connect();
    printf("IP Address is %s\n", eth.getIPAddress());

/*    
    NTPClient ntp;
    if (ntp.setTime("0.pool.ntp.org") == 0) {
      printf("Set time successfully\n");
      time_t rawtime = time(NULL) + (2 * 60 * 60);
      struct tm *timeinfo = localtime(&rawtime);
      strftime(buffer, sizeof(buffer), "Time: %d.%m.%Y %H:%M:%S", timeinfo);
      printf("%s\n", buffer);
    } else {
      printf("NTP Error\n");
    }
*/

    Thread thread(netio_server);

    while(1) {
        Thread::wait(60000);
    }
    
    // eth.disconnect();
}