/****************************************************************************************************
* created by sunpeng 2017 all rights reserved!
****************************************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "delay.h"
#include "usart.h"
#include "wireless.h"
#include "include.h"
//#include "led.h"
#include "power.h"

/** @addtogroup Template_Project
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t sta_id = 1;
static uint8_t NumTab[]="0123456789";

/********** define esp8266 debug mode ***********/
//#define ESP8266_DEBUG


/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/
#if ARCH_MODE == CC254x_Slave_Mode

void Init_CC254x_Slave_Client(void)
{

}

#elif ARCH_MODE == ESP8266_Station_Mode
void debug_wifiConnection(void)
{

	
}

u8 wifiConnectWaitDelay(void)
{
	u16 i=0;
	for(i=0;i<15;i++)
	{
		delay_ms(1000);
		if(true == wifiApConnected_Flag)
		{	
			wifiConnectWaitDelayCnt = i+1;
			break;
		}
	}

	return wifiApConnected_Flag;
}


void Init_ESP8266_Station_Client(void)
{
	u8 initESP_Flag = false;
	initESP_Flag = startConnectRouterlink();
	if(true == initESP_Flag)
	{
		//startConnectRouterlink();
		initESP_Flag = startConnectServerlink();
	}
	
	if(false == initESP_Flag)
	{
		shineAllAngleNTimes(2);
		//init_set_teach_led_queue(); //离线模式，初始化Led教学固定步骤
	}
}


u8 startConnectRouterlink(void)
{
	u8 conSCnt = 0,conS_Flag = false;
	
	for(conSCnt=0;conSCnt<1;conSCnt++)
	{
		conS_Flag = connectRouter();
		if(true == conS_Flag)
		{
			break;
		}
	}
	
	if(false == conS_Flag)  //connect to server falied at boot
	{
		return false;
	}
	return true;
}

u8 wifiResetReady_FlagWaitDelay(void)
{
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	delay_ms(1000);if(true == wifiResetReady_Flag){	return true;}
	return false;
}

u8 connectRouter(void)
{
	//u8 wififlag = false;
	delay_ms(200); //200
	//SendString_NewLine("AT+RST");
	//wififlag = wifiResetReady_FlagWaitDelay();
	//if (false == wififlag)
	//{
	//	//return false;
	//}
    delay_ms(1600); //1000
    SendString_NewLine("AT+CIPSERVER=0");
    delay_ms(300); //500
    SendString_NewLine("AT+CWMODE=3");
	
    delay_ms(300); //500
    SendString_NewLine("AT+CWJAP=\"Phi_FA9308\",\"20151206\"");
	
#ifndef ESP8266_DEBUG	//debug mode no delay 
	if(false == wifiConnectWaitDelay())
	{
		return false;
	}
#endif
   //SendString_NewLine("AT+CWJAP?");  //查看连接路由是否成功
    //delay_ms(10);
    //SendString_NewLine("AT+CIFSR");  //查询连接的路由IP
    delay_ms(120);
#ifdef ESP8266_SINGLE_CONNECTION_MODE
    SendString_NewLine("AT+CIPMUX=0");//单路连接时(+CIPMUX=0)指令为：AT+CIPSEND=<length> 
#else
    SendString_NewLine("AT+CIPMUX=1");//多路连接时(+CIPMUX=1) 指令为： AT+CIPSEND= <id>,<length> 
#endif
    delay_ms(120); //500
//    SendString_NewLine("AT+SLEEP=1"); //0=disable sleep   1=light sleep   2=moderm sleep  |  AT+GSLP=1000 deep sleep
//    delay_ms(120); //120
	Init_ESP8266_AP_Server();
	return true;
}



u8 startConnectServerlink(void)
{
	u8 conSCnt = 0,conS_Flag = false;
	
	for(conSCnt=0;conSCnt<2;conSCnt++)
	{
		conS_Flag = connectServerPort();
		if(true == conS_Flag)
		{
			break;
		}
	}
	
	if(false == conS_Flag)
	{
		return false;
	}
	return true;
}

u8 udpClientLink1ConnectedWaitDelay(void)
{
	u16 i=0;
	for(i=0;i<20;i++)
	{
		delay_ms(200);if(true == udpClientLink1Connected_Flag){	udpClientLink1ConnectedWaitDelayCnt = i+1;return true;}//printf("waitdelay\n");
	}

	return false;                                           
}

//#define IP_SELECT_DEBUG_SERVER_IP  

