/**
  ******************************************************************************
  * @file    iot_HAL_TCP_stm32.c
  * @author  MCD Application Team
  * @brief   This file provides a set of functions to support Ali IoT kit on STM32
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics International N.V. 
  * All rights reserved.</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without 
  * modification, are permitted, provided that the following conditions are met:
  *
  * 1. Redistribution of source code must retain the above copyright notice, 
  *    this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. Neither the name of STMicroelectronics nor the names of other 
  *    contributors to this software may be used to endorse or promote products 
  *    derived from this software without specific written permission.
  * 4. This software, including modifications and/or derivative works of this 
  *    software, must execute solely and exclusively on microcontroller or
  *    microprocessor devices manufactured by or for STMicroelectronics.
  * 5. Redistribution and use of this software other than as permitted under 
  *    this license is void and will automatically terminate your rights under 
  *    this license. 
  *
  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 
  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 
  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

#include "wifi.h"

#define WIFI_WRITE_TIMEOUT   200
#define WIFI_READ_TIMEOUT    200
#define WIFI_PAYLOAD_SIZE    1200
#define WIFI_READ_RETRY_TIME 5

uintptr_t HAL_TCP_Establish(const char *host, uint16_t port)
{
    WIFI_Status_t ret;
    uint8_t ip_addr[20];
    int fd = 1;

    ret = WIFI_GetHostAddress((char *)host, ip_addr);
    if (ret != WIFI_STATUS_OK) {
        printf("HAL_TCP_Establish: get host addr fail - %d\n", ret);
        return (uintptr_t)-1;
    }

    ret = WIFI_OpenClientConnection(0, WIFI_TCP_PROTOCOL, "", ip_addr, port, 0);
    if (ret != WIFI_STATUS_OK) {
        printf("HAL_TCP_Establish: open client fail - %d\n", ret);
        return (uintptr_t)-1;
    }
    return fd;
}
int32_t HAL_TCP_Destroy(uintptr_t fd)
{
    WIFI_Status_t ret;


    ret = WIFI_CloseClientConnection(0);
    if (ret != WIFI_STATUS_OK) {
        printf("HAL_TCP_Destroy: close client fail - %d\n", ret);
        return -1;
    }
    return 0;
}
int32_t HAL_TCP_Write(uintptr_t fd, const char *buf, uint32_t len, uint32_t timeout_ms)
{
    WIFI_Status_t ret;
    uint16_t send_size;


    ret = WIFI_SendData(0,
                        (uint8_t *)buf, len,
                        &send_size, WIFI_WRITE_TIMEOUT);
    if (ret != WIFI_STATUS_OK) {
        printf("HAL_TCP_Write: send data fail - %d\n", ret);
        return -1;
    }
    return send_size;
}
int32_t HAL_TCP_Read(uintptr_t fd, char *buf, uint32_t len, uint32_t timeout_ms)
{
    WIFI_Status_t ret;
    uint16_t recv_size;


    if (len > WIFI_PAYLOAD_SIZE) {
        len = WIFI_PAYLOAD_SIZE;
    }
    ret = WIFI_ReceiveData(0,
                            (uint8_t *)buf, (uint16_t)len,
                            &recv_size, WIFI_READ_TIMEOUT);
    if (ret != WIFI_STATUS_OK) {
        printf("HAL_TCP_Read: receive data fail - %d\n", ret);
        return -1;
    }
    return recv_size;
}

/**
 * @brief Establish a UDP connection.
 *
 * @param [in] host: @n Specify the hostname(IP) of the UDP server
 * @param [in] port: @n Specify the UDP port of UDP server
 *
 * @retval  < 0 : Fail.
 * @retval >= 0 : Success, the value is handle of this UDP connection.
 * @see None.
 */
void *HAL_UDP_create(char *host, unsigned short port)
{
	return 0;
}

/**
 * @brief Destroy the specific UDP connection.
 *
 * @param [in] p_socket: @n Specify the UDP connection by handle.
 * @return None.
 * @see None .
 */
void HAL_UDP_close(void *p_socket)
{
	
}

/**
 * @brief Write data into the specific UDP connection.
 *
 * @param [in] p_socket @n A descriptor identifying a connection.
 * @param [in] p_data @n A pointer to a buffer containing the data to be transmitted.
 * @param [in] datalen @n The length, in bytes, of the data pointed to by the 'p_data' parameter.

 * @retval          < 0 : UDP connection error occur.
 * @retval [0,datalen ] : The number of bytes sent.
 * @see None.
 */
int HAL_UDP_write(void *p_socket, const unsigned char *p_data, unsigned int datalen)
{
	return 0;
}
/**
 * @brief Read data from the specific UDP connection by blocked
 *
 * @param [in] p_socket @n A descriptor identifying a UDP connection.
 * @param [in] p_data @n A pointer to a buffer to receive incoming data.
 * @param [out] datalen @n The length, in bytes, of the data pointed to by the 'p_data' parameter.
 * @return
 *
 * @retval < 0 : UDP connect error occur.
 * @retval = 0 : End of file.
 * @retval > 0 : The number of byte read.
 * @see None.
 */
int HAL_UDP_read(void *p_socket, unsigned char *p_data, unsigned int datalen)
{
	return 0;
}

/**
 * @brief Read data from the specific UDP connection with timeout parameter.
 *        The API will return immediately if 'datalen' be received from the specific UDP connection.
 *
 * @param [in] p_socket @n A descriptor identifying a UDP connection.
 * @param [out] p_data @n A pointer to a buffer to receive incoming data.
 * @param [out] datalen @n The length, in bytes, of the data pointed to by the 'p_data' parameter.
 * @param [in] timeout_ms @n Specify the timeout value in millisecond. In other words, the API block timeout_ms millisecond maximumly.
 *
 * @retval          -4 : UDP connect error occur.
 * @retval          -3 : The  call  was interrupted by a signal before any data was read.
 * @retval          -2 : No any data be received in 'timeout_ms' timeout period.
 * @retval          -1 : Invalid parameter.
 * @retval           0 : End of file.
 * @retval (0,datalen] : The number of byte read.
 * @see None.
 */
int HAL_UDP_readTimeout(void *p_socket, unsigned char *p_data, unsigned int datalen, unsigned int timeout_ms)
{
	return 0;
}
