#include "sr_log.h"
#include "sr_gpio.h"
#include "sr_shell.h"

#include "at.h"

#include <string.h>

#define  WIFI_SSID       "ldx"
#define  WIFI_PASSWARD   "1319032487"

#define  ESP8266_PD   SR_GPIO41      //PC1
#define  ESP8266_UART_ID   SR_UART4  
#define  NET_SERVER_IP    "192.168.3.11"
#define  NET_SERVER_PORT  5000

SR_CT_T esp8266Ct;

struct at_client  espCleint;

static char cmd[48]={0};

int AtWait(void *args);

void esp8266_client_init(void)
{
  
	SR_GPIO_CFG_T gpioCfg = {0};
	SR_UART_CFG_T uartCfg = SR_UART_CFG_DEFAULT; // 初始默认配置

	gpioCfg.gpioMode = SR_GPIO_OUTPUT;		  // 输出
	gpioCfg.pull = SR_GPIO_NP;				      // 无上下拉
	gpioCfg.initLvl = SR_GPIO_HIGH;			  // 初始低电平
	SR_HalGpioInit(ESP8266_UART_ID, &gpioCfg);    // 初始化
	
	uartCfg.rxBufsz = 128;
	at_client_init(&espCleint,ESP8266_UART_ID, &uartCfg,128);
	
}

static void urc_busy_p_func(struct at_client *client, const char *data, srSize_t size)
{
    SR_LOG(INFO,"system is processing a commands...");
}

static void urc_busy_s_func(struct at_client *client, const char *data, srSize_t size)
{
    SR_LOG(INFO,"system is sending data...");
}

static void urc_func(struct at_client *client, const char *data, srSize_t size)
{
	  SR_LOG(INFO,"[URC] %*s",size,data);
}

static void urc_recv_func(struct at_client *client, const char *data, srSize_t size)
{
	 SR_LOG(INFO,"recv:");
	 SR_LOG(INFO,"%*s",size,data);
}

static const struct at_urc urc_table[] =
{
    {"busy p",           "\r\n",           urc_busy_p_func},
    {"busy s",           "\r\n",           urc_busy_s_func},
    {"WIFI CONNECTED",   "\r\n",           urc_func},
    {"WIFI DISCONNECT",  "\r\n",           urc_func},
		{"CONNECT",  "\r\n",                   urc_func},
		{"SEND OK",          "\r\n",           urc_func},
    {"SEND FAIL",        "\r\n",           urc_func},
		{"+IPD",             "\r\n",           urc_recv_func},
};


static int esp8266_send(at_client_t client,at_response_t resp, const char *buff, srSize_t bfsz)
{
    SR_CT_T *ct = SR_GET_CUR_CT();
	  int ret = SR_OK;

	  if(buff==SR_NULL || bfsz<=0) SR_OsThreadExit(SR_INVALID);
		if(resp==SR_NULL) SR_OsThreadExit(SR_NOMEM);
		
		SR_CT_BEGIN(ct);

		SR_CT_MUTEX_TAKE(ct, &client->lock, OS_WAIT_FOREVER);
 

    /* set AT client end sign to deal with '>' sign */
    at_obj_set_end_sign(client, '>');
  
    
		/* send the "AT+CIPSEND" commands to AT server than receive the '>' response on the first line */	
		SR_CT_WAIT_CHILD(ct,ret,at_obj_exec_cmd(client,resp,"AT+CIPSEND=%d",bfsz));
		if(ret!=SR_OK) {ret=SR_FAIL;goto __exit;};

		SR_CT_WAIT_CHILD(ct,ret,at_client_obj_send(client,buff,bfsz));
		ret = (ret<=0)? ret=SR_FAIL:SR_OK;
        
    

__exit:
    /* reset the end sign for data */
    at_obj_set_end_sign(client, 0);

		SR_CT_MUTEX_RELEASE(&client->lock);

		SR_OsThreadExit(ret);
		
		SR_CT_END(ct);
}