u8 connectServerPort(void)
{
#if ARCH_MODE == ESP8266_Station_Mode
	//---------------------------------------------
#ifdef IP_SELECT_DEBUG_SERVER_IP
	//debug mode
	#ifdef ESP8266_TCP_CLIENT_MODE	
		//TCP mode
		#ifdef ESP8266_SINGLE_CONNECTION_MODE
			//SendString_NewLine("AT+CIPCLOSE");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=\"TCP\",\"192.168.10.124\",3721"); //单路连接时(+CIPMUX=0)，指令为：AT+CIPSTART= <type>,<addr>,<port> 
		#else
			//SendString_NewLine("AT+CIPCLOSE=1");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=1,\"TCP\",\"192.168.10.124\",3721"); //多路连接时(+CIPMUX=1)，指令为：AT+CIPSTART=<id>,<type>,<addr>,<port>
		#endif
	#else
		//UDP mode
		#ifdef ESP8266_SINGLE_CONNECTION_MODE
			//SendString_NewLine("AT+CIPCLOSE");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=\"UDP\",\"192.168.10.124\",3721"); //单路连接时(+CIPMUX=0)，指令为：AT+CIPSTART= <type>,<addr>,<port> 
		#else
			//SendString_NewLine("AT+CIPCLOSE=1");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=1,\"UDP\",\"192.168.10.124\",3721"); //多路连接时(+CIPMUX=1)，指令为：AT+CIPSTART=<id>,<type>,<addr>,<port>
		#endif

	#endif
#else
	//release mode
	#ifdef ESP8266_TCP_CLIENT_MODE	
		//TCP mode
		#ifdef ESP8266_SINGLE_CONNECTION_MODE
			//SendString_NewLine("AT+CIPCLOSE");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=\"TCP\",\"192.168.10.104\",3721"); //单路连接时(+CIPMUX=0)，指令为：AT+CIPSTART= <type>,<addr>,<port> 
		#else
			//SendString_NewLine("AT+CIPCLOSE=1");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=1,\"TCP\",\"192.168.10.104\",3721"); //多路连接时(+CIPMUX=1)，指令为：AT+CIPSTART=<id>,<type>,<addr>,<port>
		#endif
	#else
		//UDP mode
		#ifdef ESP8266_SINGLE_CONNECTION_MODE
			//SendString_NewLine("AT+CIPCLOSE");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=\"UDP\",\"192.168.10.104\",3721"); //单路连接时(+CIPMUX=0)，指令为：AT+CIPSTART= <type>,<addr>,<port> 
		#else
			//SendString_NewLine("AT+CIPCLOSE=1");
			delay_ms(200);
			SendString_NewLine("AT+CIPSTART=1,\"UDP\",\"192.168.10.104\",3721"); //多路连接时(+CIPMUX=1)，指令为：AT+CIPSTART=<id>,<type>,<addr>,<port>
		#endif

	#endif
	
#endif
	
    delay_ms(120); //120

	if(false == udpClientLink1ConnectedWaitDelay())
	{
		return false;
	}
	
    delay_ms(500); //500
#endif
	return true;
}



u8 changeConnectServerPort(void)  //通过wifi Server 调试TCP客户端发送更改App Server IP Port指令重新连接App Server
{
	u8 wifi_data_buf[56] = "";
	udpClientLink1Connected_Flag = false;
	//release mode
	#ifdef ESP8266_TCP_CLIENT_MODE	
		//TCP mode
		#ifdef ESP8266_SINGLE_CONNECTION_MODE
			SendString_NewLine("AT+CIPCLOSE");
			delay_ms(200);
			sprintf((char *)wifi_data_buf,"AT+CIPSTART=\"TCP\",%s",sAppServerIPandPort);
			SendString_NewLine(wifi_data_buf); //单路连接时(+CIPMUX=0)，指令为：AT+CIPSTART= <type>,<addr>,<port> 
		#else
			SendString_NewLine("AT+CIPCLOSE=1");
			delay_ms(200);
			sprintf((char *)wifi_data_buf,"AT+CIPSTART=1,\"TCP\",%s",sAppServerIPandPort);
			SendString_NewLine(wifi_data_buf); //多路连接时(+CIPMUX=1)，指令为：AT+CIPSTART=<id>,<type>,<addr>,<port>
		#endif
	#else
		//UDP mode
		#ifdef ESP8266_SINGLE_CONNECTION_MODE
			SendString_NewLine("AT+CIPCLOSE");
			delay_ms(200);
			sprintf((char *)wifi_data_buf,"AT+CIPSTART=\"UDP\",%s",sAppServerIPandPort);
			SendString_NewLine(wifi_data_buf); //单路连接时(+CIPMUX=0)，指令为：AT+CIPSTART= <type>,<addr>,<port> 
		#else
			SendString_NewLine("AT+CIPCLOSE=1");
			delay_ms(200);
			sprintf((char *)wifi_data_buf,"AT+CIPSTART=1,\"UDP\",%s",sAppServerIPandPort);
			SendString_NewLine(wifi_data_buf); //多路连接时(+CIPMUX=1)，指令为：AT+CIPSTART=<id>,<type>,<addr>,<port>
		#endif

	#endif
	
	
    delay_ms(120); //120

	if(false == udpClientLink1ConnectedWaitDelay())
	{
		return false;
	}
	
    delay_ms(200); //500

	return true;
}

