#include "ec800m.h"
#include "usart.h"
#include "systick.h"
#include "cJson.h"
#include "string.h"
#include "log.h"
#include "systick.h"


void EC800MPwoerOn(void)
{
	rcu_periph_clock_enable(RCU_GPIOD);
	gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
	gpio_bit_set(GPIOD,GPIO_PIN_2);
	delay_1ms(5000);
	gd_pull_EC800M_pwr_up();
	gd_pull_EC800M_rst_down();
	delay_1ms(50);
	gd_pull_EC800M_pwr_down();
	delay_1ms(320);
	gd_pull_EC800M_rst_up();
	delay_1ms(800);
	gd_pull_EC800M_pwr_up();
}

void EC800MSendCmd(char *buf, uint16_t len)
{
	uint16_t i;
	uint16_t data;
	for (i = 0; i < len; i++)
	{
		data = buf[i];
		usart_data_transmit(COM_EC800, data);
		while (RESET == usart_flag_get(COM_EC800, USART_FLAG_TBE))
			;
	}
}

void EC800MWaitReady()
{
	WaitResponse(RSP_READY, 0);
}

/*
 *  函数名：bool WaitResponse(char *expectStr, int timeout)
 *  输入参数：expectStr 需要匹配的关键字 timeout超时时间
 *  输出参数：true flase
 *  返回值：无
 *  函数作用：从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false
 */
bool WaitResponse(char *expectStr, int timeout)
{
	bool timeoutFlag = false;
	if (timeout >= 0)
	{
		timeoutFlag = true;
	}
	// gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义

	while (1)
	{
		delay_1ms(50);
		if (UART0_RX_STAT > 0)
		{
			UART0_RX_STAT = 0;
			char *p = strstr((char *)&UART0_RX_BUF, expectStr);
			if (p)
			{
				Clear_DMA_Buffer();
				return true;
			}
		}
		timeout -= 50;
		if (timeoutFlag == true && timeout <= 0)
		{
			Clear_DMA_Buffer();
			return false;
		}
	};
}


//bool WaitResponseserver(CONFIG_PARAMS *gateway,int timeout)
//{
//	bool timeoutFlag = false;
//	if (timeout >= 0)
//	{
//		timeoutFlag = true;
//	}
//	// gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义

//	while (1)
//	{
//		char *p=NULL;
//		char *Q=NULL;
//		uint8_t seg1;
//		uint8_t seg2;
//		char seg3[20];
//		char seg6[10];
//		uint8_t seg4;
//		char seg5[25];
//		char buf[20];
//		char *token;
//		delay_1ms(50);
//		if (UART0_RX_STAT > 0)
//		{

//				UART0_RX_STAT = 0;
////			char *p = strstr((char *)&UART0_RX_BUF, expectStr);
//			

//			
//			
//			if(strstr((char *)&UART0_RX_BUF, "+COPS:"))
//			{
//				Q=strstr((char *)&UART0_RX_BUF, "+COPS:");
//			
//				sscanf(Q, "+COPS:%d,%d,%s", &seg1,&seg2,seg3);
//				sscanf(Q, "+COPS:%d,%d,%*s%s ", &seg1,&seg2,seg6);
//				
//				if(strstr((char *)&seg3, "CHN-CT"))
//				{
//					strcpy((char *)gateway->Operatortyp,"CHN-CT");
//					p=strchr((char *)&seg3,',')+1;	
//					strcpy((char *)gateway->Networktyp,p);
//					strcpy(gateway->Networkstatu,"1");//注册到网络
//					
//				
//				}else if(strstr((char *)&seg3, "CHN-UNICOM"))
//				{
//					strcpy((char *)gateway->Operatortyp,"CHN-UNICOM");
//					p=strchr((char *)&seg3,',')+1;	
//					strcpy((char *)gateway->Networktyp,p);
//					strcpy(gateway->Networkstatu,"1");//注册到网络
//					
//				}else if(strstr((char *)&seg3, "CHINA"))
//				{
//					strcpy((char *)gateway->Operatortyp,"CHINA MOBILE");
//					p=strchr((char *)&seg6,',')+1;	
//					strcpy((char *)gateway->Networktyp,p);
//					strcpy(gateway->Networkstatu,"1");//注册到网络
//					
//				}else 
//				{
//					strcpy((char *)gateway->Operatortyp,"");
//					strcpy((char *)gateway->Networktyp,"");
//					strcpy(gateway->Networkstatu,"0");//注册到网络
//				}
//					
//			}else if(strstr((char *)&UART0_RX_BUF, "+CLCK:"))
//			{
//				Q=strstr((char *)&UART0_RX_BUF, "+CLCK:");
//				sscanf(Q, "+CLCK:%d", &seg1);
//				sprintf(buf,"%d",seg1);
//				memcpy(gateway->SIMcardstatus,buf,sizeof(buf));
//				memset(buf,0,sizeof(buf));
//			
//				}else if(strstr((char *)&UART0_RX_BUF, "+QCCID:"))
//			{

