

#include <stdlib.h>

/* TI-DRIVERS Header files */
#include <ti/drivers/net/wifi/simplelink.h>
#ifdef CC32XX
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC32XX.h>
#endif
/* Example Header files */
#include "cmd_parser.h"
#include <luckcome_doppler.h>
#include "wlan_cmd.h"
#include "transceiver_cmd.h"
#include "userInfo.h"

/* Application defines */
#define WLAN_EVENT_TOUT             (6000)
#define MAX_SCAN_TRAILS             (10)
#define P2P_CONNECT_PRIORITY        (SPAWN_TASK_PRIORITY - 1)
#define P2P_STACK_SIZE              (2048)
#define P2P_REMOTE_DEVICE           ("StartScan")
#define P2P_DEVICE_TYPE             ("1-0050F204-1")
#define P2P_DEVICE_NAME             ("cc32xx_p2p_device")
#define LISTEN_CHANNEL              (11)
#define LISTEN_REGULATORY_CLASS     (81)
#define OPRA_CHANNEL                (6)
#define OPRA_REGULATORY_CLASS       (81)
#define TIMEOUT_SEM                 (-1)
#define LPDS_WAKEUP_SW              (1)
#define MGMT                        (0)
#define CTRL                        (1)
#define DATA                        (2)
#define CC3x35_BIT                  (0x100000)

#ifdef SECURE_SOCKET
#define TCP_PROTOCOL_FLAGS    SL_SEC_SOCKET
#define ROOT_CA_CERT_FILE     "dummy-root-ca-cert"
#define PRIVATE_KEY_FILE      "dummy-trusted-cert-key"
#define TRUSTED_CERT_FILE     "dummy-trusted-cert"
#define TRUSTED_CERT_CHAIN    "trusted-chain.pem"

#define DEVICE_YEAR                 (2017)
#define DEVICE_MONTH                (4)
#define DEVICE_DATE                 (5)

#define BUF_LEN                (MAX_BUF_SIZE - 20)
#else
#define TCP_PROTOCOL_FLAGS      0
#define BUF_LEN                (MAX_BUF_SIZE)
#endif
#define SERIALWIFI_NET_BUFFER_SIZE          (1024)

typedef union
{
    SlSockAddrIn6_t in6;       /* Socket info for Ipv6 */
    SlSockAddrIn_t in4;        /* Socket info for Ipv4 */
}sockAddr_t;


int32_t setStaticIPConfig(uint8_t* pIP,
                          uint8_t* pGw,
                          uint8_t* pDns);
int32_t sendConnectionReq(void);
int32_t setP2Pparams(void);
void printScanResults(uint32_t res_num);
void printExtScanResults(uint32_t res_num);
void *p2pConnect(void *arg);


int32_t sock = -1;
extern  wifiStatus;
uint8_t sendErrorcount = 0;
unsigned char netReceiveBuffer[SERIALWIFI_NET_BUFFER_SIZE];

int32_t SendTcp(uint8_t* pData,uint16_t len, uint8_t nb)
{
    int32_t status = 0;

    if(2 == wifiStatus)
    {
        status = sl_Send(sock, pData, len, 0);
        if(status < 0)
        {
            UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status,SL_SOCKET_ERROR);
            UART_PRINT("SendTcp()->sendErrorcount: %d\n\r", sendErrorcount);
            sendErrorcount++;
            if(sendErrorcount > 0)//连续5个包都发送失败的话，则重启WIFI连接
            {
                sendErrorcount = 0;
                wifiStatus = 1;
            }
            return(-1);
        }else{
            sendErrorcount = 0;
        }
    }
    return 0;
}

int32_t ReceiveTcp(void)
{
    int32_t bytesRx = 0;
    if(2 == wifiStatus)
    {
        bytesRx = sl_Recv(sock,
                          netReceiveBuffer,
                          SERIALWIFI_NET_BUFFER_SIZE,
                          0);
        GetTcpPackage(netReceiveBuffer,bytesRx);
    }
}




