/** ******************************************************************************
 * @file    ME3616.c
 * @author  度云未来 DOIOT
 * @brief   EC20模块AT指令简易串口驱动
 ******************************************************************************
 * @attention
 * <h2><center>&copy; Copyright (c) 2019 成都度云未来
 * All rights reserved.</center></h2>
 * 注意:本程序针对cubemx 生成的hal库快速开发
 * 环境:keil5.0
 * 描述：
 * 文件版本：1.3		更新时间2020/10/15   已支持TCP,LWM2M的连接
 ********************************************************************************/
/*必备依赖*/
#include "includes.h"
#include "trace.h"
#include "me3616.h"				 	/*文件的头文件*/
#include "at_module.h"		 	/*AT指令相关的头文件*/
#include "string_fuc.h"

#include <stdarg.h>		
#include <string.h>		
#include <stdlib.h>		
#include <stdio.h>	
/********************************************************************************/
/*
测试了strstr和kmp的性能，最终用strstr。
*/
/* me3616类的句柄,该句柄会默认调用 */
ME3616  me3616;

/*发送的指令组，需要校验的响应组，校验组数量，校验等级，重发次数，跳转位置，超时时间*/

/**
* @brief  ME3616句柄的构造函数
* @param  该函数会对本文件核心全局句柄进行函数构造
*/		
ME3616 * ME3616_Init()
{
	ME3616 * me=&me3616;

	#if(config_MQTT_Enable)

	MQTT mqtt;

	me->MQTT=mqtt;

	me->MQTT.SetNet=MQTT_Set_Net;

	me->MQTT.Connect=MQTT_Connet;

	me->MQTT.Sub=MQTT_SUB;

	me->MQTT.Pub=MQTT_PUB;
  #endif
	me->imei_iccid_get = ME3616_IMEI_ICCID_INFO_GET;
  
	#if(config_TCP_Enable)
	TCP tcp;		/*创建实体*/

	me->TCP=tcp;

	me->TCP.CreateChannel=ME3616_Connect_TCP;

	me->TCP.CloseChannel=Close_TCP_Socket;

	me->TCP.SendStr=ME3616_TCP_SEND_String;

	me->TCP.SendHex=ME3616_TCP_SEND_Hex;

	me->TCP.GetData=ME3616_TCP_DATA_purification;
	#endif

	me->PowerOn=ME3616_Power_On;
	#if(Hvertion_data)
	me->HardRest=ME3616_HARD_Rest;
	#endif
	
	#if(SoftRest_fun)
	me->SoftRest=ME3616_SOFT_Rest;
	#endif
	#if(GetEPS_fun)
	me->GetEPS=ME3616_READ_EPS;
	#endif
	#if(GetCSQ_fun)
	me->GetCSQ=ME3616_READ_CSQ;
	#endif
	me->GetCESQ=ME3616_READ_CESQ;
	#if(GetCCID_fun)
	me->GetCCID=ME3616_READ_CCID;
	#endif
	me->GetPIN=ME3616_READ_PIN;
	
	
	#if(IMEI_ME3616_INFOrmation)
	me->GetIMEI=ME3616_READ_IMEI;
	#endif
	#if(Svertion_data)
	me->Version=ME3616_READ_Revision;
	#endif
	#if(ICCID_ME3616_INFOrmation)
	memset(me->State.iccid,0,50);
	#endif
	#if(IMEI_ME3616_INFOrmation)
	memset(me->State.imei,0,50);
	#endif
	memset(me->State.imsi,0,50);
	#if(MAC_ME3616_INFOrmation)
	memset(me->State.mac,0,50);
	#endif
	#if(Hvertion_data)
	memset(me->State.Hvertion,0,50);
	#endif
	#if(Svertion_data)
	memset(me->State.Svertion,0,50);
	#endif
	#if(config_LMW2M_Enable)
	memset(me->State.msgid,0,20);
	#endif
	#if(ICCID_ME3616_INFOrmation)
	me->flug.iccid=0;
	#endif
	#if(IMEI_ME3616_INFOrmation)
	me->flug.imei=0;
	#endif
	me->flug.imsi=0;
	#if(MAC_ME3616_INFOrmation)
	me->flug.mac=0;
	#endif
	#if(Hvertion_data)
	me->flug.Hvertion=0;
	#endif
	#if(Svertion_data)
	me->flug.Svertion=0;
	#endif
	me->flug.pwr=0;
	me->flug.rssi=0;
	me->flug.ber=0;
	me->flug.eps=0;
	me->flug.pin=0;
	me->flug.rest=0;
	
	#if defined (config_TCP_Enable_Disconnection_reconnection)
	me->flug.tcp_recon=0;
	#endif	
	
	#if(config_LMW2M_Enable)
	me->flug.msgid=0;
	#endif
	
//		UartModuleInit();
	return me;
}