void get_wifi_info(void)
{
    delay_ms(120);
    SendString_NewLine("AT+CIFSR");  //查询连接的路由IP
    delay_ms(120);
}

void Init_ESP8266_AP_Server(void)
{
    delay_ms(200);
    SendString_NewLine("AT+CWSAP=\"CubeDebug\",\"123456123456\",5,3"); //wifi name and passwd channel passwdMode  
	//passwdMode: 0-OPEN，1-WEP，2-WPA_PSK，3-WPA2_PSK，4-WPA_WPA2_PSK
    delay_ms(200);
    SendString_NewLine("AT+CWMODE=3");  //station and AP mix mode
    delay_ms(120);
    SendString_NewLine("AT+CIPMUX=1");  //multi link mode
    delay_ms(120);
    SendString_NewLine("AT+CIPSERVER=1,18080");
    delay_ms(120);
    SendString_NewLine("AT+CIPSTO=360"); //server link timeout
    delay_ms(120);
    
}

#ifdef ESP8266_SINGLE_CONNECTION_MODE
uint8_t Sta_CIPSEND_str[] = "AT+CIPSEND=00";//单路连接时(+CIPMUX=0)，指令为：AT+CIPSEND=<length>
uint8_t Sta_CIPSEND_str_base = 11;			//单路连接时(+CIPMUX=0)，指令为：AT+CIPSEND=<length>
#else
uint8_t Sta_CIPSEND_str[] = "AT+CIPSEND=1,00";	//多路连接时(+CIPMUX=1) ，指令为： AT+CIPSEND= <id>,<length>
uint8_t Sta_CIPSEND_str_base = 13;				//多路连接时(+CIPMUX=1) ，指令为： AT+CIPSEND= <id>,<length>
#endif
void Sta_Send(int id, int len, uint8_t *Str)
{
#ifndef ESP8266_SINGLE_CONNECTION_MODE
    Sta_CIPSEND_str[Sta_CIPSEND_str_base-2] = NumTab[id];
#endif	
    //send message to specific station server
    //delay_ms(1500);
    if(len > 9)
    {
        len = len%100;
        Sta_CIPSEND_str[Sta_CIPSEND_str_base]=NumTab[len/10];
        Sta_CIPSEND_str[Sta_CIPSEND_str_base+1]=NumTab[len%10];
    }
    else
    {
        Sta_CIPSEND_str[Sta_CIPSEND_str_base]=NumTab[len];
        Sta_CIPSEND_str[Sta_CIPSEND_str_base+1]='\0';
    }
    SendString_NewLine(Sta_CIPSEND_str);
    delay_ms(10);
    SendString_NewLine(Str);
	
#ifndef ESP8266_SINGLE_CONNECTION_MODE
	if(true == APServerCubeDebugMailAdd_Flag) //增加调试抄送功能
	{
		Sta_CIPSEND_str[Sta_CIPSEND_str_base-2] = NumTab[0];//调试连接fd默认0
		delay_ms(10);
		SendString_NewLine(Sta_CIPSEND_str);
		delay_ms(10);
		SendString_NewLine(Str);
		delay_ms(10);
	}	
#endif		
	
}
#endif

/**
  * print_wifi  
  * Esp8266 Station Mode
  * sta_id=1
  * auto detect send len
  */
void print_wifi(uint8_t *str)
{
	u16 len = 0;
	//无线未连接，不发送
	if(false == wireless_connected_Flag)
	{
		return;
	}
	
	while(0x0 != *(str+len))
	{
		len++;
	}
#if ARCH_MODE == ESP8266_Station_Mode	
	delay_ms(20);
	Sta_Send(sta_id,len,str);
#elif ARCH_MODE == CC254x_Slave_Mode
	delay_ms(20);
	SendString(str);
#elif ARCH_MODE == NRF52832_Slave_Mode
	write_LOG_INFO_STRUCT(str, LOG_DATA_TYPE_Send, len);
#elif ARCH_MODE == CC254X_Peripheral_Mode
    ble_uart_string_len_send(str, len);
#elif ARCH_MODE == NRF51822_Peripheral_Mode
    ble_uart_string_len_send(str, len);
#elif ARCH_MODE == NRF51802_Peripheral_Mode
    write_LOG_INFO_STRUCT(str, LOG_DATA_TYPE_Send, len);
#endif
}

