#include <string.h>
#include "wm_include.h"
#include "wm_demo.h"
#include "iperf.h"
#include "lwip/inet.h"
#include "wm_cmdp.h"


#if (DEMO_IPERF_AUTO_TEST && TLS_CONFIG_WIFI_PERF_TEST && TLS_IPERF_AUTO_TEST)


u8 iperf_test_info[15] = {0};

u8 iperf_test_rev[10] = {0};
u8 sever_ip[16];
u16 iperfLocalPort = 0;

extern 	tls_os_queue_t *tht_q;
extern struct tht_param gThtSys;
extern void CreateThroughputTask(void);

void iperf_start(u8 mode, u8 chnl, u8 interval, u32 maxcnt, u16 localport, u32 severIp)
{
    struct tht_param *tht = (struct tht_param *)(&gThtSys);

    CreateThroughputTask();

    if(mode)
    {
        tht->role = 's';
    }
    else
    {
        tht->role = 'c';

        inet_ntoa_r(severIp, (char *)sever_ip, 16);
        strcpy(tht->server_hostname, (char *)sever_ip);
        printf("ipaddr:%s\n", tht->server_hostname);

        tht->protocol = Pudp;
        tht->rate = 0;
        tht->block_size = 0;
    }

    tht->localport = localport;

    tht->report_interval = interval;
    tht->duration = maxcnt;
    tht->port = chnl + PORT - 1;

    tls_os_queue_send(tht_q, (void *)TLS_MSG_WIFI_PERF_TEST_START, 0);
}


int demo_iperf_auto_test(u8 *ssid, u8 csmode, u8 remoteIP, u8 bgnrate, u8 pcrate, u8 interval, u32 maxcnt)
{
    int ret = -1;
    u16 i;
    int ipefTestSock;
    u8 destip[4];
    u32 severIp;
    struct tls_cmd_wl_hw_mode_t hw_mode;
    struct tls_cmd_link_status_t lk;


    memset(&hw_mode, 0, sizeof(struct tls_cmd_wl_hw_mode_t));
    hw_mode.hw_mode = 2;
    hw_mode.max_rate = bgnrate;
    ret = tls_cmd_set_hw_mode(&hw_mode, 1);

    if (!ssid)
    {
        return WM_FAILED;
    }

    printf("\nssid:%s\n", ssid);

    ret = tls_wifi_connect(ssid, strlen((char *)ssid), NULL, 0);
    while(WM_WIFI_JOINED != tls_wifi_get_state())
    {
        tls_os_time_delay(2);
    }

    memset(&lk, 0, sizeof(struct tls_cmd_link_status_t));
    while(lk.ip[0] == 0)
    {
        tls_cmd_get_link_status(&lk);
        tls_os_time_delay(2);
    }

    memcpy(&destip[0], &lk.ip[0], 4);
    destip[3] = remoteIP;
    memcpy(&severIp, &destip[0], 4);

    iperfLocalPort ++;
    if(iperfLocalPort > 20)
    {
        iperfLocalPort = 0;
    }

    ipefTestSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(ipefTestSock < 0)
    {
        printf("iperf test socket creat err\n");
        return WM_FAILED;;
    }

    if(csmode)		//iperf ×÷Îª·þÎñ¶Ë
    {
        printf("iperf test sever start\n");
        iperf_start(csmode, destip[2] - 100, interval, maxcnt, iperfLocalPort, severIp);
    }

    struct sockaddr_in localAddr;
    memset(&localAddr, 0, sizeof(struct sockaddr_in));
    localAddr.sin_family = AF_INET;
    localAddr.sin_port = htons(20000 + iperfLocalPort);
    memcpy(&localAddr.sin_addr.s_addr, &lk.ip[0], 4);
    printf("iperf test port:%d\n", 20000 + iperfLocalPort);

    if (bind(ipefTestSock, (const struct sockaddr *)&localAddr, sizeof(const struct sockaddr_in)) < 0)
    {
        printf("iperf test bind err\n");
        return WM_FAILED;
    }

    struct sockaddr_in iperfAddr;
    memset(&iperfAddr, 0, sizeof(struct sockaddr_in));
    iperfAddr.sin_family = AF_INET;
    iperfAddr.sin_port = htons(30000);
    iperfAddr.sin_addr.s_addr = severIp;

    i = 0;
    while (0 != connect(ipefTestSock, (const struct sockaddr *)&iperfAddr, sizeof(const struct sockaddr_in)))
    {
        printf("iperf test connect err\n");
        if(i++ > 5)
        {
            closesocket(ipefTestSock);
            return WM_FAILED;
        }
    }

    iperf_test_info[0] = csmode;
    iperf_test_info[1] = destip[2] - 100;
    memcpy(&iperf_test_info[2], &lk.ip[0], 4);
    iperf_test_info[6] = pcrate;
    iperf_test_info[7] = interval;
    memcpy(&iperf_test_info[8], &maxcnt, 4);

    if(send(ipefTestSock, (const char *)iperf_test_info, 12, 0) < 0)
    {
        printf("iperf test tcp send err\n");
        closesocket(ipefTestSock);
        return WM_FAILED;
    }

    if(csmode == 0)
    {
        ret = recv(ipefTestSock, iperf_test_rev, 10, 0);
        if(ret > 0)
        {
            ret = strcmp((const char *)iperf_test_rev, "OK");
            closesocket(ipefTestSock);
            if(ret == 0)
            {
                printf("iperf test client start\n");
                tls_os_time_delay(100);
                iperf_start(csmode, destip[2] - 100, interval, maxcnt, iperfLocalPort, severIp);
            }
        }
        else
        {
            printf("iperf test tcp recv err\n");
            closesocket(ipefTestSock);
            return WM_FAILED;
        }
    }
    else
    {
        closesocket(ipefTestSock);
    }

    return WM_SUCCESS;
}



#endif