uint8_t ME3616_Check_State()
{
	
	#if (config_TCP_Enable_heart)	/*心跳*/	
	
	if(me3616.State.TCP_State==1)
	{
		debug_printf("\r\n开始心跳\r\n");
		char temp[256]={0};
		Chaoyou_package("01","",temp);
		Check_Package(temp);
		me3616.TCP.send_Str(temp);	
	}
	#endif	
	
	
	#if (config_CEREG)	/*网络检查*/	
	if(me3616.State.TCP_State==1)
	{
		
		
		
		
	}
	#endif		
	
	#if (config_TCP_Enable_Disconnection_reconnection)	/*重连检查*/
	if(me3616.flug.tcp_recon)
	{
		if(me3616.State.TCP_State==0)
		{
			/*检查到掉线*/
			me3616.flug.rest=1;
		}
		else
		{
			debug_printf("TCP连接正常");
		}
		
	}
	#endif
	
	return 1;
}

	
/**
* @brief  ME3616硬件开机
* @param	flug = 1,阻塞开机，会直到开机成功，且读取完全部开机信息后才会退出
* @param	flug = 0,操作完硬件开机后立即返回
* @param  [Antiphase_flug]额外参数	: 以宏形式的标志，1为反相，0为不反相
* 【是否反相根据硬件电路决定，如果mcu拉低，模组也被拉低，则不需要反相，否则给反相位置1即可】
* 	如果在计时器启动前调用了，建议选择直接返回[针对RTOS]
*/	
uint8_t ME3616_Power_On(uint8_t flug)
{
	OS_ERR err;
	
		#if(config_CHINESE_LOG)
		ME3616_INFO("ME3616 硬件开机");	
		#else
		ME3616_INFO("ME3616 Hardware Power On");	
		#endif

		if(AT_CMD_Polling("AT\r\n","OK",100,300))
		{
			me3616.State.pwr=1;
			#if(config_CHINESE_LOG)
			ME3616_INFO("ME3616 完成开机");	
			#else
			ME3616_INFO("ME3616 Power On");
			#endif
			return 1;
		}
	#if 0
		if(config_Antiphase_flug)
		{
		PWR_IO_PORT->ODR|=PWR_IO_PIN;/*拉低PWR引脚*/
		OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err);	
		//HAL_Delay(2000);							/*延时两秒*/
		PWR_IO_PORT->ODR&=!PWR_IO_PIN; /*拉高PWR引脚*/	
		}
		else
		{
		PWR_IO_PORT->ODR&=!PWR_IO_PIN;/*拉低PWR引脚*/
		OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err);	
		//HAL_Delay(2000);							/*延时两秒*/
		PWR_IO_PORT->ODR|=PWR_IO_PIN; /*拉高PWR引脚*/
		}
	#endif
		if(flug)
		{
		
		char buff[MODULE_RDA_MAXlen]={0};
		
				/*这里是为了吃掉三条开机信息，如果直接开始往下运行，开就信息可能会干扰*/
				if(Module_Blocking_Read(buff,20000))
				{
					me3616.State.pwr=1;
					if(strstr(buff,"*MATREADY:"))
					{
						memset(buff,0,MODULE_RDA_MAXlen);
						if(Module_Blocking_Read(buff,6000))
						{

							if(strstr(buff,"+CPIN:"))
							{
								memset(buff,0,MODULE_RDA_MAXlen);
									if(Module_Blocking_Read(buff,60000))
									{
										if(strstr(buff,"+IP:")) 
										{
											/*完整开机需要的时常很长*/
											AT_CMD_Polling("AT\r\n","OK",200,15000);
											AT_CMD_Polling("AT\r\n","OK",200,15000);
											AT_CMD_Polling("AT\r\n","OK",200,15000);
											
											ME3616_INFO("ME3616 Hardware Power On OK!");
											return 1;
										}
									}
							}
					 }
					}
				}
		}
		return 0;
}	


/**
* @brief  ME3616硬件复位
*	@param  flug:复位标志，1，阻塞复位，会直到开机成功才退出，开机时间较长，2，立即返回*/
uint8_t ME3616_HARD_Rest(uint8_t flug)
{		
	OS_ERR err;
		#if(config_CHINESE_LOG)
		ME3616_INFO("ME3616开始硬件复位");
		#else
		ME3616_INFO("ME3616 Hardware Reset");
		#endif
		if(config_Antiphase_flug)
		{
		RST_IO_PORT->ODR|=RST_IO_PIN;/*拉低PWR引脚*/
		OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err);	
		//HAL_Delay(2000);							/*延时两秒*/
		RST_IO_PORT->ODR&=!RST_IO_PIN; /*拉高PWR引脚*/	
		}
		else
		{
		RST_IO_PORT->ODR&=!RST_IO_PIN;/*拉低PWR引脚*/
		OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err);	
		//HAL_Delay(2000);							/*延时两秒*/
		RST_IO_PORT->ODR|=RST_IO_PIN; /*拉高PWR引脚*/
		}
		if(flug)
		{
		/*这里是为了吃掉三条开机信息，如果直接开始往下运行，开就信息可能会干扰*/
		char buff[MODULE_RDA_MAXlen]={0};
		if(Module_Blocking_Read(buff,20000))
		{
			me3616.State.pwr=1;
			if(strstr(buff,"*MATREADY:"))
			{
				memset(buff,0,MODULE_RDA_MAXlen);
				if(Module_Blocking_Read(buff,6000))
				{

					if(strstr(buff,"+CPIN:"))
					{
						memset(buff,0,MODULE_RDA_MAXlen);
							if(Module_Blocking_Read(buff,6000))
							{
								if(strstr(buff,"+IP:")) 
								{
									/*完整开机需要的时常很长*/
									AT_CMD_Polling("AT\r\n","OK",200,15000);
									AT_CMD_Polling("AT\r\n","OK",200,15000);
									AT_CMD_Polling("AT\r\n","OK",200,15000);
									ME3616_INFO("ME3616 Hardware Reset OK!");
									return 1;
								}
							}
					}
				}
			}
		}
		}
		return 1;
}

