PicoTCP robustness Test

Dependencies:   PicoTCP lpc1768-picotcp-eth mbed-rtos mbed

main.cpp

Committer:
tass
Date:
2013-07-26
Revision:
2:c0838e12f038
Parent:
1:97b1710fd9c3
Child:
3:457043c6a3a6

File content as of revision 2:c0838e12f038:

#include "mbed.h"
#include <stdarg.h>
#include "EthernetInterface.h"

#define msgdbg(...)

//#define msgdbg printf


#define SENDING_RETRIES    3u
#define READING_RETRIES    7u
#define DHCP_RETRIES       10u
#define BUFFER_SIZE        256

#define NUMBER_OF_HOSTS   3u

#define MBED_HOST               "www.mbed.org"
#define MBED_HOST_REQUEST       "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\n\n"

#define MEDIAFAX_HOST           "www.mediafax.ro"
#define MEDIAFAX_HOST_REQUEST   "GET / HTTP/1.1\nHost: www.mediafax.ro\n\n"

#define NXP_HOST                "www.nxp.com"
#define NXP_HOST_REQUEST        "GET /documents/user_manual/UM10360.pdf HTTP/1.0\nHost: www.nxp.com\n\n"

int totalTime = 0;

struct WebStats
{
    char request[70];
    char host[20];
    int avgDuration;
    int maxReceived;
    int minReceived;
    int snapshots;
};

struct WebStats webStatistics[NUMBER_OF_HOSTS]= 
{
    {MBED_HOST_REQUEST,MBED_HOST,0,0,0x7FFFFFFF,0},
    {MEDIAFAX_HOST_REQUEST,MEDIAFAX_HOST,0,0,0x7FFFFFFF,0},
    {NXP_HOST_REQUEST,NXP_HOST,0,0,0x7FFFFFFF,0}
};

void inline printMemoryStats(void);
void printStatistics(void)
{
    printf("\nTotal Time : %f seconds\n",(float)totalTime/1000.0f);    
    for(int i=0;i<NUMBER_OF_HOSTS;i++)
    {
        printf("Host number : %d | %s\n",i, webStatistics[i].host);
        printf("MaxRecv : %d\n",webStatistics[i].maxReceived);
        printf("MinRecv : %d\n",webStatistics[i].minReceived);
        printf("Avg duration : %d ms\n",webStatistics[i].avgDuration);
        printf("Total snapshots : %d\n\n",webStatistics[i].snapshots);
    }
    printMemoryStats();    
}

struct MemoryUsage
{
    uint32_t curFreeRam;
    uint32_t minFreeRam;
    uint32_t maxFreeRam;
    uint32_t avgFreeRam;
    uint32_t stackPointer;
    uint32_t cntSamples;
};

struct MemoryUsage memoryStats = {0,0xFFFFFFFF,0,0,0};

int fakePrintf(void* pvHeapInfo, char const* pFormatString, ...)
{
    struct MemoryUsage * memStat = (struct MemoryUsage *)pvHeapInfo;
    static const char* freeRamFormat = "%d bytes in";
    va_list valist;
    
    if(memcmp(pFormatString,freeRamFormat,strlen(freeRamFormat)) == 0)
    {
        va_start(valist, pFormatString);
        unsigned long freeSize = va_arg(valist, unsigned long);
        memStat->curFreeRam = freeSize;
        if(memStat->minFreeRam > freeSize)
            memStat->minFreeRam = freeSize;
        
        if(memStat->maxFreeRam < freeSize)
            memStat->maxFreeRam = freeSize;
            
        memStat->avgFreeRam = ((memStat->avgFreeRam * memStat->cntSamples) + freeSize)/(++memStat->cntSamples);
    }
    else
    {
        // ignore format
    }
    return 0;
}

void inline printMemoryStats(void)
{
    if(memoryStats.cntSamples == 1)
        printf("\n\n***** Initial Memory Report *****\n");
    else
        printf("\n\n********* Memory Report *********\n");
    
    printf("Current free memory : %d bytes\n",memoryStats.curFreeRam);
    printf("Maximum free memory : %d bytes\n",memoryStats.maxFreeRam);
    printf("Minimum free memory : %d bytes\n",memoryStats.minFreeRam);
    printf("Average free memory : %d bytes\n",memoryStats.avgFreeRam);
    printf("****************************\n");
}

void inline memoryStamp(void)
{
    __heapstats((__heapprt)fakePrintf, &memoryStats);
}


int main() {
    
    int retries = 0;
    EthernetInterface eth;
    TCPSocketConnection client;
    
    printf("Initialising...\n");

    // use DHCP
    eth.init();

    // attempt DHCP and if timing out then try again
    while (eth.connect()) {
        retries++;
        printf("[%d] DHCP timeout %d\n",PICO_TIME_MS(),retries);
        if(retries >= DHCP_RETRIES)
        {
            printf("DHCP failed. Bailing out..\n");
            goto failure;
        }
    };
    
    printf("[%d] Starting the robustness test...\n",PICO_TIME_MS());
    
    while(1) 
    {
        for(int i=0;i<NUMBER_OF_HOSTS;i++,client.close())
        {
            int retries = 0;
            int received = 0;
            int time = 0;
            char tmpBuffer[BUFFER_SIZE];
            int ret;
            
            printf("Mbed --> %s\n",webStatistics[i].host);
            
            time = PICO_TIME_MS();
            // connecting
            if (client.connect(webStatistics[i].host, 80)) {
                printf("Failed to connect to : %s\n",webStatistics[i].host);
                continue;
            }                    
            
            client.set_blocking(false,1500);
            retries = 0;
            
            // sending request

            ret = client.send_all(webStatistics[i].request,strlen(webStatistics[i].request));
            if (ret <= 0) 
            {
                printf("This test failed big time, ret=%d, err=%d!!\n", ret, pico_err);
                while(1);;;
            }
            
            retries = 0;
            // start reading
            while(true)
            {
                ret = client.receive(tmpBuffer,sizeof(tmpBuffer));
                if (ret == 0) {
                    printf("Read timeout: ret = %d, err = %d, retry = %d\n", ret, pico_err, retries);
                    retries++;
                } else if (ret < 0) {
                    if (pico_err != PICO_ERR_ESHUTDOWN) {
                        printf("Read error, bailing out. Ret = %d, err = %d\n", ret, pico_err);
                        while(1);;;
                    }
                    client.close();
                    break;
                } else {
                    received += ret;
                }
                
                if(retries == READING_RETRIES) {
                    printf("Read operation failed too many times. Giving up.\n");
                    break;
                }      
            }
            
            
            
            //Snapshot!
            time = PICO_TIME_MS() - time;
            
            if(webStatistics[i].maxReceived < received)
            {
                webStatistics[i].maxReceived = received;
            }
            
            if(webStatistics[i].minReceived > received)
            {
                webStatistics[i].minReceived = received;
            }
            printf("Received : %d bytes\n",received);
            if (received <= 0) {
               printf("Test FAILED!\n"); 
               while(1);;;  
            }
            webStatistics[i].avgDuration = ((webStatistics[i].avgDuration *(webStatistics[i].snapshots++) ) + time)/webStatistics[i].snapshots;
            totalTime += time;
            memoryStamp();
        }
        
        printStatistics();
        Thread::wait(500);
    }
    failure:    
    printf("Fatal error. Main thread is inactive\n");
    while(1);
}