PicoTCP robustness Test

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

main.cpp

Committer:
tass
Date:
2014-04-09
Revision:
5:16d6db68e32f
Parent:
4:0406e4e7639f

File content as of revision 5:16d6db68e32f:

/*
*   This is an endurance test that downloads text, an image and a pdf file from the web in a loop using PicoTCP
*   Debug output is printed to the USB serial port (what it is doing and memory stats)
*/
#include "mbed.h"
#include <stdarg.h>
#include "EthernetInterface.h"

#define msgdbg(...)

//#define msgdbg printf

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

#define NUMBER_OF_HOSTS   3

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

#define HOST_2              "www.mbed.org"
#define HOST_2_REQUEST      "GET /media/img/boardlogos/lpc1768/pinout.png\nHost: www.mbed.org\n\n"

#define HOST_3              "www.nxp.com"
#define HOST_3_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 sumDuration;
    int maxReceived;
    int minReceived;
    int snapshots;
};

struct WebStats webStatistics[NUMBER_OF_HOSTS]=
{
    {HOST_1_REQUEST,HOST_1,0,0,0x7FFFFFFF,0},
    {HOST_2_REQUEST,HOST_2,0,0,0x7FFFFFFF,0},
    {HOST_3_REQUEST,HOST_3,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].sumDuration / webStatistics[i].snapshots);
        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 + 1);
        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", (int)memoryStats.curFreeRam);
    printf("Maximum free memory : %d bytes\n", (int)memoryStats.maxFreeRam);
    printf("Minimum free memory : %d bytes\n", (int)memoryStats.minFreeRam);
    printf("Average free memory : %d bytes\n", (int)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("[%llu] DHCP timeout %d\n",PICO_TIME_MS(),retries);
        if(retries >= DHCP_RETRIES)
        {
            printf("DHCP failed. Bailing out..\n");
            goto failure;
        }
    };

    printf("[%llu] Starting the robustness test...\n",PICO_TIME_MS());

    while(1)
    {
        printf("Starting cycle ****************************************\n");
        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, 8000);
            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, skipping. Ret = %d, err = %d\n", ret, pico_err);
                        break;
                    }
                    client.close();
                    break;
                } else {
                    received += ret;
                }

                if(retries == READING_RETRIES) {
                    printf("Read operation failed too many times: skipping.\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);
            webStatistics[i].sumDuration += time;
            webStatistics[i].snapshots++;
            totalTime += time;
            memoryStamp();
        }

        printStatistics();
        Thread::wait(500);
    }
    failure:
    printf("Fatal error. Main thread is inactive\n");
    while(1);
}