/**
* @brief  ME3616软件复位
*	@param  flug:复位标志，1，阻塞复位，会直到开机成功才退出，软复位很快，2，立即返回*/
uint8_t ME3616_SOFT_Rest(uint8_t flug)
{		

		#if(config_CHINESE_LOG)
		ME3616_INFO("ME3616开始软件复位");
		#else
		ME3616_INFO("ME3616 Software Reset");
		#endif
		Module_SEND_CRC("AT+ZRST\r\n","OK",500);
	
		if(flug)
		{
		/*这里是为了吃掉三条开机信息，如果直接开始往下运行，开就信息可能会干扰*/
		char buff[MODULE_RDA_MAXlen]={0};
		if(Module_Blocking_Read(buff,20000))
		{
			me3616.State.pwr=1;
			if(strstr(buff,"*MATREADY:"))
			{
				memset(buff,0,MODULE_RDA_MAXlen);
				if(Module_Blocking_Read(buff,6000))
				{

					if(strstr(buff,"+CPIN:"))
					{
						memset(buff,0,MODULE_RDA_MAXlen);
							if(Module_Blocking_Read(buff,6000))
							{
								if(strstr(buff,"+IP:")) 
								{
									/*完整开机需要的时常很长*/
									AT_CMD_Polling("AT\r\n","OK",200,15000);
									AT_CMD_Polling("AT\r\n","OK",200,15000);
									AT_CMD_Polling("AT\r\n","OK",200,15000);
									ME3616_INFO("ME3616 Software Reset OK!");
									return 1;
								}
							}
					}
			 }
		}
		}
		}
		return 1;
}

/**
* @brief  ME3616读取网络状态并打印数据
**/
uint8_t ME3616_READ_EPS()
{
	char buff[MODULE_RDA_MAXlen]={0};
	char get_buff[100];
	int log;
	ME3616_INFO("Start to query network registration status");
	module_printf("AT+CEREG?\r\n");
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"+CEREG:"))
		{
			AT_GET_Data_2Param(buff,(uint8_t*)get_buff,",","OK");
			log=atoi(get_buff);
			me3616.State.eps=log;	/*装载标数据*/
			me3616.flug.eps=1;		/*装载成功标志*/
			switch(log)
			{			
				case 0: ME3616_INFO("You are not logged on to the network. You are not searching the network at present"); break;
				case 1: ME3616_INFO("Local network already logged in"); break;
				case 2: ME3616_INFO("\r\nYou are not logged on to the network. You are currently searching the network\r\n"); break;
				case 3: ME3616_INFO("\r\nRegistration denied\r\n"); break;
				case 4: ME3616_INFO("\r\nUnknown state\r\n"); break;
				case 5: ME3616_INFO("\r\nYou have logged in to the network and are roaming\r\n"); break;
				default: 
				{
					ME3616_ERROR("Response ME3616_ERROR:%s",buff);
					return  33;//设定的错误码
				}
			}
		return log+1;
		}
		{
		ME3616_ERROR("%s",buff);
		return 0;
		}
	} 
	ME3616_INFO("Response timeout");
	return 0;
}


/**
* @brief  ME3616读取网络信号强度
* @param  rssi:用来装载的参数，会装载信号强度原文[弃用]
* @param  ber:用来装载的参数， 会装载错码率原文[弃用]
*	*/
uint8_t ME3616_READ_CSQ()
{
	char buff[MODULE_RDA_MAXlen]={0};
	char get_buff[32]={0};
	int log;
	
	#if(config_CHINESE_LOG)
	ME3616_INFO("开始查询网络信号强度");
	#else
	ME3616_INFO("Start querying network signal strength");
	#endif

	module_printf("AT+CSQ\r\n");
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"+CSQ:"))
		{
			AT_GET_Data_2Param(buff,(uint8_t*)get_buff,"+CSQ:",",");
			log=atoi(get_buff);
			me3616.State.rssi=log;
			me3616.flug.rssi=1;		/*装载成功标志*/
			if(log==99) 							{ME3616_INFO("signal intensity:there is no signal");}
			else if(log>=31&&log<=99) {ME3616_INFO("signal intensity:-51dBm or higher");}
			else if(log>=2&&log<31)		{ME3616_INFO("signal intensity:-109dBm ~ -53dBm");}
			else if(log==1)						{ME3616_INFO("signal intensity:-111dBm");}
			else 											{ME3616_INFO("signal intensity:-111dBm or less");}
			
			AT_GET_Data_2Param(buff,(uint8_t*)get_buff,",","OK");
			log=atoi(get_buff);
			me3616.State.ber=log;
			me3616.flug.ber=1;		/*装载成功标志*/
			//*ber=log;
			switch(log)
			{	
				case 0: ME3616_INFO("Bit error rate:<0.01%"); break;
				case 1: ME3616_INFO("Bit error rate:0.01% --- 0.1%"); break;
				case 2: ME3616_INFO("Bit error rate:0.1% --- 0.5%"); break;
				case 3: ME3616_INFO("Bit error rate:0.5% --- 1.0%"); break;
				case 4: ME3616_INFO("Bit error rate:1.0% --- 2.0%"); break;
				case 5: ME3616_INFO("Bit error rate:2.0% --- 4.0%"); break;
				case 6: ME3616_INFO("Bit error rate:4.0% --- 8.0%"); break;
				case 7: ME3616_INFO("Bit error rate:> 8.0%"); break;
				case 8: ME3616_INFO("Bit error rate:So far or not measurable");break;
				default: 
				{
					ME3616_ERROR("So far or not measurable");
					return  33;//设定的错误码
				}
			}
		return log+1;
		}
		{
		ME3616_ERROR("%s",buff);
		return 0;
		}
	} 
	
	ME3616_INFO("Response timeout");
	return 0;
}