//发送特定长度的字符串
void print_wifi_len(uint8_t *str, uint16_t len)
{
	//无线未连接，不发送
	if(false == wireless_connected_Flag)
	{
		return;
	}
	
#if ARCH_MODE == NRF52832_Slave_Mode
	write_LOG_INFO_STRUCT(str, LOG_DATA_TYPE_Send, len);
#elif ARCH_MODE == CC254X_Peripheral_Mode
    ble_uart_string_len_send(str, len);
#elif ARCH_MODE == NRF51822_Peripheral_Mode
    ble_uart_string_len_send(str, len);
#elif ARCH_MODE == NRF51802_Peripheral_Mode
    write_LOG_INFO_STRUCT(str, LOG_DATA_TYPE_Send, len);
#endif
}

/**
  * debug_print_wifi  
  * Esp8266 Station Mode
  * sta_id=1
  * auto detect send len
  */
void debug_print_wifi(uint8_t *str)
{
	u16 len = 0;
	
	//无线未连接，不发送
	if(false == wireless_connected_Flag)
	{
		return;
	}
	
	if(false == DEBUG_FLAG)
	{
		return;
	}
	
	if(NULL == str)
	{
		return;
	}
		
	while(0x0 != *(str+len))
	{
		len++;
	}
#if ARCH_MODE == ESP8266_Station_Mode	
	delay_ms(20);
	Sta_Send(sta_id,len,str);
#elif ARCH_MODE == CC254x_Slave_Mode
	delay_ms(20);
	SendString_NewLine(cstr);
#elif ARCH_MODE == NRF52832_Slave_Mode
	write_LOG_INFO_STRUCT(str, LOG_DATA_TYPE_Send, len);
#elif ARCH_MODE == CC254X_Peripheral_Mode
    ble_uart_string_len_send(str, len);
#elif ARCH_MODE == NRF51822_Peripheral_Mode
    ble_uart_string_len_send(str, len);
#elif ARCH_MODE == NRF51802_Peripheral_Mode
    write_LOG_INFO_STRUCT(str, LOG_DATA_TYPE_Send, len);
#endif

}


void print_wifi_num(uint8_t num)
{
	u8 str[8]={0x0};
	sprintf((char *)str,"%d",num);
	delay_ms(20);
#if ARCH_MODE == ESP8266_Station_Mode	
	Sta_Send(sta_id,strlen((const char *)str),str);
#endif
}

/**
  * AP_Send
  * len 
  * *Str
  */
uint8_t AP_CIPSEND_str[] = "AT+CIPSEND=00";
void AP_Send(int len, uint8_t *Str)
{
    //send message to specific client
    //delay_ms(1500);
    if(len > 9)
    {
        len = len%100;
        AP_CIPSEND_str[11]=NumTab[len/10];
        AP_CIPSEND_str[12]=NumTab[len%10];
    }
    else
    {
        AP_CIPSEND_str[11]='0';
        AP_CIPSEND_str[12]=NumTab[len];
    }
    SendString_NewLine(AP_CIPSEND_str);
    delay_ms(10);
    SendString(Str);
}

#if ARCH_MODE == ESP8266_Station_Mode	

/**
  *SendReplyByCmdcode
  *para: Cmdcode:指令码
  *		 CmdStr: 待发送的指令字符串
  *rtn:TRUE，FALSE
  *Cmdcode:指令码
  *Note: 将纯数据封包后发送出去
  */
