/**
******************************************************************************
* @file    			main.c
* @version 			V1.0
* @date    			2024-08-21
* @brief 		    Main function entry
*
* @company  		WIZnet
* @website  		https://wiznet.io/
* @gitee            https://gitee.com/wiznet-hk
* @github           https://github.com/Wiznet/
******************************************************************************
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "wizchip_conf.h"
#include "wiz_interface.h"
#include "bsp_tim.h"
#include "bsp_uart.h"
#include "bsp_rcc.h"
#include "delay.h"
#include "socket.h"
#include "iperf.h"
#include "cJSON.h"

#define DEFAULT_MAC_EN        1                   //1: Use the default MAC address, 0: Use the user - defined MAC address
#define SOCKET_ID             0

/* network information */
wiz_NetInfo default_net_info = {
    .mac  = {0x00, 0x08, 0xdc, 0x12, 0x22, 0x12}, //User-defined MAC address
    .ip   = {192, 168, 2, 30},
    .gw   = {192, 168, 2, 1},
    .sn   = {255, 255, 255, 0},
    .dns  = {8, 8, 8, 8},
    .dhcp = 1
};

uint8_t  ethernet_buf_tx[ETHERNET_BUF_MAX_SIZE] = {0};
uint8_t  ethernet_buf_rx[ETHERNET_BUF_MAX_SIZE] = {0};
uint8_t  dest_ip[4]                          = {192, 168, 2, 44};
uint16_t dest_port                           = 8080;
uint8_t  tx_size[_WIZCHIP_SOCK_NUM_]         = {8, 8, 0, 0, 0, 0, 0, 0};
uint8_t  rx_size[_WIZCHIP_SOCK_NUM_]         = {8, 8, 0, 0, 0, 0, 0, 0};

int main(void)
{
	 wiz_NetInfo net_info;
	  bool reverse = false;
	  bool udp = false;
    uint8_t remote_ip[4];
    uint16_t remote_port;
    uint8_t socket_status;
    Stats stats;
    /* hardware initialization */
    rcc_clk_config();
    delay_init();

    console_usart_init(115200);

    tim3_init();
    printf("W55MH32 iperf3 ethernet test example\r\n");

   wiz_toe_init();
#if DEFAULT_MAC_EN == 1
    getSHAR(default_net_info.mac);
#endif

    wiz_phy_link_check();

    network_init(ethernet_buf_rx, &default_net_info);
    wizchip_getnetinfo(&net_info);
    wizchip_init(tx_size, rx_size);
    for (uint16_t i = 0; i < ETHERNET_BUF_MAX_SIZE; i++)
    {
        ethernet_buf_tx[i] = 65 + i % 26;
    }
    socket(SOCKET_CTRL, Sn_MR_TCP, PORT_IPERF, Sn_MR_ND);
    listen(SOCKET_CTRL);
		printf("The iperf3 test is ready. Please enter the following command for testing:\r\n");
		printf("TCP RX: iperf3 -c %d.%d.%d.%d -p 5007\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
		printf("TCP TX: iperf3 -c %d.%d.%d.%d -p 5007 -R\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
		printf("UDP RX: iperf3 -c %d.%d.%d.%d -p 5007 -u -b 100M -l 4000\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
		printf("UDP TX: iperf3 -c %d.%d.%d.%d -p 5007 -u -b 100M -R\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
    /* Enable keepalive,Parameter 2 is the keep alive time, with a unit of 5 seconds */
    setSn_KPALVTR(SOCKET_ID, 6); // 30s keepalive

    while (1)
    {
         stats_init(&stats, 1000);
        socket_status = getSn_SR(SOCKET_CTRL);
        if (socket_status == SOCK_ESTABLISHED)
        {
            handle_param_exchange(SOCKET_CTRL, &reverse, &udp);
            handle_create_streams(SOCKET_CTRL, udp, remote_ip, &remote_port);

            start_iperf_test(SOCKET_CTRL, SOCKET_DATA, &stats, reverse, udp, remote_ip, &remote_port);
            close(SOCKET_DATA);
            disconnect(SOCKET_CTRL);
        }
        else if (socket_status == SOCK_CLOSE_WAIT)
        {
            disconnect(SOCKET_CTRL);
        }
        else if (socket_status == SOCK_CLOSED)
        {
            socket(SOCKET_CTRL, Sn_MR_TCP, PORT_IPERF, Sn_MR_ND);
            listen(SOCKET_CTRL);
					  printf("The iperf3 test is ready. Please enter the following command for testing:\r\n");
						printf("The iperf3 test is ready. Please enter the following command for testing:\r\n");
						printf("TCP RX: iperf3 -c %d.%d.%d.%d -p 5007\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
						printf("TCP TX: iperf3 -c %d.%d.%d.%d -p 5007 -R\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
						printf("UDP RX: iperf3 -c %d.%d.%d.%d -p 5007 -u -b 100M -l 4000\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
						printf("UDP TX: iperf3 -c %d.%d.%d.%d -p 5007 -u -b 100M -R\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
        }
    }
    
    }