/**
* @brief  ME3616读取精确的网络信号强度
*	*/
int ME3616_READ_CESQ()
{
	char buff[MODULE_RDA_MAXlen]={0};
	char get_buff[100]={0};
	int log;
	ME3616_INFO("Start querying network signal strength");
	module_printf("AT+CESQ\r\n");
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"+CESQ:"))
		{
			AT_GET_Data_2Param(buff,(uint8_t*)get_buff,"+CESQ: ",",");
			log=atoi(get_buff);
			//me3616.State.rssi=log;
			me3616.flug.dBm=1;		/*装载成功标志*/
			log=atoi(get_buff);
			
			log+=-110;/*转化成dBm*/
			me3616.State.dBm=log;
			
			ME3616_INFO("signal intensity:%ddBm");
		return log+1;
		}
		{
		ME3616_ERROR("%s",buff);
		return 0;
		}
	} 
	ME3616_INFO("Response timeout");
	return 0;
}
/**
* @brief  ME3616读取SIM卡的CCID
* @param  rssi:用来装载的参数，会装载信号强度原文
* @param  ber:用来装载的参数， 会装载错码率原文
*	*/
uint8_t ME3616_READ_CCID()
{
	char buff[MODULE_RDA_MAXlen]={0};
	char get_buff[32]={'\0'};
	
	ME3616_INFO("Start to query SIM card iccid");
	module_printf("AT*MICCID\r\n");
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"*MICCID:"))
		{
			if(AT_GET_Data_2Param(buff,(uint8_t*)get_buff,"*MICCID: ","\n\r"))//0d0a
			{
			#if(IMEI_ME3616_INFOrmation)
			strcpy(me3616.State.iccid,get_buff);
			me3616.flug.iccid=1;		/*装载成功标志*/
			#endif
			debug_printf("\r\nICCID:");
			debug_printf("%s\r\n", get_buff);
			}
			else 
			{
				ME3616_ERROR("%s",buff);
				ME3616_INFO("%s",buff);
				return 0;
			}
		return 1;
		}
		else{
			if(strstr(buff,"SIM not inserted"))
			{
				ME3616_INFO("SIM card not inserted,Please check the SIM card");
				return 0;
			}
			else
			{
					ME3616_ERROR("%s",buff);
					return 0;
			}
		}
	} 
	ME3616_INFO("Response timeout");
	return 0;
}


/**
* @brief  ME3616查询pin状态
* @param  return 1 为ready，0 其他
*	*/
uint8_t ME3616_READ_PIN()
{
	char buff[256]={0};

	#if(config_CHINESE_LOG)
	ME3616_INFO("开始查询PIN状态");
	#else
	ME3616_INFO("Start to query pin status");
	#endif
	
	module_printf("AT+CPIN?\r\n");
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"+CPIN:"))
		{
			
			me3616.State.pin=1;
			me3616.flug.pin=1;		/*装载成功标志*/
			
			#if(config_CHINESE_LOG)
			if(strstr(buff,"READY")) 				{ME3616_INFO("PIN状态: READY,已准备好");return 1;}
			else if(strstr(buff,"SIM PIN")) {ME3616_INFO("PIN状态: 需要pin码");return 1;}
			else if(strstr(buff,"SIM PUK")) {ME3616_INFO("PIN状态: PIN 码解锁密码");return 1;}
			else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("PIN状态: SIM 卡绑定密码");return 1;}
			else if(strstr(buff,"SIM PIN2")) {ME3616_INFO("PIN状态: PIN2 码密码");return 1;}
			else if(strstr(buff,"SIM PUK2")) {ME3616_INFO("PIN状态: PIN2 码解锁密码");return 1;}
			else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("PIN状态: 网络密码");return 1;}
			#else
			if(strstr(buff,"READY")) 					 {ME3616_INFO("Pin status: READY");return 1;}
			else if(strstr(buff,"SIM PIN"))	   {ME3616_INFO("Pin status: need pin");return 1;}
			else if(strstr(buff,"SIM PUK")) 	 {ME3616_INFO("Pin status: Pin code unlock password");return 1;}
			else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("Pin status: SIM card binding password");return 1;}
			else if(strstr(buff,"SIM PIN2"))   {ME3616_INFO("Pin status: Pin2 code");return 1;}
			else if(strstr(buff,"SIM PUK2"))   {ME3616_INFO("Pin status: Pin2 code unlock password");return 1;}
			else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("Pin status: Network password");return 1;}
			#endif
		}
		else{
		ME3616_ERROR("%s",buff);
		return 0;
		}
	} 
	ME3616_INFO("Response timeout");
	return 0;
}