int SendReplyByCmdcode(int Cmdcode, char *CmdStr)
{
	int strMaxLen = 0;
	int CmdStrLenCnt = 0;
	int CmdStrLenCntMSB = 0;
	int strLenCnt = 0;
	u16 i=0;
	char str[129]={0x00};//="EasyCube:%c%c%c%s";
	//unsigned char cmdstr[]="192.168.0.130";
	//printf("cmdlen=%d",cmdlen);
	char CmdStrAdd = 0x0;
	while(1)
	{
		if(0x00 == *(CmdStr+CmdStrLenCnt))
		{
			break;
		}
		else
		{
			CmdStrAdd = (unsigned char)(CmdStrAdd + *(CmdStr+CmdStrLenCnt));
		}

		if(CmdStrLenCnt > 1024)
		{
			return mpu_FALSE;
		}

		CmdStrLenCnt++;
	}
	//printf("CmdStrLenCnt=%d \n",CmdStrLenCnt);
	//printf("CmdStrAdd=%d \n",CmdStrAdd);
	//printf("CmdStrAdd=%x \n",(unsigned char)CmdStrAdd);
	CmdStrLenCntMSB = CmdStrLenCnt/256;
	//if(0 == CmdStrLenCntMSB)
	//{
	//	CmdStrLenCntMSB = 255;
	//}
	//printf("CmdStrLenCntMSB=%d\n",CmdStrLenCntMSB);
	/**/

	//printf("\n");
	strMaxLen = sizeof(str);
	/**/
	for(i=0;i<strMaxLen;i++)
	{
		strLenCnt++;
		//printf("%x ",(unsigned char)str[i]);
		if(0x0d == str[i])
		{
			if(0x0a == str[i+1])
			{
				if(0x0 == str[i+2])
				{
					strLenCnt+=1;
					//printf("%x ",(unsigned char)str[i+1]);
					//printf("%x ",(unsigned char)str[i+2]);
					break;
				}
			}
		}
	}
	Sta_Send(sta_id,strLenCnt,(uint8_t *)str);
	//printf("len=%d",sizeof(str));

	return mpu_TRUE;
}
#endif

/********************************************************************************************/

LOG_INFO_STRUCT lInfo;		//全局日志存储信息结构体

//初始化日志存储数据
u8 init_LOG_INFO_STRUCT(LOG_INFO_STRUCT *pInfo)
{
	u16 i = 0;
	
	if(NULL == pInfo)
	{
		return false;
	}
	
	pInfo->writeOffset = 0;
	pInfo->readOffset = 0;
	pInfo->writeTimeCnt = 0;
	for(i = 0;i < LOG_RECORD_MAX; i++)
	{
		pInfo->record[i].flag = false;
		pInfo->record[i].type = LOG_DATA_TYPE_MIN;
		pInfo->record[i].dataLen = 0;
		pInfo->record[i].data[LOG_PER_RECORD_LEN_MAX] = 0x0;
		pInfo->record[i].writeTime = 0;
	}
	return true;
}

//写入一条日志到日志存储中
u8 write_LOG_INFO_STRUCT(u8 *str, LOG_DATA_TYPE_ENUM type, u16 strLen)
{
	return true;
}

//读取日志缓冲中数据
//str 	: 指向日志存储有效记录
//flag  : 指向日志存储数据有效标志, 数据使用完成后外部清空flag
//type  : 输出数据类型
//strLen: 输出数据长度
u8 read_LOG_INFO_STRUCT(u8 **str, u8 **flag, LOG_DATA_TYPE_ENUM *type, u16 *strLen)
{
	u16 i = 0;
	u16 offset = lInfo.readOffset;
	u16 readOffset = offset;
	u16 writeTime = 65535;
	
	if(true == lInfo.record[readOffset].flag)
	{
		writeTime = lInfo.record[readOffset].writeTime;
	}
	
	
	if(true == lInfo.record[readOffset].flag)
	{
		*str = (u8 *)&lInfo.record[readOffset].data;
		*strLen = lInfo.record[readOffset].dataLen;
		*type = lInfo.record[readOffset].type;
		*flag = (u8 *)&lInfo.record[readOffset].flag;
		lInfo.readOffset = readOffset;
		return true;
	}
	else
	{
		*strLen = 0;
		return false;
	}
}

//初始化日志缓冲队列
void init_log_queue(void)
{
	init_LOG_INFO_STRUCT(&lInfo);
}

//定时检测日志缓冲队列中是否有未发送的数据，若有则上传APP
void cycle_process_log_queue(void)
{
	u8 *str = NULL;
	u8 *str_flag = NULL;
	u16 strLen = 0;
	LOG_DATA_TYPE_ENUM type = LOG_DATA_TYPE_MIN;
		
	//无数据可发送，返回
	if(false == read_LOG_INFO_STRUCT(&str, &str_flag, &type, &strLen))
	{
		return;
	}
		
	//获取数据失败
	if((0 == strLen)||(NULL == str)||(NULL == str_flag))
	{
		return;
	}
		
	if(LOG_DATA_TYPE_Send == type)
	{
		//将缓冲中数据发送给App
		ble_uart_string_len_send(str, strLen);
		*str_flag = false;		//数据用完，清空标志
	}
	else if(LOG_DATA_TYPE_Recv == type)
	{
		detectDataFromBLE(str, strLen);
		*str_flag = false;		//数据用完，清空标志
	}
	
}

/*********************************************end of file*********************************************/