//				p = strchr((char *)&UART0_RX_BUF,':')+2;
//				sscanf(p, "%20s", seg5); 
//				strcpy((char *)gateway->SIMcardICCID,seg5);

//				}else if(strstr((char *)&UART0_RX_BUF, "+GSN"))
//			{
//				p = strchr((char *)&UART0_RX_BUF,'N')+4;
//				sscanf(p, "%15s", seg5); 
//				strcpy((char *)gateway->IMEInumber,seg5);		
//			
//			}else if(strstr((char *)&UART0_RX_BUF, "+CSQ:"))
//			{
//				Q=strstr((char *)&UART0_RX_BUF, "+CSQ:");
//				sscanf(Q, "+CSQ:%d,%d", &seg1,&seg2);
//				sprintf(buf,"%d",(int)(((float)seg1/31)*100));
//				memcpy(gateway->Signalstrength,buf,sizeof(buf));
//				memset(buf,0,sizeof(buf));				
//			}
//		}else if(strstr((char *)&UART0_RX_BUF, "+CME ERROR:"))//QCCID没有的情况出现+CME ERROR:
//			{
//			strcpy((char *)gateway->SIMcardICCID,"");
//			
//			}
//		timeout -= 50;
//		if (timeoutFlag == true && timeout <= 0)
//		{
//			Clear_DMA_Buffer();
//			return false;
//		}
//	};
//}







/*
 *  函数名：void EC800MSetPDP()
 *  输入参数：无
 *  输出参数：无
 *  返回值：无
 *  函数作用：设置对应运营商和激活ip
 */
void EC800MSetPDP()
{
	delay_1ms(200);
	EC800MSendCmd(CMD_SET_PDP, strlen(CMD_SET_PDP));
	WaitResponse(RSP_OK, 1000);
	delay_1ms(200);
	EC800MSendCmd(CMD_SET_ACTIVE, strlen(CMD_SET_ACTIVE));
	WaitResponse(RSP_OK, 1000);
	delay_1ms(200);
	//	//测试代码查看ip
	//	char *test="AT+QIACT?\r\n";
	//	EC800MSendCmd(test,strlen(test));
	//	WaitResponse(RSP_OK, 1000);
}


//void ec800m_information_service(CONFIG_PARAMS *gateway)
//{
////delay_1ms(200);
//		EC800MSendCmd(CMD_SERVICE_Operatortyp, strlen(CMD_SERVICE_Operatortyp)); // 	
//		WaitResponseserver(gateway, 200);

////	delay_1ms(200);
//		EC800MSendCmd(CMD_SERVICE_SIMcardstatus, strlen(CMD_SERVICE_SIMcardstatus)); // 输入URL
//		WaitResponseserver(gateway, 200);

////	delay_1ms(200);
//	
//		EC800MSendCmd(CMD_SERVICE_SIMcardICCID, strlen(CMD_SERVICE_SIMcardICCID)); // 输入URL
//		WaitResponseserver(gateway, 200);