int esp8266Thd(void *args)
{
	SR_CT_T *ct = SR_GET_CUR_CT();
	static int ret=0;
	at_client_t client = (at_client_t)args;
	static at_response_t resp = SR_NULL;
	static uint8_t retry_num =3;
	
  SR_CT_BEGIN(ct);
	retry_num =3;
	ret =0;
	
	//设置URC
	at_obj_set_urc_table(client, urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
	
	//检查UART连接
	SR_CT_WAIT_CHILD(ct,ret,at_client_obj_wait_connect(client,3000));
	if(ret!=SR_OK)
	{
		SR_LOG(INFO,"wait AT...,ret(%d)",ret);
		SR_OsThreadExit(SR_FAIL);
	}
	
	/* 创建响应结构体，设置最大支持响应数据长度为 512 字节，响应数据行数无限制，超时时间为 5 秒 */
	resp = at_create_resp(512, 0, SR_OsMsToTick(5000));
	if (resp==SR_NULL)
	{
			SR_LOG(ERR,"No memory for response structure!");
			SR_OsThreadExit(SR_NOMEM);
	}
	
 
	//网络初始化
	while (retry_num--)
    {
       
        SR_CT_WAIT_CHILD(ct,ret,at_obj_exec_cmd(client,resp,"ATE0"));
			  if(ret!=SR_OK) {ret=SR_FAIL;goto __exit;};
				
				SR_CT_WAIT_CHILD(ct,ret,at_obj_exec_cmd(client,resp,"AT+CWMODE=1"));
			  if(ret!=SR_OK) {ret=SR_FAIL;goto __exit;};
				
				
				SR_CT_WAIT_CHILD(ct,ret,at_obj_exec_cmd(client,resp,"AT+CWJAP=\"%s\",\"%s\"",WIFI_SSID,WIFI_PASSWARD));
			  if(ret!=SR_OK) {ret=SR_FAIL;goto __exit;};
				
				SR_CT_WAIT_CHILD(ct,ret,at_obj_exec_cmd(client,resp,"AT+CIFSR"));
			  if(ret!=SR_OK) {ret=SR_FAIL;goto __exit;};
				//打印MAC和IP
				SR_PRINTF("%s",at_resp_get_line_by_kw(resp, "STAIP"));
				SR_PRINTF("%s",at_resp_get_line_by_kw(resp, "STAMAC"));
				
				//连接服务器
				SR_CT_WAIT_CHILD(ct,ret,at_obj_exec_cmd(client,resp,"AT+CIPSTART=\"TCP\",\"%s\",%d",NET_SERVER_IP,NET_SERVER_PORT));
				if(ret!=SR_OK) {ret=SR_FAIL;goto __exit;};
				
				
        
        /* initialize successfully  */
        ret = SR_OK;
        break;

    __exit:
        if (ret != SR_OK)
        {
            SR_CT_DELAY_MS(ct,1000);  //1s后重试
            SR_LOG(INFO,"client(%s ) init  retry...", client->device->name);
        }
    }
		
		if (ret != SR_OK)
    {
        SR_LOG(INFO,"esp8266 net init fail!");
			  goto _END;
    }
    else
    {
        SR_LOG(INFO,"esp8266 net init ok!");
    }
		
		while(1)
		{	
				
			//发送数据
			SR_CT_WAIT_CHILD(ct,ret,esp8266_send(client,resp,"hello world!", 12));
			SR_CT_DELAY_MS(ct,2000);
		
		}
		

_END:
		if (resp != SR_NULL)
    {
        at_delete_resp(resp);
			  resp =SR_NULL;
    }

    
	SR_CT_END(ct);
}
int Esp8566Start(int argc, char**argv)
{

	  //创建协程
		SR_OsThreadCreate("atMode",esp8266Thd,&espCleint,128,1);
	  
	  return 0;
}
SR_SHELL_CMD_EXPORT(wifiStart, Esp8566Start);



static int at_send(void *argv)
{
	struct ct *ct =SR_GET_CUR_CT();
	static at_response_t resp = SR_NULL;
	
	int ret;
	
	SR_CT_BEGIN(ct);

	/* 创建响应结构体，设置最大支持响应数据长度为 512 字节，响应数据行数无限制，超时时间为 5 秒 */
	resp = at_create_resp(512, 0, SR_OsMsToTick(5000));
	if (resp==SR_NULL)
	{
			SR_LOG(ERR,"No memory for response structure!");
			SR_OsThreadExit(SR_NOMEM);
	}


	/* 发送 AT 命令并接收 AT Server 响应数据，数据及信息存放在 resp 结构体中 */
	SR_CT_WAIT_CHILD(ct,ret,at_obj_exec_cmd(&espCleint,resp,cmd));
	if (ret != SR_OK)
	{
			SR_LOG(ERR,"AT client send commands failed, response error or timeout (%d) !",ret);						
	}
	else
	{
		  /* 打印返回 */
			//SR_LOG(DEBUG,"AT Client send commands to AT Server success!");
			for(int i=0;i<resp->line_counts;i++)
			{
					SR_PRINTF("%s",at_resp_get_line(resp,i+1));
			}
	}

	/* 删除响应结构体 */
	at_delete_resp(resp);
	resp = SR_NULL;

	SR_CT_END(ct);
}

int AtClientSend(int argc, char**argv)
{
    if (argc != 2)
    {
        SR_LOG(ERR,"at_cli_send [command]  - AT client send commands to AT server.");
        return SR_FAIL;
    }
		
		strcpy(cmd,argv[1]);
		
		//创建协程
		SR_OsThreadCreate("atSend",at_send,SR_NULL,48,1);

    return SR_OK;
}
SR_SHELL_CMD_EXPORT(atcSend, AtClientSend);



/*********AT 模式**************/
SR_DEVICE_T *atUartDev=SR_NULL;
struct ct_sem atUartSem;
uint8_t recvBuf[128];
uint8_t sendBuf[64];
uint16_t recvLen=0;

// 串口事件回调
static void UserUartCb(SR_DEVICE_T *dev, SR_UART_EVENT_E event, uint32_t size, void *args)
{
    switch (event)
    {
        case SR_UART_EVT_RXNE:
              
				      //发送信号量
				      recvLen = size;
				      SR_CT_SEM_RELEASE(&atUartSem);
        break;
    }

}

int AtModeThd(void *args)
{
    SR_CT_T *ct = SR_GET_CUR_CT();
	  int ret;
	  SR_UART_CFG_T config = SR_UART_CFG_DEFAULT; // 初始默认配置
	  SR_GPIO_CFG_T gpioCfg = {0};
	
	  SR_CT_BEGIN(ct);
	
		gpioCfg.gpioMode = SR_GPIO_OUTPUT;		  // 输出
		gpioCfg.pull = SR_GPIO_NP;				      // 无上下拉
		gpioCfg.initLvl = SR_GPIO_HIGH;			    // 初始低电平
		SR_HalGpioInit(ESP8266_UART_ID, &gpioCfg); // 初始化

    // 获取设备句柄
    atUartDev = SR_HalUartOpen(ESP8266_UART_ID);

    // 参数配置
    config.baudrate = SR_UART_BAUD_115200;
    config.dataBits = SR_UART_DATA_BIT_8;
    config.parity = SR_UART_PARITY_NONE;
    config.stopBits = SR_UART_STOP_BIT_1;
	  config.rxBufsz = 128;
    SR_HalUartConfig(atUartDev, &config);

    // 注册回调
    SR_HalUartSetCb(atUartDev, UserUartCb, 0);
	
	  //初始化信号量
	  SR_CT_SEM_INIT(&atUartSem, 1);
	
	  while(gShellThreadRun)
		{
		   SR_CT_SEM_TAKE(ct, &atUartSem, OS_WAIT_FOREVER);
			
			 //转发至LOG串口
		 	 ret = SR_HalUartRead(atUartDev, recvBuf, recvLen);
			 if(ret >0) 
			 {	 
				 recvBuf[ret] = 0;
			   SR_Printf("%*s",ret,recvBuf);
			 }	
		}
		
  
		SR_CT_END(ct);
}

int AtModeEnter(int argc, char**argv)
{
    gShellThreadRun =1;
	  //创建协程
		SR_OsThreadCreate("atMode",AtModeThd,SR_NULL,48,1);
	  
	  return 0;
}
SR_SHELL_CMD_EXPORT(atMode, AtModeEnter);

int AtUartSend(int argc, char**argv)
{
	if(argc<2) return -1;
	
	sprintf((char *)sendBuf,"%s\r\n",argv[1]);
  SR_HalUartWrite(atUartDev,sendBuf,strlen((char *)sendBuf));
	
	return 0;
}
SR_SHELL_CMD_EXPORT(atu_send, AtUartSend);


/*
atu_send ATE0
atu_send AT+CWMODE=1
atu_send AT+CWJAP="ldx","1319032487"
atu_send AT+CIFSR
atu_send AT+CIPSTART="TCP","192.168.3.11",5000
atu_send AT+CIPSEND=6

*/