/**
* @brief  ME3616查询CIMI状态
*	*/
uint8_t ME3616_READ_CIMI()
{
	char buff[MODULE_RDA_MAXlen]={0};
	#if(config_CHINESE_LOG)
	ME3616_INFO("开始查询PIN状态");
	#else
	ME3616_INFO("Start to query pin status");
	#endif
	module_printf("AT+CPIN?\r\n");
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"+CPIN:"))
		{
			#if(config_CHINESE_LOG)
			if(strstr(buff,"READY")) {ME3616_INFO("PIN状态: READY,已准备好");return 1;}
			else if(strstr(buff,"SIM PIN")) {ME3616_INFO("PIN状态: 需要pin码");return 1;}
			else if(strstr(buff,"SIM PUK")) {ME3616_INFO("PIN状态: PIN 码解锁密码");return 1;}
			else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("PIN状态: SIM 卡绑定密码");return 1;}
			else if(strstr(buff,"SIM PIN2")) {ME3616_INFO("PIN状态: PIN2 码密码");return 1;}
			else if(strstr(buff,"SIM PUK2")) {ME3616_INFO("PIN状态: PIN2 码解锁密码");return 1;}
			else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("PIN状态: 网络密码");return 1;}
			#else
			if(strstr(buff,"READY")) {ME3616_INFO("Pin status: READY");return 1;}
			else if(strstr(buff,"SIM PIN")) {ME3616_INFO("Pin status: need pin");return 1;}
			else if(strstr(buff,"SIM PUK")) {ME3616_INFO("Pin status: Pin code unlock password");return 1;}
			else if(strstr(buff,"PH-SIM PIN")) {ME3616_INFO("Pin status: SIM card binding password");return 1;}
			else if(strstr(buff,"SIM PIN2")) {ME3616_INFO("Pin status: Pin2 code");return 1;}
			else if(strstr(buff,"SIM PUK2")) {ME3616_INFO("Pin status: Pin2 code unlock password");return 1;}
			else if(strstr(buff,"PH-NET PIN")) {ME3616_INFO("Pin status: Network password");return 1;}
			#endif

		}
		else{
		
		ME3616_ERROR("%s",buff);
		return 0;
		}
	} 
	ME3616_INFO("Response timeout");
	return 0;
}
#if(IMEI_ME3616_INFOrmation)
/**
* @brief  ME3616查询IMEI并装载至寄存器
* @param  
*	*/
uint8_t ME3616_READ_IMEI()
{
	rxbuff(buff);

	clear(buff);	
	ME3616_INFO("Start query IMEI");
	module_printf("ATI\r\n");
	if(Module_Blocking_Read(buff,6000))
	{
		if(strstr(buff,"IMEI"))
		{
			#if 0
				char temp[32]={0};

				memset(temp, 0 , sizeof(temp));
				AT_GET_Data_2Param(buff,(uint8_t*)temp,"IMEI: ","OK");	/*头尾提取方法*/
				AT_Extract_numbers(temp);							/*提纯数字*/
				strcat(me3616.State.imei,temp);
				ME3616_INFO("IMEI:%s\r\n",temp);
			#else
				AT_GET_Data_2Param(buff,me3616.State.imei,"IMEI: ","OK");	/*头尾提取方法*/
			#endif
				me3616.flug.imei=1;
				ME3616_INFO("IMEI:%s\r\n",me3616.State.imei);
				return 1;
		}
		else{
		ME3616_ERROR("%s",buff);
		return 0;
		}
	} 
	ME3616_INFO("Response timeout");
	return 0;
}
#endif
#if(Hvertion_data)
/**
* @brief  ME3616查询IMEI并装载至寄存器
* @param  
*	*/
uint8_t ME3616_READ_Revision()
{
	char buff[MODULE_RDA_MAXlen]={0};
	
	debug_printf("\r\n开始查询软硬件环境\r\n");
	module_printf("ATI\r\n");
	if(Module_Blocking_Read(buff,2000))
	{
		if(strstr(buff,"SwRevision: "))
		{
				char temp[256]={0};
				AT_GET_Data_2Param(buff,(uint8_t*)temp,"SwRevision: ","HwR");	/*头尾提取方法*/
				AT_Extract_numbers_letters(temp);							/*提纯数字*/
				strcat(me3616.State.Svertion,temp);
				me3616.flug.Svertion=1;
				AT_GET_Data_2Param(buff,(uint8_t*)temp,"HwRevision: ","SVN");	/*头尾提取方法*/
				AT_Extract_numbers_letters(temp);							/*提纯数字*/
				strcat(me3616.State.Hvertion,temp);
				me3616.flug.Hvertion=1;
				debug_printf("\r\nSvertion:%s",me3616.State.Svertion);
				debug_printf("Hvertion:%s\r\n",me3616.State.Hvertion);
				return 1;
		}
		else{
		debug_printf("原文：");
		debug_printf(buff);

		return 0;
		}
	} 
	ME3616_INFO("Response timeout");
	return 0;
}
#endif

void ME3616_IMEI_ICCID_INFO_GET(char *imei, char *iccid)
{
	memcpy(imei, me3616.State.imei, strlen(me3616.State.imei));
	memcpy(iccid, me3616.State.iccid, strlen(me3616.State.iccid));
}