////delay_1ms(200);
//		EC800MSendCmd(CMD_SERVICE_IMEInumber, strlen(CMD_SERVICE_IMEInumber)); // 输入URL
//		WaitResponseserver(gateway, 200);
////delay_1ms(200);
//		EC800MSendCmd(CMD_SERVICE_Signalstrength, strlen(CMD_SERVICE_Signalstrength)); // 输入URL
//		WaitResponseserver(gateway, 200);

//}







/*
 *  函数名：bool EC800MGetUrl(char *url)
 *  输入参数：url 网址信息
 *  输出参数：无
 *  返回值：无
 *  函数作用：从对应的http获取信息
 */
bool EC800MGetUrl(char *url)
{
	// Set url
	char command[100];
	sprintf(command, CMD_SET_URL, strlen(url)); // CMD_SET_URL "%d\r\n"

	EC800MSendCmd(command, strlen(command)); // 设置服务器URL   响应若参数格式正确，且不发送 HTTP(S) GET/POST 请求：CONNECT
	WaitResponse(RSP_CONNECT, 0);
	delay_1ms(200);
	EC800MSendCmd(url, strlen(url)); // 输入URL
	if (WaitResponse(RSP_OK, 5000) == false)
		return false;

	// Send get request
	delay_1ms(200);
	EC800MSendCmd(CMD_GET, strlen(CMD_GET)); // 向服务器发送get请求
	if (WaitResponse("QHTTPGET:", 5000) == false)
		return false;

	// read to UFS
	delay_1ms(200);
	EC800MSendCmd(CMD_GET_TO_FILE, strlen(CMD_GET_TO_FILE)); //"AT+QHTTPREADFILE=\"UFS:http.txt\",80\r\n"
	if (WaitResponse("QHTTPREADFILE:", 5000) == false)
		return false;

	// get data from UFS
	delay_1ms(1000);
	EC800MSendCmd(CMD_READ_FILE, strlen(CMD_READ_FILE)); //"AT+QFDWL=http.txt\r\n"
	delay_1ms(6000);

	return true;
}

/*
 *  函数名：void ConnectMQTTSever(uint8_t *host, uint16_t port, uint8_t keepalive, uint8_t *clientid)
 *  输入参数：host:mqtt服务器IP port：mqtt端口，keepalive mqtt心跳时间，clientid设备id
 *  输出参数：无
 *  返回值：无
*  函数作用:与服务器建立连接
 */