signed short shocketNum = 0;
extern int32_t ipv4_lost;
int32_t TCPClient(uint8_t nb,
                  uint16_t portNumber,
                  ip_t ipAddress,
                  uint8_t ipv6,
                  uint32_t numberOfPackets,
                  uint8_t tx)
{

    int32_t status;
    uint32_t i = 0;
    int32_t nonBlocking;
    SlSockAddr_t        *sa;
    int32_t addrSize;
    sockAddr_t sAddr;

    /* clear the global data buffer */
    memset(app_CB.gDataBuffer.nwData, 0x0, MAX_BUF_SIZE);

    /* filling the buffer with data */
    for(i = 0; i < MAX_BUF_SIZE; i++)
    {
        app_CB.gDataBuffer.nwData[i] = (char)(i % 10);
    }

    if(ipv6)
    {
        sAddr.in6.sin6_family = SL_AF_INET6;
        sAddr.in6.sin6_port = sl_Htons(portNumber);
        sAddr.in6.sin6_flowinfo = 0;

        sAddr.in6.sin6_addr._S6_un._S6_u32[0] =
            ((unsigned long*)ipAddress.ipv6)[0];
        sAddr.in6.sin6_addr._S6_un._S6_u32[1] =
            ((unsigned long*)ipAddress.ipv6)[1];
        sAddr.in6.sin6_addr._S6_un._S6_u32[2] =
            ((unsigned long*)ipAddress.ipv6)[2];
        sAddr.in6.sin6_addr._S6_un._S6_u32[3] =
            ((unsigned long*)ipAddress.ipv6)[3];
        sa = (SlSockAddr_t*)&sAddr.in6;
        addrSize = sizeof(SlSockAddrIn6_t);
    }
    else
    {
        /* filling the TCP server socket address */
        sAddr.in4.sin_family = SL_AF_INET;

        /* Since this is the client's side,
         * we must know beforehand the IP address
         * and the port of the server wer'e trying to connect.
         */
        sAddr.in4.sin_port = sl_Htons((unsigned short)portNumber);
        sAddr.in4.sin_addr.s_addr = sl_Htonl((unsigned int)ipAddress.ipv4);

        sa = (SlSockAddr_t*)&sAddr.in4;
        addrSize = sizeof(SlSockAddrIn6_t);
    }

    if(sock >= 0){
        shocketNum = sl_Close(sock);
    }
    UART_PRINT("\t old sock:  %d",sock);
    sock = sl_Socket(sa->sa_family, SL_SOCK_STREAM, TCP_PROTOCOL_FLAGS);
    UART_PRINT("\t new sock:  %d",sock);

    ASSERT_ON_ERROR(sock, SL_SOCKET_ERROR);

    /* Set socket as non-blocking socket (if needed):
     * Non-blocking sockets allows user to handle
     * other tasks rather than block
     * on socket API calls.
     * If an API call using the Non-blocking socket descriptor
     * returns 'SL_ERROR_BSD_EAGAIN' -
     * this indicate that the user should try the API again later.
     */
    if(TRUE == nb)
    {
        nonBlocking = TRUE;
        status =
            sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlocking,
                          sizeof(nonBlocking));
        UART_PRINT("\t sl_SetSockOpt:  %d",status);
        if(status < 0)
        {
            UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status,
                       SL_SOCKET_ERROR);
            sl_Close(sock);
            return(-1);
        }
    }
    status = -1;
    while(status < 0)
    {
        /* Calling 'sl_Connect' followed by server's
         * 'sl_Accept' would start session with
         * the TCP server. */
        if(ipv4_lost == -1)
        {
            UART_PRINT("\t ipv4_lost:  %d",ipv4_lost);
            sleep(1);
            continue;
        }
        status = sl_Connect(sock, sa, addrSize);
        UART_PRINT("\t sl_Connect:  %d",status);
        if((status == SL_ERROR_BSD_EALREADY)&& (TRUE == nb))
        {
            sleep(1);
            continue;
        }
        else if(status < 0)
        {
            UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status,
                       SL_SOCKET_ERROR);
            sl_Close(sock);
            return(-1);
        }
        break;
    }
    UART_PRINT("\t sl_Connect ok");
    return(0);
}