#if(config_TCP_Enable)
/**
* @brief  ME3616关闭一个套接字
* @param  socket：套接字的句柄编号
*	*/
uint8_t ME3616_Close_Socket(uint8_t socket)
{
	char buff[MODULE_RDA_MAXlen]={0};
	module_printf("AT+ESOCL=%d\r\n",socket);//printf的重映射有问题，正在修改 
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"OK"))
		{
			ME3616_INFO("socket:%d Close OK!",socket);
			return 1;
		}
		else if(strstr(buff,"ERROR")){
		//debug_printf("\r\n关闭失败\r\n");
		return 0;
		}else 
		{	
		//	debug_printf("\r\nunknow\r\n");
		}
	}else
	{
		ME3616_INFO("Response timeout");
	}
	return 99;
}
/**
* @brief  ME3616关闭一个套接字[内部调用]
*	*/
uint8_t Close_TCP_Socket()
{
	char buff[MODULE_RDA_MAXlen]={0};
	module_printf("AT+ESOCL=%d\r\n",me3616.State.TCP_Socket);//printf的重映射有问题，正在修改 
	if(Module_Blocking_Read(buff,1000))
	{
		if(strstr(buff,"OK"))
		{
			ME3616_INFO("socket:%d Close OK!",me3616.State.TCP_Socket);
			return 1;
		}
		else if(strstr(buff,"ERROR")){
		ME3616_INFO("Closing failed");
		return 0;
		}else 
		{	
			ME3616_ERROR("%s",buff);
		}
	} 
	else
	{
		ME3616_INFO("Response timeout");
	}
	return 0;
}
/**
* @brief  ME3616创建一个Socket
* @param  IPvX	 	:	1 - IPv4	,2 - IPv6
*	@param  TCP_UDP	:	1 - TCP		,2 - UDP		,3 - RAW
*	@param  protocol:	1 - IP		,2 - ICMP
*	【创建失败返回99，创建成功返回socket的句柄编号,范围0-4】
*/
uint8_t ME3616_Create_Socket(int IPvX,int TCP_UDP,int protocol)
{
	char buff[MODULE_RDA_MAXlen]={'\0'};
	char get_buff[100]={'\0'};
	uint8_t socket=99;
	
	module_printf("AT+ESOC=%d,%d,%d\r\n",IPvX,TCP_UDP,protocol);

	if(Module_Blocking_Read(buff,1000))
	{	
		if(strstr(buff,"ERROR"))
		{
			if(strstr(buff,"too much socket instance")) 
			{
			ME3616_INFO("There is no socket channel left. Please close the socket channel");
			return  88; 
			}
			else 
			{
				ME3616_ERROR("%s",buff);
			}
		}
		else if(strstr(buff,"+ESOC="))
		{
			char *p;
//			ME3616_ERROR("\r\n原文:");
//			ME3616_ERROR((char*)buff);
			if(strlen(buff)>15) p=buff+13;
			else p=buff;
			if(AT_GET_Data_2Param(p,(uint8_t*)get_buff,"OC=","OK"))
			{
				socket=atoi(get_buff);
				me3616.State.TCP_Socket=socket;
				ME3616_INFO("Socket created successfully, No.:%d",socket);
				return socket;
			}
			else
			{
				ME3616_INFO("Socket creation failed :%d",socket);
				ME3616_ERROR("%s",buff);
				return 99;
			}
		}
		else{
		ME3616_ERROR("%s",buff);		
		return 99;
		}
	}else
	{
		ME3616_INFO("Response timeout");
		return 99;
	}
	  return 99;	
}
/**
* @brief  ME3616连接到一个Socket
* @param  socket	 	:	socket创建好的socket通道句柄编号
*	@param  port  		:	端口
*	@param  ip  			:	ip地址，或者域名支持域名解析
*	【创建失败返回99，创建成功返回socket的句柄编号,范围0-5】
*/
int ME3616_Connect_Socket(uint8_t socket,char *port,char *ip)
{
	char buff[MODULE_RDA_MAXlen]={0};
	char get_buff[100]={'\0'};
	char send_data[256]={0};
	char data_crc[256]={0};
	/*导入句柄编号*/
	sprintf(send_data,"AT+ESOCON=%d,",socket);
	/*导入端口号*/
	strcat(send_data,port);
	strcat(send_data,",\"");

	/*导入ip地址或域名*/
	strcat(send_data,ip);	
	strcpy(data_crc,send_data);
	strcat(data_crc,"\"");
	strcat(send_data,"\"\r\n");
	
	//debug_printf("\r\nSEND TO ME3616\r\n");
	//debug_printf(send_data);
	//debug_printf("\r\nCRC FIFO\r\n");
	//debug_printf(data_crc);
	
	/*发送指令*/
	module_printf(send_data);
	if(Module_Blocking_Read(buff,8000))
	{
		if(strstr(buff,"ERROR"))
		{
		ME3616_INFO("Socket connection error");	
		return 0;
		}
		else if(strstr(buff,"OK"))
		{
			ME3616_INFO("Socket connection successful");
			return 1;
		}
		else if(strstr(buff,data_crc))
		{		
				memset(buff,0,MODULE_RDA_MAXlen);
				if(Module_Blocking_Read(buff,10000))
				{
					/*注册成功*/
					if(strstr(buff,"OK")) 
					{
						ME3616_INFO("Socket connection successful");
						return 1;
					}
					else if(strstr(buff,"ERROR"))
					{
						ME3616_INFO("Socket connection error");
						//ME3616_ERROR("%s",buff);
						return 0;
					}
				}
				else 
				{
				ME3616_INFO("Response timeout");
				}
		}
		else if(strstr(buff,"+ESOERR"))
		{
			int code=0;
			/*套接字错误指示器*/
			if(AT_GET_Data_2Param(buff,(uint8_t*)get_buff,",","\n\r"))
			{
				code=atoi(get_buff);
				ESOERR_PRINT(code);	
				return code+10;
			}
		}
		else {
			ME3616_ERROR("%s",buff);
		}
	}
	else 
	{
		ME3616_INFO("Response timeout");
		return 99;	
	}
	return 0;
}
/**
* @brief  ME3616创建一个TCP连接
*	@param  port  		:	端口
*	@param  ip  			:	ip地址，或者域名支持域名解析
*	【创建失败返回99，创建成功返回socket的句柄编号,范围0-5】
*/
uint8_t  ME3616_Connect_TCP(char *port,char *ip)
{
	OS_ERR err;
	
		ME3616_Close_Socket(0);
		ME3616_Close_Socket(1);
		ME3616_Close_Socket(2);
		ME3616_Close_Socket(3);
		ME3616_Close_Socket(4);
	
	/*静态的Socket句柄*/
	static int TCP_Socket;
	uint8_t 	 Try_count=0;
	create:
	Try_count++;/*尝试次数*/
	
	/*创建一个套接字,并返回一个句柄*/
	TCP_Socket=ME3616_Create_Socket(1,1,1);
	
	if(TCP_Socket>=0&&TCP_Socket<=4) 
	{/*创套接字编号满足要求则继续*/
		ME3616_INFO("Start Connection TCP");
		//me3616.State.TCP_Socket=TCP_Socket;
	}
	else if(TCP_Socket==88)
	{
		/*88是套接字通道用尽标志*/
		ME3616_INFO("Socket Channel has no more left,Start clear");
		ME3616_Close_Socket(0);
		ME3616_Close_Socket(1);
		ME3616_Close_Socket(2);
		ME3616_Close_Socket(3);
		ME3616_Close_Socket(4);
		if(Try_count<3) goto create;
		else return 0;
	}
	else if(TCP_Socket==99)
	{
		/*99是其他error，暂未处理*/
		ME3616_INFO("Socket creation failed");
		ME3616_INFO("Try again");
		ME3616_Close_Socket(0);
		ME3616_Close_Socket(1);
		ME3616_Close_Socket(2);
		ME3616_Close_Socket(3);
		ME3616_Close_Socket(4);
		
		if(Try_count<3) goto create;
		else return 0;
	}
	OSTimeDlyHMSM(0, 0, 500, 0, OS_OPT_TIME_DLY, &err);	
	//HAL_Delay(500);
	/*创建一个TCP通道*/
	int code=ME3616_Connect_Socket(TCP_Socket,port,ip);
	
	if(code!=1)
	{
		ME3616_INFO("TCP creation failed：%d",code);
		ME3616_INFO("Try again");
		ME3616_Close_Socket(0);
		ME3616_Close_Socket(1);
		ME3616_Close_Socket(2);
		ME3616_Close_Socket(3);
		ME3616_Close_Socket(4);
		if(Try_count<3) goto create;
		
		if(code==99)
		{	
			return 0;
		}
		else if(code>=9&&code<=11)
		{
			/*带错误码返回的套接字错误*/
			return 0;
		}
		else return 0;
		
	}else if(code==1)
	{
		/*装载参数*/
		me3616.State.TCP_State=1;
		#if defined (config_TCP_Enable_Disconnection_reconnection)
		me3616.flug.tcp_recon=1;
		#endif
		ME3616_INFO("TCP connection successful (*^▽^*) ");
		ME3616_INFO("IP Address:%s\r\n>> Port:%s\r\n>> Socket:%d ",ip,port,TCP_Socket);
		return 1;
	}	/*code==1是唯一正确的返回*/
	else
	{
		ME3616_INFO("TCP creation failed ");
		return 0;
	}
}