void ConnectMQTTSever(uint8_t *host, uint16_t port, uint8_t keepalive, uint8_t *clientid)
{
	char cmd[150];
	bool success = false;
	int retry_count = 0;

	// 主动断开连接
	EC800MSendCmd(CMD_MQTT_DISCONNECT, 0);

	// 设置mqtt版本
	EC800MSendCmd(CMD_MQTT_VERSION, strlen(CMD_MQTT_VERSION));
	WaitResponse(RSP_OK, 100);

	sprintf(cmd, "AT+QMTCFG=\"qmtping\",0,%d\r\n", keepalive);
	EC800MSendCmd(cmd, strlen(cmd));
	WaitResponse(RSP_OK, 0);
	// EC800MSendCmd(CMD_MQTT_DISCONNECT, 0);

	sprintf(cmd, "AT+QMTOPEN=0,\"%s\",%d\r\n", host, port);

	do
	{
		EC800MSendCmd(cmd, strlen(cmd));
		success = WaitResponse("QMTOPEN: 0,0", 1000);
		retry_count++;
	} while (!success && retry_count < 3);

	if (success)
	{
		retry_count = 0;
		sprintf(cmd, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n", clientid, "", ""); // 后两个为username password
		do
		{
			EC800MSendCmd(cmd, strlen(cmd));
			success = WaitResponse("QMTCONN: 0,0,0", 1000);
			retry_count++;
		} while (!success && retry_count < 3);
	}
}

///*
// *  函数名：void MQTTPublish(CONFIG_PARAMS *gateway)
// *  输入参数：CONFIG_PARAMS *gateway 网关内存储信息
// *  输出参数：无
// *  返回值：无
// *  函数作用：读出采集到的数据进行上报,若未采集到数据则不进行任何处理 23/4/4添加testId测试丢包情况
// */
//void MQTTPublish(CONFIG_PARAMS *gateway)
//{
//	char payload_out[200];
//	char mqtt_publish[200];
//	if (gateway->dataSource == 1) // 645协议查询到的值进行上报
//	{
//		for (int i = 0; i < gateway->device_read_data_num; i++)
//		{
//			if (gateway->device_read_data[i].rxLen!= 0)
//			{
//				float value;
//			
//				uint8_t minute,hour,day,month,year;
//				switch (gateway->device_read_data[i].rxLen)
//				{
//					case 0:
//					case 1:
//					case 2:
//					case 3:
//					case 4:		
//							memcpy(&value, gateway->device_read_data[i].data, 4); // 取出相应的值给value
//							sprintf((char *)payload_out,
//								"{\"deviceId\":\"%s\",\"data\":[{\"deviceId\":\"%s\",\"%s\": %.2f}]}",
//									gateway->deviceId,
//									gateway->device_read_data[i].deviceId,
//									gateway->device_read_data[i].keyword,
//									value);
//						break;
//					case 5:
//						memcpy(&value, gateway->device_read_data[i].data, 4);
//						year =gateway->device_read_data[i].data[4];
//						month = gateway->device_read_data[i].data[3];
//						day = gateway->device_read_data[i].data[2];
//						hour = gateway->device_read_data[i].data[1];
//						minute = gateway->device_read_data[i].data[0];
//						sprintf((char *)payload_out,
//								"{\"deviceId\":\"%s\",\"data\":[{\"deviceId\":\"%s\",\"%s\": \"%02X%02X%02X%02X%02X\"}]}",
//								gateway->deviceId,gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,year,month,day,hour,minute);
//						break;
//					case 6:
//					case 7:
//					case 8:
//					case 9:
//						memcpy(&value, gateway->device_read_data[i].data, 4);
//						year =gateway->device_read_data[i].data[8];
//						month = gateway->device_read_data[i].data[7];
//						day = gateway->device_read_data[i].data[6];
//						hour = gateway->device_read_data[i].data[5];
//						minute = gateway->device_read_data[i].data[4];
//						sprintf((char *)payload_out,
//								"{\"deviceId\":\"%s\",\"data\":[{\"deviceId\":\"%s\",\"%s\":\"%02X%02X%02X%02X%02X%.2f\"}]}",
//								gateway->deviceId,gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,year,month,day,hour,minute,value);
//						break;
//						default:
//							//不在此区域要清空上一次sprintf
//						break;
//					}
//					sprintf((char *)mqtt_publish, "AT+QMTPUBEX=0,0,0,0,\"%s\",%d\r\n", gateway->messageTopic, strlen(payload_out));
//					EC800MSendCmd(mqtt_publish, strlen(mqtt_publish));
//					WaitResponse("QMTPUBEX", 1000);
//					delay_1ms(50);
//					EC800MSendCmd(payload_out, strlen(payload_out));
//					//WaitResponse(RSP_OK, 1000);
//					//特殊处理2023、6、28日添加publish失败重新订阅MQTT平台
//					if(WaitResponse("QMTPUBEX", 1000)==false)
//					{
//						ConnectMQTTSever(gateway->host, gateway->port, 60, gateway->deviceId);
//						MQTTSubTopic(gateway->commandTopic);
//					}
//						
//			}
//		}
//	}
//	else if (gateway->dataSource == 2) // modbus协议处理
//	{
//		for (int i = 0; i < gateway->device_read_data_num; i++)
//		{
//			if (gateway->device_read_data[i].rxLen!= 0)
//			{
//				// 功能码03、01需要分开，因功能码01查询到的值为开关转台
//				if (gateway->device_read_data[i].mdbFunctionCode == 0x03)
//				{
//					if(gateway->device_read_data[i].decimalPoint!=0)
//					{
//					float value;
//					memcpy(&value, gateway->device_read_data[i].data, 4); // 取出相应的值给value
//					sprintf((char *)payload_out,
//							"{\"deviceId\":\"%s\",\"data\":[{\"deviceId\":\"%s\",\"%s\": %.2f\r\n}]}",
//							gateway->deviceId,
//							gateway->device_read_data[i].deviceId,
//							gateway->device_read_data[i].keyword,
//							value);
//					}
//					else if(gateway->device_read_data[i].decimalPoint==0)
//					{
//						uint32_t value;
//						value=gateway->device_read_data[i].data[0]+(gateway->device_read_data[i].data[1]>>8)+(gateway->device_read_data[i].data[2]>>16)+(gateway->device_read_data[i].data[3]>>24);
//						sprintf((char *)payload_out,
//							"{\"deviceId\":\"%s\",\"data\":[{\"deviceId\":\"%s\",\"%s\": %d\r\n}]}",
//							gateway->deviceId,
//							gateway->device_read_data[i].deviceId,
//							gateway->device_read_data[i].keyword,
//							value);
//					}
//					
//				}
//				else if (gateway->device_read_data[i].mdbFunctionCode == 0x01)
//				{
//					uint8_t value[4];
//					uint8_t state;
//					memcpy(&value, gateway->device_read_data[i].data, 4);
//					if (value[2] == 0xFF)
//					{
//						state = 1;
//					}
//					else
//					{
//						state = 0;
//					}
//					sprintf((char *)payload_out,
//							"{\"deviceId\":\"%s\",\"data\":[{\"deviceId\":\"%s\",\"%s\": %d}]}",
//							gateway->deviceId,
//							gateway->device_read_data[i].deviceId,
//							gateway->device_read_data[i].keyword,
//							state);
//				}
//				sprintf((char *)mqtt_publish, "AT+QMTPUBEX=0,0,0,0,\"%s\",%d\r\n", gateway->messageTopic, strlen(payload_out));
//				EC800MSendCmd(mqtt_publish, strlen(mqtt_publish));
//				WaitResponse("QMTPUBEX", 1000);
//					delay_1ms(50);
//					EC800MSendCmd(payload_out, strlen(payload_out));
//					//WaitResponse(RSP_OK, 1000);
//					//特殊处理2023、6、28日添加publish失败重新订阅MQTT平台
//					if(WaitResponse("QMTPUBEX", 1000)==false)
//					{
//						NVIC_SystemReset();
//					}
//						
//			}
//		}
//		
//	}
//}
/*
 *  函数名：void MQTTPublish(CONFIG_PARAMS *gateway)
 *  输入参数：CONFIG_PARAMS *gateway 网关内存储信息
 *  输出参数：无
 *  返回值：无
 *  函数作用：读出采集到的数据进行上报,若未采集到数据则不进行任何处理 23/4/4添加testId测试丢包情况7/18日重写此方法
 */
void MQTTPublish(CONFIG_PARAMS *gateway)
{
	char *payload_out=malloc(2*1024);         //要发送的字符串
	memset(payload_out,0,2*1024);
	char mqtt_publish[200];        //发送字符串的指令
	sprintf((char *)payload_out,"{\"deviceId\":\"%s\",\"data\":[",gateway->deviceId);//组成json头部
	for (int i = 0; i < gateway->device_read_data_num; i++)
	{
		if (gateway->dataSource == 1)
		{
			if (gateway->device_read_data[i].rxLen!= 0) //dlt645
			{
				float value;
			
				uint8_t minute,hour,day,month,year;
				switch (gateway->device_read_data[i].rxLen)
				{
					case 0:
					case 1:
					case 2:
					case 3:
					case 4:		
							memcpy(&value, gateway->device_read_data[i].data, 4); // 取出相应的值给value
							sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %.2f},",gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,value);
						break;
					case 5:
						memcpy(&value, gateway->device_read_data[i].data, 4);
						year =gateway->device_read_data[i].data[4];
						month = gateway->device_read_data[i].data[3];
						day = gateway->device_read_data[i].data[2];
						hour = gateway->device_read_data[i].data[1];
						minute = gateway->device_read_data[i].data[0];
						sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": \"%02X%02X%02X%02X%02X\"},",gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,year,month,day,hour,minute);
						break;
					case 6:
					case 7:
					case 8:
					case 9:
						memcpy(&value, gateway->device_read_data[i].data, 4);
						year =gateway->device_read_data[i].data[8];
						month = gateway->device_read_data[i].data[7];
						day = gateway->device_read_data[i].data[6];
						hour = gateway->device_read_data[i].data[5];
						minute = gateway->device_read_data[i].data[4];
						sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\":\"%02X%02X%02X%02X%02X%.2f\"},",gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,year,month,day,hour,minute,value);
						break;
						default:
							//不在此区域要清空上一次sprintf
						break;
					}
			}
		}
		else if(gateway->dataSource == 2)  //modbus
		{
			if (gateway->device_read_data[i].rxLen!= 0)
			{
				// 功能码03、01需要分开，因功能码01查询到的值为开关转台
				if (gateway->device_read_data[i].mdbFunctionCode == 0x03)
				{
					if(gateway->device_read_data[i].decimalPoint!=0)
					{
						float value;
						memcpy(&value, gateway->device_read_data[i].data, 4); // 取出相应的值给value
						sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %.2f},",gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,value);
					}
					else if(gateway->device_read_data[i].decimalPoint==0)
					{
						uint32_t value;
						value=gateway->device_read_data[i].data[0]+(gateway->device_read_data[i].data[1]>>8)+(gateway->device_read_data[i].data[2]>>16)+(gateway->device_read_data[i].data[3]>>24);
						sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %d},",gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,value);
					}
				}
				else if (gateway->device_read_data[i].mdbFunctionCode == 0x01)
				{
					uint8_t value[4];
					uint8_t state;
					memcpy(&value, gateway->device_read_data[i].data, 4);
					if (value[2] == 0xFF)
					{
						state = 1;
					}
					else
					{
						state = 0;
					}
					sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %d},",gateway->device_read_data[i].deviceId,gateway->device_read_data[i].keyword,state);
				}
		}
	}
}
	sprintf(payload_out+strlen(payload_out)-1,"]}");
	sprintf((char *)mqtt_publish, "AT+QMTPUBEX=0,0,0,0,\"%s\",%d\r\n", gateway->messageTopic, strlen(payload_out));
	EC800MSendCmd(mqtt_publish, strlen(mqtt_publish));
	WaitResponse("QMTPUBEX", 1000);	
	delay_1ms(50);
	EC800MSendCmd(payload_out, strlen(payload_out));
	free(payload_out);
	payload_out=NULL;

	
	//特殊处理2023、6、28日添加publish失败重新订阅MQTT平台
	if(WaitResponse("QMTPUBEX", 1000)==false)
	{
		NVIC_SystemReset();
	}
}
/*
 *  函数名：void MQTTSubTopic(uint8_t *commandTopic)
 *  输入参数：uint8_t *commandTopic 订阅的主题
 *  输出参数：无
 *  返回值：无
 *  函数作用：读出采集到的数据进行上报,若未采集到数据则不进行任何处理
 */
void MQTTSubTopic(uint8_t *commandTopic)
{
	char AT_SUB[100];
	sprintf(AT_SUB, "AT+QMTSUB=0,1,\"%s\",0\r\n", commandTopic);
	bool success = false;
	uint8_t retry_count = 0;
	do
	{
		EC800MSendCmd(AT_SUB, strlen(AT_SUB));
		success = WaitResponse(RSP_OK, 1000);
		retry_count++;
	} while (!success && retry_count < 3);
}