int32_t WlanConnect(void)
{
    int32_t ret = 0;
    ConnectCmd_t ConnectParams;

 /*add by edison*/
    sl_WlanDisconnect();
    app_CB.Status = 0 ;
 /*end add by edison**/

    memset(&ConnectParams, 0x0, sizeof(ConnectCmd_t));

    ConnectParams.ip = NULL;
    ConnectParams.dns = NULL;
    ConnectParams.gw = NULL;
    ConnectParams.ssid = wifiLocalPara.ssid;
    ConnectParams.secParams.Type = SL_WLAN_SEC_TYPE_WPA_WPA2;
    ConnectParams.secParams.Key = wifiLocalPara.passwd;
    ConnectParams.secParams.KeyLen = strlen(ConnectParams.secParams.Key);

    if(app_CB.Role != ROLE_STA)
    {
        ret = sl_WlanSetMode(ROLE_STA);
        ret = sl_Stop(SL_STOP_TIMEOUT);
        ret = sl_Start(0, 0, 0);


        /* Here we are in STA mode */
        app_CB.Role = ret;
    }
    cmdSetPolicyCallback();
    /* Connect to AP */
    ret = sl_WlanConnect((const signed char *)(ConnectParams.ssid),
                       strlen((const char *)(ConnectParams.ssid)),
                       0,
                       &ConnectParams.secParams,
                       0);


    /* Wait for connection events:
     * In order to verify that connection was successful,
     * we pend on two incoming events: Connected and Ip acquired.
     * The semaphores below are pend by this (Main) context.
     * They will be signaled once an asynchronous event
     * Indicating that the NWP has connected and acquired IP address is raised.
     * For further information, see this application read me file.
     */
    if(!IS_CONNECTED(app_CB.Status))
    {
        ret = sem_wait_timeout(&app_CB.CON_CB.connectEventSyncObj,
                               WLAN_EVENT_TOUT);
        if(ret == TIMEOUT_SEM)
        {
            UART_PRINT("\n\r[wlanconnect] : Failed to connect to AP: %s\n\r",
                       ConnectParams.ssid);
            return(-1);
        }
    }
    if(!IS_IP_ACQUIRED(app_CB.Status))
    {
        ret = sem_wait_timeout(&app_CB.CON_CB.ip4acquireEventSyncObj,
                               WLAN_EVENT_TOUT);
        if(ret == TIMEOUT_SEM)
        {
            /* In next step try to get IPv6,may be router/AP doesn't support IPv4 */
            UART_PRINT("\n\r[wlanconnect] : Failed to acquire IPv4 address.\n\r");
            return(-1);
        }
    }
/*
    if(!IS_IPV6G_ACQUIRED(app_CB.Status))
    {
        ret = sem_wait_timeout(&app_CB.CON_CB.ip6acquireEventSyncObj,
                               WLAN_EVENT_TOUT);
        if(ret == TIMEOUT_SEM)
        {
            UART_PRINT(
                "\n\r[wlanconnect] : Failed to acquire IPv6 address.\n\r");
        }
    }

    if(!IS_IPV6G_ACQUIRED(app_CB.Status) &&
       !IS_IPV6L_ACQUIRED(app_CB.Status) && !IS_IP_ACQUIRED(app_CB.Status))
    {
        UART_PRINT("\n\r[line:%d, error:%d] %s\n\r", __LINE__, -1,
                   "Network Error");
    }
*/
    return(0);
}

int32_t TcpConnect(void)
{
    int32_t ret = 0;
    SendCmd_t SendCmdParams;

    memset(&SendCmdParams, 0x0, sizeof(SendCmd_t));
    SendCmdParams.nb = 1,//1表示非阻塞
    SendCmdParams.portNumber = wifiLocalPara.serverPort,
    SendCmdParams.ipAddr.ipv4 = (wifiLocalPara.serveripAddr[0]<<24)|
                                    (wifiLocalPara.serveripAddr[1]<<16)|
                                    (wifiLocalPara.serveripAddr[2]<<8)|
                                    (wifiLocalPara.serveripAddr[3]<<0);
    SendCmdParams.ipv6 = 0,
    SendCmdParams.numberOfPackets = 100;

    if(ret < 0)
    {
        return(-1);
    }

    ret = TCPClient(SendCmdParams.nb, SendCmdParams.portNumber,
                    SendCmdParams.ipAddr, SendCmdParams.ipv6,
                    SendCmdParams.numberOfPackets,
                    TRUE);

    return(ret);
}



