uint8_t  ME3616_TCP_SEND_String(char *str)
{
		if(me3616.State.TCP_State==1)
		{
			uint16_t len=strlen(str);
			if(len>0&&len<512)
			{
				char str_arry[strlen(str)+1];		
				memset(str_arry,0,strlen(str)+1);
				AsciiStr_2_HexStr(str,str_arry);
				
				module_printf("AT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,strlen(str),str_arry);
				//ME3616_INFO("\r\nAT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,strlen(str),str_arry);
				char rxbuf[MODULE_RDA_MAXlen]={0};
				if(Module_Blocking_Read(rxbuf,5000))
				{
					//debug_printf(rxbuf);
					if(strstr(rxbuf,"+ESONMI")||strstr(rxbuf,"OK"))
					{
						ME3616_INFO("Send:%s",str);
						ME3616_INFO("Sent successfully");
					}
					else if(strstr(rxbuf,"ERROR"))
					{
						ME3616_ERROR("%s",rxbuf);
					}
				}else 
				{
					ME3616_INFO("Response timeout");
					return 99;
				}
			}
			else 
			{
				ME3616_INFO("Data length violation");
				return 0;
			}
		}
		else{
			
			ME3616_INFO("Send failed, TCP channel not open");
		return 0;
		}
		return 0;
}

uint8_t  ME3616_TCP_SEND_Hex(char *str)
{
		if(me3616.State.TCP_State==1)
		{
			uint16_t len=strlen(str);
			if(len%2!=0) 
			{
				ME3616_INFO("hex data不符合规范");
				return 0;
			}
			if(len>0&&len<512)
			{
				module_printf("AT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,len/2,str);
				//debug_printf("AT+ESOSEND=%d,%d,%s\r\n",me3616.State.TCP_Socket,len/2,str);
				char rxbuf[MODULE_RDA_MAXlen];
				if(Module_Blocking_Read(rxbuf,3000))
				{
					//debug_printf(rxbuf);
					if(strstr(rxbuf,"+ESONMI")||strstr(rxbuf,"OK"))
					{
						ME3616_INFO("发送成功");
					}
					else if(strstr(rxbuf,"ERROR"))
					{
						ME3616_INFO("发送失败");
						
					}
				}else 
				{
						ME3616_INFO("响应超时");
						return 99;
				}
			}
			else 
			{
				ME3616_INFO("数据长度违规");
				return 0;
			}
		}
		else{
			
				ME3616_INFO("\r\nTCP通道未打开\r\n");
		return 0;
		}
		return 0;
}

uint8_t ME3616_TCP_DATA_purification(uint8_t data[])
{
	/**/
	if(me3616.State.TCP_State)
	{
		char temp[15]={0};
		sprintf(temp,"+ESONMI=%d",me3616.State.TCP_Socket);
		if(strstr((char*)data,temp))/*校验数据是否来自指定的socket*/
		{
			/*读取数据长度*/
			char temp[10]={0};
			AT_GET_Data((char*)data,(uint8_t*)temp,",",1);
			int i=atoi(temp);
			//debug_printf("\r\nlen:%d\r\n",i);
			int loc=0;
			for(int n=0;loc<50;loc++)
			{
				if(*(data+loc)==',') n++;
				if(n==2) break;
			}
			Shift_left((char*)data,loc+1);
			//Str.convert.R_CUT((char*)data,i*2+2);/*因为数据还包括odoa，所以额外+2*/
			return 1;
		}
		else return 0;
	}
	return 0;
}
#endif

/**
* @brief  ME3616打印套接字错误码
*/
void  ESOERR_PRINT(int code)
{
	switch(code)
	{
		case -1:debug_printf("\r\n错误:通用错误\r\n"); break;
		case 1:debug_printf("\r\n错误:没有找到路由信息，一般是掉网的情况下会出现\r\n"); break;
		case 2:debug_printf("\r\n错误:TCP 链接被动断开，一般掉网的情况下会出现\r\n"); break;
		case 3:debug_printf("\r\n错误:TCP 链接被 server 断连，一般是 device 收到 server 的 reset 数据包\r\n"); break;
		case 4:debug_printf("\r\n错误:TCP 连接错误\r\n"); break;
		case 5:debug_printf("\r\n错误:非法值\r\n"); break;
		case 6:debug_printf("\r\n错误:socket 阻塞\r\n"); break;
		case 7:debug_printf("\r\n错误:地址已经被使用\r\n"); break;
		case 8:debug_printf("\r\n错误:正在连接中\r\n"); break;
		case 9:debug_printf("\r\n错误:已经建立连接\r\n"); break;
		case 10:debug_printf("\r\n错误:网络接口错误\r\n"); break;
		default: debug_printf("\r\n错误:通用错误\r\n"); break;
	}
}

/*--------------------------------MQTT------------------------------------------------------*/
#if(config_MQTT_Enable)


uint8_t MQTT_Set_Net(char *ip,char *port)
{
	if(strcpy(me3616.State.mqtt_ip,ip))
	if(strcpy(me3616.State.mqtt_port,port))
	{
		me3616.flug.mqtt_ip=1;
		me3616.flug.mqtt_port=1;
		ME3616_INFO("Net Set OK!");
		return 1;
	}
	return 0;
}

uint8_t MQTT_Connet(char *_productID,char *_deviceID,char *_secret)
{
	int mqttid;
	/*申请一个接收缓存*/
	rxbuff(buff);
	
	if(!(me3616.flug.mqtt_ip&&me3616.flug.mqtt_port))
	{
		ME3616_INFO("The network port has not been configured");
		return 0;
	}
	
	module_printf("AT+EMQNEW=\"%s\",\"%s\",12000,512\r\n",me3616.State.mqtt_ip,me3616.State.mqtt_port);
	/*conenet的地址*/
	//module_printf("AT+EMQNEW=\"183.230.40.39\",\"6002\",12000,100\r\n");
	clear(buff);
	if(Module_Blocking_Read(buff,5000))
	{
		if(strstr(buff,"+EMQNEW:")&&strstr(buff,"OK"))
		{
			uint8_t getid[5]={0};
			AT_GET_Data_2Param(buff,getid,":","OK");
			AT_Remove_spaces((char*)getid);
			mqttid=atoi((char*)getid);
			ME3616_INFO("NEW mqtt server ok! Start Connect...");
			
			module_printf("AT+EMQCON=%d,4,\"%s\",1000,1,0\r\n",mqttid,_deviceID);
			
			clear(buff);
			if(Module_Blocking_Read(buff,5000))
			{
				if(strstr(buff,"OK"))
				{
					me3616.State.mqtt_id=mqttid;
					me3616.State.MQTT_State=1;
					ME3616_INFO("Connect MQTT Successful,MQTT id:%d",mqttid);
					return 1;
				}	
			}
		}else {
			ME3616_ERROR("%s",buff);
		}
	} else {
		ME3616_INFO("Response timeout");
	}
	
	return 0;
}


uint8_t MQTT_SUB(char * topic)
{
	if(!me3616.State.MQTT_State)
	{
		ME3616_INFO("Cannot Connect MQTT");
		return 0;
	}
	/*往模组打印*/
	module_printf("AT+EMQSUB=%d,\"%s\",1\r\n",me3616.State.mqtt_id,topic);
	
	Module_Read_A_CRC("AT+EMQSUB=",5000);
	
	if(Module_Read_A_CRC("OK",15000))
	{
		ME3616_INFO("Sub \"%s\" Successful",topic);
		return 1;
	}else
	{
		ME3616_INFO("Sub ERROR");
		return 0;
	}
}


uint8_t MQTT_PUB(char * topic,char *data, uint32_t len)
{
	if(!me3616.State.MQTT_State)
	{
		ME3616_INFO("Cannot Connect MQTT");
		return 0;
	}
	/*往模组打印*/
	module_printf("AT+EMQPUB=%d,\"%s\",1,0,0,%d,\"%s\"\r\n",me3616.State.mqtt_id,topic,strlen(data)/2,data);
	
	//Module_Read_A_CRC("AT+EMQPUB=",5000);
	
	if(Module_Read_A_CRC("OK",3000))
	{
		/*
		if(Module_Read_A_CRC("+EMQPUB:",15000))
		{
			ME3616_INFO("Pub Successful \r\n[%s]<-[%s]",topic,data);
			return 1;
		}	*/
			ME3616_INFO("Pub Successful \r\n[%s]<-[%s]",topic,data);
			return 1;
	}else
	{
		ME3616_INFO("Pub ERROR");
		return 0;
	}

}

#endif
