/*!
 * @file       tcp_client_test.c
 *
 * @brief      tcp client test program body
 *
 * @version    V1.0.0
 *
 * @date       2022-11-15
 *
 * @attention
 *
 *  Copyright (C) 2022 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

/* Includes */
#include <stdio.h>
#include <string.h>

#include "main.h"
#include "lwip/sockets.h"

/** @addtogroup Examples
  * @{
  */

/** @addtogroup ETH_RTT_TcpClient
  * @{
  */

/** @defgroup ETH_RTT_TcpClient_Macros Macros
  @{
*/

/* Tcp Server IP */
#define TCP_SERVER_IP      "169.254.90.242"

/* Tcp Server Port */
#define TCP_SERVER_PORT    (5005)

/* tcp client receive data buffer size */
#define BUFF_SIZE       (128)

/**@} end of group ETH_RTT_TcpClient_Macros */

/** @defgroup ETH_RTT_TcpClient_Variables Variables
  * @{
  */

/* tcp client receive data buffer */
char recv_buff[BUFF_SIZE];

/**@} end of group ETH_RTT_TcpClient_Variables */

/** @defgroup ETH_RTT_TcpClient_Functions Functions
  * @{
  */

/*!
 * @brief       Tcp Client task
 *
 * @param       pvParameters: passed into the task function as the function parameters
 *
 * @retval      None
 */
static void tcp_client_task(void *pParams)
{
    int ret = -1;
    int sock = -1;
    int bytes_received = 0;
    struct sockaddr_in server_addr;
    
    printf("please connect tcp server IP: 169.254.90.123, Port: 5005\r\n");
    
    while (1)
    {
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            printf("Socket error.\n");
            rt_thread_delay(1000);
            continue;
        }
        
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(TCP_SERVER_PORT);
        server_addr.sin_addr.s_addr = inet_addr(TCP_SERVER_IP);
        memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

        if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
        {
            printf("Connect fail.\r\n");
            closesocket(sock);
            rt_thread_delay(1000);
            continue;
        }

        printf("Connect Tcp Server successful.\r\n");
        
        while (1)
        {
            bytes_received = recv(sock, recv_buff, BUFF_SIZE - 1, 0);
            if (bytes_received <= 0)
            {
                closesocket(sock);
                printf("\r\nreceived error, close the socket.\r\n");
                break;
            }
            else if (bytes_received == 0)
            {
                closesocket(sock);
                printf("\r\nreceived error,close the socket.\r\n");
                break;
            }

            recv_buff[bytes_received] = '\0';
            printf("\r\nReceived data: %s \r\n", recv_buff);

            ret = send(sock, recv_buff, bytes_received, 0);
            if (ret < 0)
            {
                closesocket(sock);
                printf("\r\nsend error,close the socket.\r\n");
                break;
            }
            else if (ret == 0)
            {
                closesocket(sock);
                printf("\r\n Send warning, send function return 0.\r\n");
                break;
            }
        }
    }
}

/*!
 * @brief       Initialize Tcp Client task.
 *
 * @param       None
 *
 * @retval      None
 *
 * @note
 */
void tcp_client_task_init(void)
{
    sys_thread_new("tcp_client_task", tcp_client_task, NULL, 512, 3);
}

/**@} end of group ETH_RTT_TcpClient_Functions */
/**@} end of group ETH_RTT_TcpClient */
/**@} end of group Examples */
