/*************************** (C) COPYRIGHT 2017 CXHY ****************************
 * 文件名  ：gsm_gprs.c
 * 描  述  ：gsm_gprs驱动代码     
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2017/06/12 
*********************************************************************************/
#include "ec200x.h"
#include "gsm_uart.h"		
#include "gsm_uart_conf.h"
#include "delay.h"	
#include "led.h"   	  	 	 	 	  
#include "string.h" 
#include "stdio.h"
#include "stdlib.h"   

#include "timer.h"
#include "data_typedef.h"	
#include "message.h"
#include "tcp_protocol.h"
#include "at_proc.h"
#include "netwer_appcall.h"


#define RCC_PeriphClock 	RCC_APB2Periph_GPIOB
#define GSM_POW_KEY_Port 	GPIOB
#define GSM_POW_KEY_Pin 	GPIO_Pin_12

uint8_t GSM_isPowerON = 0x00;									//GSM模块是否处于开机标志
uint8_t ConnectionStatus = OFFLINE;						//连接状态（当有数据包发送成功后置位为在线状态）
uint8_t connectionClosedMark = 0;							//连接断开标志

uint16_t networkConnectionCount = 0;					//建立网络连接次数

static uint8_t GSM_GPRS_Status = 0x00;				//GSM_GPRS的工作状态
static uint8_t GSM_GPRS_initStatus = 0x00;		//GSM模块加载时的工状态

static uint8_t GSM_GPRS_workingState = 0x00;	//GSM模块TCP客户端的数据收发处理工作状态
static uint8_t errorStatus = 0x00;						//GSM模块异常错误处理状态
static uint8_t errorProcessCount = 0;					//错误处理次数
static uint8_t sendFailureCount = 0;					//发送失败计数
static uint8_t seriousError = 0;							//严重的错误

uint8_t lteLoadCompletedFlag = 0;							//LTE模块加载完成标志
uint8_t lteLoadResetFlag = 0;									//LTE模块加载过程复位

uint8_t lteCreateSocketOkFlag = 0;						//创建Socket连接完成标志
uint8_t lteCreateSocketResetFlag = 0;					//创建Socket连接过程复位标志

uint8_t lteHandlerResetFlag = 0;							//数据收发过程复位标志


/*
***********************************************************************
*	函 数 名: LTE_Init
*	功能说明: LTE模组初始化
*	形    参: 无
*	返 回 值: 无
***********************************************************************
*/
void LTE_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_PeriphClock, ENABLE);	 			//使能PB端口时钟
	
	//GSM开关机控制引脚初始化配置
 	GPIO_InitStructure.GPIO_Pin = GSM_POW_KEY_Pin;	 				//开机键端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 		//推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;				
 	GPIO_Init(GSM_POW_KEY_Port, &GPIO_InitStructure);				
	GPIO_ResetBits(GSM_POW_KEY_Port, GSM_POW_KEY_Pin);			//默认输出低，相当于开机键处于没有按下状态
	
	GSM_GPRS_Uart_Init();
	gsm_msg.Running = 0;
}

/*
***********************************************************************
*	函 数 名: LTE_StatusReset
*	功能说明: LTE模块各工作状态复位
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void LTE_StatusReset(void)
{
	lteLoadResetFlag = 1;
	lteCreateSocketResetFlag = 1;
	GSM_GPRS_Status = 0x00;
	errorStatus = 0x00;									//GSM模块异常处理时的状态复位
}
   
/*
***********************************************************************
*	函 数 名: GSM_PowerON
*	功能说明: GSM模块开机
*	形    参: 无
*	返 回 值: 开机完成输出1；正在开机输出0
***********************************************************************
*/
uint8_t GSM_PowerON(void)
{
	uint8_t returnData = 0;
	static timer pullDown_Time;
	static timer pullUp_Time;
	static uint8_t timer_ok = 0;
	
	static uint8_t powerOnStatus = 0x00;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&pullDown_Time, CLOCK_SECOND*3);  		//创建1个定时器，用于计算下拉为低电平时间
		timer_set(&pullUp_Time, CLOCK_SECOND*8);  			//创建1个定时器，用于计算上拉为高电平时间
	}
	switch(powerOnStatus)
	{
		case 0x00:			//最初进入状态
			printf("\r\nGSM模块正在开机\r\n");	
			GPIO_SetBits(GSM_POW_KEY_Port, GSM_POW_KEY_Pin);	
// 			GPIO_ResetBits(GSM_POW_KEY_Port, GSM_POW_KEY_Pin);
			
			timer_restart(&pullDown_Time);
			powerOnStatus = 0x01;
			break;
			
		case 0x01:			//大约等待2S钟的时间，power_key按键按下2S后松开启动模块		
			if(timer_expired(&pullDown_Time))
			{
// 				GPIO_SetBits(GSM_POW_KEY_Port, GSM_POW_KEY_Pin);
				GPIO_ResetBits(GSM_POW_KEY_Port, GSM_POW_KEY_Pin);

				timer_restart(&pullUp_Time);
				powerOnStatus = 0x02;
				break;
			}		
			break;
			
		case 0x02:
			if(timer_expired(&pullUp_Time))
			{
				returnData = 1;
				powerOnStatus = 0x00;
			}
			break;
			
		default:break;
	}
	return returnData;
}

/*
***********************************************************************
*	函 数 名: GSM_PowerOFF
*	功能说明: GSM模块关机
*	形    参: 无
*	返 回 值: 无
***********************************************************************
*/
uint8_t GSM_PowerOFF(void)
{
	uint8_t returnData = 0;
	
	return returnData;
}

/*
***********************************************************************
*	函 数 名: GSM_SignalCheck
*	功能说明: 查询信号质量
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void GSM_SignalCheck(void)
{
	uint8_t cnt = 0;
	GSM_SendAtCmd("AT+CSQ", AT_CMD_CSQ_NO);
	while((at_cmd_table[AT_CMD_CSQ_NO-1].result != AT_CMD_SUCCESS) && (cnt < 10))
	{
		delay_ms(1);
		cnt++;
	}
	
	if(at_cmd_table[AT_CMD_CSQ_NO-1].result == AT_CMD_SUCCESS)
	{
		if(signal > 0)
		{
			printf("\r\nGSM信号强度 = %d\r\n", signal);
			if(signal < 5)
			{
				printf("\r\nGSM信号弱，请检查天线连接是否正常\r\n");
			}
		}else{
			printf("\r\n无GSM信号！！！\r\n");
		}
	}
}

/*
***********************************************************************
*	函 数 名: GSM_GetHardInfo
*	功能说明: 取得GSM模块的硬件信息（IMEI）
*	形    参: msg：保存GSM模块信息结构体
*	返 回 值: 无
***********************************************************************
*/
void GSM_GetHardInfo(_gsm_msg *msg)
{
}

/*
***********************************************************************
*	函 数 名: GPRS_OnlineCheck
*	功能说明: GPRS与后台连接在线与否检查（发送心跳包来检测）
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
static void GPRS_OnlineCheck(void)
{
	sendMsg.msgType = 1001;														//心跳
	MessageSend(MSG_FIFO_PROTOCOL, sendMsg);
}

uint8_t startSyncNTP_Mark = 0;					//开启同步NTP服务器标志
uint8_t syncNTP_SuccessMark = 0;				//同步NTP服务器成功标志
typedef enum
{
	LTE_STA_NTP_INIT = 0,									//LTE模块NTP时间同步初始状态
	LTE_STA_NTP_QIACT,										//激活PDP场景
	LTE_STA_NTP_QIACT_ACK,								//激活PDP场景应答
	LTE_STA_NTP_QIDEACT,									//反激活PDP场景
	LTE_STA_NTP_QIDEACT_ACK,							//反激活PDP场景应答
	
	LTE_STA_QNTP,													//同步NTP时间服务器
	LTE_STA_QNTP_ACK,											//同步NTP时间服务器应答
	LTE_STA_GET_CLK,											//获取日期时间
	LTE_STA_GET_CLK_ACK,									//获取日期时间应答
	
	LTE_STA_NTP_OK,												//LTE模块加载完成状态
	LTE_STA_NTP_FAILURE,									//LTE模块加载失败状态
}_LTE_NTP_Status;
/*
***********************************************************************
*	函 数 名: EC200X_NTP_SyncHandler
*	功能说明: EC200X模块同步NTP时间服务器处理程序
*	形    参：无
*	返 回 值: 无（同步时间成功后全局变量syncNTP_SuccessMark = 1）
***********************************************************************
*/
void EC200X_NTP_SyncHandler(void)
{
	static _LTE_NTP_Status currentStatus = LTE_STA_NTP_INIT;
	static _LTE_NTP_Status nextStatus = LTE_STA_NTP_INIT;
	
	static uint8_t GSM_GPRS_initStatus = 0;
	static uint8_t waitTimeOutCount = 0;
	
	static timer responseTimeout;
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&responseTimeout, CLOCK_SECOND*10);  			//创建1个定时器，用于发送AT命令后等待应答的时间
	}
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{
		case LTE_STA_NTP_INIT:		//初始状态
			if(startSyncNTP_Mark == 1)
			{
				startSyncNTP_Mark = 0;
				syncNTP_SuccessMark = 0;
				printf("\r\n开始同步NTP服务器\r\n");
				nextStatus = LTE_STA_NTP_QIACT;
				break;
			}
			break;
			
		case LTE_STA_NTP_QIACT:		//激活PDP
			GSM_SendAtCmd("AT+QIACT=1", AT_CMD_QIACT_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_NTP_QIACT_ACK;
			break;
			
		case LTE_STA_NTP_QIACT_ACK:		//等待激活PDP应答
			if(at_cmd_table[AT_CMD_QIACT_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n激活PDP OK\r\n");
				nextStatus = LTE_STA_QNTP;
				break;
			}
			if(at_cmd_table[AT_CMD_QIACT_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\n激活PDP ERROR\r\n");
				nextStatus = LTE_STA_NTP_FAILURE;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答超时，激活PDP失败\r\n");
				nextStatus = LTE_STA_NTP_FAILURE;	
				break;
			}
			break;
			
		case LTE_STA_QNTP:		//同步NTP时间服务器
// 			printf("\r\n同步时间\r\n");
			GSM_SendAtCmd("AT+QNTP=1,\"202.112.10.36\",123", AT_CMD_QNTP_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_QNTP_ACK;
			break;
			
		case LTE_STA_QNTP_ACK:		//等待同步时间应答
			if(at_cmd_table[AT_CMD_QNTP_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n时间同步OK\r\n");
				nextStatus = LTE_STA_GET_CLK;
				break;
			}
			if(at_cmd_table[AT_CMD_QNTP_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\n时间同步 ERROR\r\n");
				nextStatus = LTE_STA_NTP_QIDEACT;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答超时，时间同步失败\r\n");
				nextStatus = LTE_STA_NTP_QIDEACT;	
				break;
			}
			break;
			
		case LTE_STA_GET_CLK:		//获取日期时间
			GSM_SendAtCmd("AT+CCLK?", AT_CMD_CCLK_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_GET_CLK_ACK;
			break;
			
		case LTE_STA_GET_CLK_ACK:		//等待获取日期时间应答
			if(at_cmd_table[AT_CMD_CCLK_NO-1].result == AT_CMD_SUCCESS)
			{
				GMT_To_Beijing(&GMT_Time);
				printf("\r\nTime:%s\r\n", systemTime);
				nextStatus = LTE_STA_NTP_QIDEACT;
				break;
			}
			if(at_cmd_table[AT_CMD_CCLK_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\nGet Time ERROR\r\n");
				nextStatus = LTE_STA_NTP_QIDEACT;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答超时，Get Time失败\r\n");
				nextStatus = LTE_STA_NTP_QIDEACT;	
				break;
			}
			break;
			
		case LTE_STA_NTP_QIDEACT:		//PDP去激活
			GSM_SendAtCmd("AT+QIDEACT=1", AT_CMD_QIDEACT_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_NTP_QIDEACT_ACK;
			break;
			
		case LTE_STA_NTP_QIDEACT_ACK:		//等待PDP去激活应答
			if(at_cmd_table[AT_CMD_QIDEACT_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\nPDP去激活 OK\r\n");
				nextStatus = LTE_STA_NTP_OK;
				break;
			}
			if(at_cmd_table[AT_CMD_QIDEACT_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\nPDP去激活 ERROR\r\n");
				nextStatus = LTE_STA_NTP_FAILURE;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答超时，PDP去激活失败\r\n");
				nextStatus = LTE_STA_NTP_FAILURE;	
				break;
			}
			break;
			
		case LTE_STA_NTP_OK:
			startSyncNTP_Mark = 0;
			syncNTP_SuccessMark = 1;
			printf("\r\n同步NTP服务器完成！\r\n");
			nextStatus = LTE_STA_NTP_INIT;
			break;
			
		case LTE_STA_NTP_FAILURE:
			startSyncNTP_Mark = 0;
			syncNTP_SuccessMark = 0;
			nextStatus = LTE_STA_NTP_INIT;
			break;
	}
}

typedef enum
{
	LTE_STA_LOADING_INIT = 0,						//LTE模块加载初始状态
	LTE_STA_AT_TEST,										//发送AT指令，检测LTE模块是否正常
	LTE_STA_AT_TEST_ACK,								//发送AT指令，检测LTE模块是否正常应答
	LTE_STA_AT_ECHO,										//设置AT指令回显模式
	LTE_STA_AT_ECHO_ACK,								//设置AT指令回显模式应答
	LTE_STA_CHECK_IMEI,									//查询IMEI号
	LTE_STA_CHECK_IMEI_ACK,							//查询IMEI号应答
	LTE_STA_CHECK_SIM,									//查询SIM卡状态
	LTE_STA_CHECK_SIM_ACK,							//查询SIM卡状态应答
	LTE_STA_CHECK_ICCID,								//查询SIM卡的ICCID卡号
	LTE_STA_CHECK_ICCID_ACK,						//查询SIM卡的ICCID卡号应答
	LTE_STA_CHECK_CSQ,									//查询信号强度
	LTE_STA_CHECK_CSQ_ACK,							//查询信号强度应答
	LTE_STA_CHECK_CREG,									//查询CS业务注册状态（是否注册网络）
	LTE_STA_CHECK_CREG_ACK,							//查询CS业务注册状态应答
	LTE_STA_CHECK_CGREG,								//查询PS业务注册状态（是否附着GPRS业务）
	LTE_STA_CHECK_CGREG_ACK,						//查询PS业务注册状态应答
	LTE_STA_QUERY_OPERATOR,							//查询网络运营商
	LTE_STA_QUERY_OPERATOR_ACK,					//查询网络运营商应答
	LTE_STA_SYNC_NTP,										//同步NTP时间服务器
	LTE_STA_SYNC_NTP_ACK,								//等待同步NTP时间服务器应答
	LTE_STA_LOADING_OK,									//LTE模块加载完成状态
	LTE_STA_LOADING_FAILURE,						//LTE模块加载失败状态
	LTE_STA_LOADING_IDLE,								//LTE模块进行空闲状态
}_LTE_LoadingStatus;
/*
***********************************************************************
*	函 数 名: EC200X_Loading
*	功能说明: EC200X模块加载（开机、查询模块的网络状态）
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void EC200X_Loading(void)
{
	static _LTE_LoadingStatus currentStatus = LTE_STA_LOADING_INIT;
	static _LTE_LoadingStatus nextStatus = LTE_STA_LOADING_INIT;
	
	static uint8_t GSM_GPRS_initStatus = 0;
	static uint8_t waitTimeOutCount = 0;
	
	static timer responseTimeout;
	static timer queryTime;
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&responseTimeout, CLOCK_SECOND*10);  			//创建1个定时器，用于发送AT命令后等待应答的时间
		timer_set(&queryTime, CLOCK_SECOND*2);  						//创建1个定时器，用于查询网络注册情况
	}
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{
		case LTE_STA_LOADING_INIT:		//初始状态
			if(GSM_PowerON())
			{
				lteLoadCompletedFlag = 0;
				
				signal = 0;
				gsm_msg.simCardStatus = 0;												//未知状态
				nextStatus = LTE_STA_AT_TEST;
				break;
			}
			break;
			
		case LTE_STA_AT_TEST:		//检测模块是否正常启动
			printf("\r\n检测模块\r\n");
			GSM_SendAtCmd("AT", AT_CMD_AT_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_AT_TEST_ACK;
			break;
			
		case LTE_STA_AT_TEST_ACK:		//等待模块应答“OK”		
			if(at_cmd_table[AT_CMD_AT_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n模块正常\r\n");
				nextStatus = LTE_STA_AT_ECHO;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n超时未见模块应答\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;		
				break;
			}
			break;
			
		case LTE_STA_AT_ECHO:		//关闭回显
			printf("\r\n关闭回显\r\n");
			GSM_SendAtCmd("ATE0", AT_CMD_ATE0_NO);
			timer_restart(&responseTimeout);							//从当前时间重新开启定时器
			nextStatus = LTE_STA_AT_ECHO_ACK;
			break;
			
		case LTE_STA_AT_ECHO_ACK:		//等待模块应答“OK”		
			if(at_cmd_table[AT_CMD_ATE0_NO-1].result == AT_CMD_SUCCESS)
			{
// 				printf("\r\n关闭回显OK\r\n");
				nextStatus = LTE_STA_CHECK_IMEI;									//接收到应答，跳转到0x
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n关闭回显超时未应答\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;		
				break;
			}
			break;
			
		case LTE_STA_CHECK_IMEI:		//获取模块IMEI号
			GSM_SendAtCmd("AT+CGSN", AT_CMD_CGSN_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_CHECK_IMEI_ACK;
			break;
			
		case LTE_STA_CHECK_IMEI_ACK:			//等待AT指令应答			
			if(at_cmd_table[AT_CMD_CGSN_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\nIMEI = %s\r\n", gsm_msg.IMEI);
				waitTimeOutCount = 0;
				
				gsm_msg.Running = 1;											//标志模块已经连接上GPRS
				nextStatus = 0xFF;
// 				nextStatus = LTE_STA_CHECK_SIM;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n获取硬件信息超时\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;		
				break;
			}
			break;
			
		case 0xFF:		//空闲等待
			break;
			
		case LTE_STA_CHECK_SIM:		//查询SIM卡状态
			if(waitTimeOutCount > 5)											//超时还未查询到网络注册状态
			{
				waitTimeOutCount = 0;
				gsm_msg.simCardStatus = 4;												//没有检测到SIM卡
				printf("\r\n查询SIM卡状态超时或SIM卡无效！！！\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;									//返回到初始状态
				break;
			}
			GSM_SendAtCmd("AT+CPIN?", AT_CMD_CPIN_NO);
			nextStatus = LTE_STA_CHECK_SIM_ACK;
			timer_restart(&queryTime);
			break;	
			
		case LTE_STA_CHECK_SIM_ACK:		//等待查询SIM卡AT指令应答
			if(at_cmd_table[AT_CMD_CPIN_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\nSIM卡已经就绪\r\n");
				printf("\r\n查询ICCID号\r\n");
				waitTimeOutCount = 0;	
				nextStatus = LTE_STA_CHECK_ICCID;
				break;
			}
			
			if(timer_expired(&queryTime))						//超时还未接收到应答
			{
				waitTimeOutCount++;										//等待超时计数+1
				nextStatus = LTE_STA_CHECK_SIM;	
				break;
			}
			break;
			
		case LTE_STA_CHECK_ICCID:		//查询SIM卡的ICCID卡号
			GSM_SendAtCmd("AT+QCCID", AT_CMD_ICCID_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_CHECK_ICCID_ACK;
			break;
			
		case LTE_STA_CHECK_ICCID_ACK:			//查询SIM卡的ICCID卡号应答
			if(at_cmd_table[AT_CMD_ICCID_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\nICCID = %s\r\n", gsm_msg.ICCID);
				nextStatus = LTE_STA_CHECK_CSQ;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n获取SIM卡的ICCID超时\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;		
				break;
			}
			break;
			
		case LTE_STA_CHECK_CSQ:		//查询网络信号强度
			if(waitTimeOutCount > 10)											//超时还未查询到网络注册状态
			{
				waitTimeOutCount = 0;
				gsm_msg.simCardStatus = 2;												//无法注册网络
				printf("\r\n查询不到网络信号！！！\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;
				break;
			}
			GSM_SendAtCmd("AT+CSQ", AT_CMD_CSQ_NO);
			timer_restart(&queryTime);							//从当前时间重新开启定时器
			nextStatus = LTE_STA_CHECK_CSQ_ACK;
			break;
			
		case LTE_STA_CHECK_CSQ_ACK:		//等待网络信号应答正常
			if(at_cmd_table[AT_CMD_CSQ_NO-1].result == AT_CMD_SUCCESS)
			{
				if((signal > 0) && (signal != 99))
				{
					printf("\r\n信号强度正常 = %d\r\n", signal);
					printf("\r\n查询网络注册状态\r\n");
					waitTimeOutCount = 0;											//等待超时计数归零
					nextStatus = LTE_STA_CHECK_CREG;
					break;
				}
			}
			
			if(timer_expired(&queryTime))						//超时还未接收到应答
			{
				waitTimeOutCount++;										//等待超时计数+1
				nextStatus = LTE_STA_CHECK_CSQ;	
				break;
			}
			break;
			
		case LTE_STA_CHECK_CREG:		//查询网络注册状态
			if(waitTimeOutCount > 20)											//超时还未查询到网络注册状态
			{
				waitTimeOutCount = 0;
				gsm_msg.simCardStatus = 2;												//无法注册网络
				printf("\r\n等待超时，尚未注册网络！！！\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;
				break;
			}

			GSM_SendAtCmd("AT+CREG?", AT_CMD_CREG_NO);
			timer_restart(&queryTime);							//从当前时间重新开启定时器
			nextStatus = LTE_STA_CHECK_CREG_ACK;
			break;
			
		case LTE_STA_CHECK_CREG_ACK:		//等待网络注册成功			
			if(at_cmd_table[AT_CMD_CREG_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n已经注册网络\r\n");
				printf("\r\n查询是否附着GPRS业务？\r\n");
				waitTimeOutCount = 0;											//等待超时计数归零
				nextStatus = LTE_STA_CHECK_CGREG;
				break;
			}
			
			if(timer_expired(&queryTime))						//超时还未接收到应答
			{
				waitTimeOutCount++;										//等待超时计数+1
				printf("\r\nCnt = %d\r\n", waitTimeOutCount);
				nextStatus = LTE_STA_CHECK_CREG;	
				break;
			}
			break;
			
		case LTE_STA_CHECK_CGREG:		//检查GPRS附着状态
			if(waitTimeOutCount > 10)											//超时还未查询到GPRS附着状态
			{
				waitTimeOutCount = 0;
				gsm_msg.simCardStatus = 3;									//SIM卡没有GPRS业务
				printf("\r\n等待超时，尚未附着GPRS\r\n");
				nextStatus = LTE_STA_LOADING_FAILURE;
				break;
			}
			GSM_SendAtCmd("AT+CGREG?", AT_CMD_CGREG_NO);	//检查GPRS附着状态						
			timer_restart(&queryTime);										//从当前时间重新开启定时器
			nextStatus = LTE_STA_CHECK_CGREG_ACK;
			break;
			
		case LTE_STA_CHECK_CGREG_ACK:		//等待附着GPRS业务		
			if(at_cmd_table[AT_CMD_CGREG_NO-1].result == AT_CMD_SUCCESS)
			{
				gsm_msg.simCardStatus = 1;									//SIM卡正常
				printf("\r\n已经附着GPRS业务\r\n");
				
				nextStatus = LTE_STA_QUERY_OPERATOR;	
				break;
			}
			
			if(timer_expired(&queryTime))									//超时还未接收到应答
			{
				waitTimeOutCount++;													//等待超时计数+1
				printf("\r\nCnt = %d\r\n", waitTimeOutCount);
				nextStatus = LTE_STA_CHECK_CGREG;	
				break;
			}
			break;
			
		case LTE_STA_QUERY_OPERATOR:		//查询网络运营商
			GSM_SendAtCmd("AT+COPS?", AT_CMD_COPS_NO);		//查询运营商
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_QUERY_OPERATOR_ACK;
			break;
			
		case LTE_STA_QUERY_OPERATOR_ACK:		//查询网络运营商应答
			if(at_cmd_table[AT_CMD_COPS_NO-1].result == AT_CMD_SUCCESS)
			{
				if(gsm_msg.OperatorType == 1)
				{
					printf("\r\n中国移动\r\n");
				}else if(gsm_msg.OperatorType == 2){
					printf("\r\n中国联通\r\n");
				}else{}
				
				nextStatus = LTE_STA_SYNC_NTP;
// 				nextStatus = LTE_STA_LOADING_OK;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答超时！\r\n");
				nextStatus = LTE_STA_SYNC_NTP;
// 				nextStatus = LTE_STA_LOADING_OK;				
				break;
			}
			break;
			
		case LTE_STA_SYNC_NTP:		//开启同步NTP服务器
			startSyncNTP_Mark = 1;
			syncNTP_SuccessMark = 0;
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_SYNC_NTP_ACK;
			break;
			
		case LTE_STA_SYNC_NTP_ACK:		//等待NTP同步本地时间完成
			EC200X_NTP_SyncHandler();
			if(syncNTP_SuccessMark == 1)
			{
				syncNTP_SuccessMark = 0;
				nextStatus = LTE_STA_LOADING_OK;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\nNTP 同步超时！\r\n");
				nextStatus = LTE_STA_LOADING_OK;				
				break;
			}
			break;
			
		case LTE_STA_LOADING_OK:		//LTE模块启动加载成功
			waitTimeOutCount = 0;												//等待超时计数归零
			lteLoadCompletedFlag = 1;										//标志LTE模块已经启动加载完成
			nextStatus = LTE_STA_LOADING_IDLE;	
			break;
			
		case LTE_STA_LOADING_FAILURE:		//LTE模块加载失败
			printf("\r\n模块加载失败！\r\n");
			nextStatus = LTE_STA_LOADING_INIT;
			break;
			
		case LTE_STA_LOADING_IDLE:			//空闲状态
			if(lteLoadResetFlag == 1)
			{
				lteLoadResetFlag = 0;
				lteLoadCompletedFlag = 0;
				printf("\r\n模块加载过程复位！\r\n");
				nextStatus = LTE_STA_LOADING_INIT;
				break;
			}
			break;
			
		default: 
			nextStatus = LTE_STA_LOADING_FAILURE;
			break;
	}
	
	//加载过程需要复位
	if(lteLoadResetFlag == 1)
	{
		lteLoadResetFlag = 0;
		lteLoadCompletedFlag = 0;
		printf("\r\n模块加载过程复位！\r\n");
		nextStatus = LTE_STA_LOADING_INIT;
	}
}

typedef enum
{
	LTE_STA_TCP_CREATE_INIT = 0,				//初始状态
	LTE_STA_SET_PDP_CONTEXT,						//配置TCP/IP场景参数
	LTE_STA_SET_PDP_CONTEXT_ACK,				//配置TCP/IP场景参数应答
	LTE_STA_QIACT,											//激活PDP场景
	LTE_STA_QIACT_ACK,									//激活PDP场景应答
	LTE_STA_QIDEACT,										//反激活PDP场景
	LTE_STA_QIDEACT_ACK,								//反激活PDP场景应答
	LTE_STA_CHECK_QIACT,								//查询PDP场景状态
	LTE_STA_CHECK_QIACT_ACK,						//查询PDP场景状态应答
	LTE_STA_OPEN_SOCKET,								//打开Socket服务
	LTE_STA_OPEN_SOCKET_ACK,						//打开Socket服务应答
// 	LTE_STA_CLOSE_SOCKET,								//关闭Socket服务
// 	LTE_STA_CLOSE_SOCKET_ACK,						//关闭Socket服务应答
	LTE_STA_CREATE_OK,									//Socket创建连接完成
	LTE_STA_CREATE_FAILURE,							//Socket创建连接失败
	LTE_STA_CREATE_IDLE,								//Socket创建连接过程空闲状态
}_LTE_TCP_CreateStatus;
/*
***********************************************************************
*	函 数 名: TCP_ClientCreate
*	功能说明: 建立TCP客户端
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void TCP_ClientCreate(void)
{
	static _LTE_TCP_CreateStatus currentStatus = LTE_STA_TCP_CREATE_INIT;
	static _LTE_TCP_CreateStatus nextStatus = LTE_STA_TCP_CREATE_INIT;
	
	static timer responseTimeout;
	static timer responseTimeout_3s;
	static timer registrationTime;
	static timer connectionWaitTime;
	static timer waitingTime_2s;
	static timer reconnectTimeout;
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&responseTimeout, CLOCK_SECOND*3);  		//创建1个定时器，用于发送AT命令后等待应答的时间
		timer_set(&responseTimeout_3s, CLOCK_SECOND*3);  	//创建1个定时器，用于发送AT命令后等待应答的时间
		timer_set(&connectionWaitTime, CLOCK_SECOND*10);  //创建1个定时器，用于建立连接等待的超时时间
		timer_set(&registrationTime, CLOCK_SECOND*10);  	//创建1个定时器，用于检查网络注册情况的等待超时时间
		timer_set(&waitingTime_2s, CLOCK_SECOND*2);
		timer_set(&reconnectTimeout, CLOCK_SECOND*20);
	}
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{	
		case LTE_STA_TCP_CREATE_INIT:			//开始建立TCP连接
			if(lteLoadCompletedFlag == 1)
			{
				printf("\r\n准备创建TCP/IP Socket!\r\n");
				nextStatus = LTE_STA_SET_PDP_CONTEXT;
				break;
			}
			break;
			
		case LTE_STA_SET_PDP_CONTEXT:
			printf("\r\n开始任务，设置APN\r\n");
			if(gsm_msg.OperatorType == 1)
			{
				GSM_SendAtCmd("AT+QICSGP=1,1,\"CMNET\","","",1", AT_CMD_QICSGP_NO);			//设置APN，中国移动
			}else if(gsm_msg.OperatorType == 2){
				GSM_SendAtCmd("AT+QICSGP=1,1,\"UNINET\","","",1", AT_CMD_QICSGP_NO);			//设置APN，中国联通
			}else{
				GSM_SendAtCmd("AT+QICSGP=1,1,\"CMNET\","","",1", AT_CMD_QICSGP_NO);			//设置APN，中国移动
			}	
			timer_restart(&responseTimeout);							//从当前时间重新开启2秒定时器
			timer_restart(&reconnectTimeout);							//开始建立链接先初始化定时器，如果超时了，则需要重新开机
			nextStatus = LTE_STA_SET_PDP_CONTEXT_ACK;
			break;
			
		case LTE_STA_SET_PDP_CONTEXT_ACK:			//等待应答		
			if(at_cmd_table[AT_CMD_QICSGP_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n设置APN OK\r\n");
				nextStatus = LTE_STA_QIDEACT;
				break;
			}
			if(at_cmd_table[AT_CMD_QICSGP_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\n设置APN ERROR\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n等待应答超时，设置APN错误\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;	
				break;
			}
			break;
			
		case LTE_STA_QIDEACT:
			printf("\r\n反激活\r\n");
			GSM_SendAtCmd("AT+QIDEACT=1", AT_CMD_QIDEACT_NO);		//设置PDP上下文,互联网接协议,接入点等信息
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_QIDEACT_ACK;
			break;
			
		case LTE_STA_QIDEACT_ACK:
			if(at_cmd_table[AT_CMD_QIDEACT_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n反激活OK\r\n");
				nextStatus = LTE_STA_QIACT;
				break;
			}
			if(at_cmd_table[AT_CMD_QIACT_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\n建立无线链路 ERROR\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答OK超时，建立无线链路失败\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;	
				break;
			}
			break;

		case LTE_STA_QIACT:			//激活PDP场景
			printf("\r\n建立无线链路\r\n");
			GSM_SendAtCmd("AT+QIACT=1", AT_CMD_QIACT_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_QIACT_ACK;
			break;
			
		case LTE_STA_QIACT_ACK:			//等待应答				
			if(at_cmd_table[AT_CMD_QIACT_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n建立无线链路OK\r\n");
				nextStatus = LTE_STA_CHECK_QIACT;
				break;
			}
			if(at_cmd_table[AT_CMD_QIACT_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\n建立无线链路 ERROR\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答OK超时，建立无线链路失败\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;	
				break;
			}
			break;
			
		case LTE_STA_CHECK_QIACT:
			printf("\r\n获得本地IP\r\n");
			GSM_SendAtCmd("AT+QIACT?", AT_CMD_CHECK_QIACT_NO);
			nextStatus = LTE_STA_CHECK_QIACT_ACK;
			timer_restart(&responseTimeout);
			break;
			
		case LTE_STA_CHECK_QIACT_ACK:
			if(at_cmd_table[AT_CMD_CHECK_QIACT_NO-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n已获得IP地址\r\n");
				nextStatus = LTE_STA_OPEN_SOCKET;
				break;
			}
			if(at_cmd_table[AT_CMD_CHECK_QIACT_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\n获得本地IP失败 ERROR\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答OK超时，获得本地IP失败\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;	
				break;
			}
			break;
		
		case LTE_STA_OPEN_SOCKET:			//开始链接远端服务器		
			printf("\r\n开始链接远端服务器\r\n");
			GSM_SendAtCmd(TCP_IP_COM, AT_CMD_QIOPEN);
			nextStatus = LTE_STA_OPEN_SOCKET_ACK;
			timer_restart(&connectionWaitTime);
			break;	
			
		case LTE_STA_OPEN_SOCKET_ACK:			//等待应答“CONNECT OK”								
			if(at_cmd_table[AT_CMD_QIOPEN-1].result == AT_CMD_SUCCESS)
			{
				printf("\r\n连接成功\r\n");
				nextStatus = LTE_STA_CREATE_OK;		
				break;
			}
			
			if(at_cmd_table[AT_CMD_QIOPEN-1].result == AT_CMD_FAILED)
			{
				printf("\r\n连接失败\r\n");
				nextStatus = LTE_STA_CREATE_FAILURE;
				break;
			}
			
			if(timer_expired(&connectionWaitTime))				//超时还未接收到应答
			{
				printf("\r\n连接超时!!!\r\n");		
				nextStatus = LTE_STA_CREATE_FAILURE;
				break;
			}
			break;
			
		case LTE_STA_CREATE_OK:		//创建Socket完成
			ConnectionStatus = ONLINE;
			lteCreateSocketOkFlag = 1;
			
			networkConnectionCount++;									//网络建立成功后网络连接次数+1
			if(networkConnectionCount >= 0xFFFF)
			{
				networkConnectionCount = 2;
			}
			printf("\r\nnetworkConnectionCount = %d\r\n", networkConnectionCount);
			
			//清除发送失败计数和重连接错误计数（为了防止在程序运行过程中出现错误处理而重新启动模块复位变量）
			sendFailureCount = 0;
			errorProcessCount = 0;
										
			gsm_msg.Running = 1;											//标志模块已经连接上GPRS
			
			nextStatus = LTE_STA_CREATE_IDLE;
			break;
			
		case LTE_STA_CREATE_FAILURE:		//创建Socket失败
			printf("\r\n创建Socket失败！\r\n");
			errorProcessCount++;
			printf("\r\n创建Socket失败次数 = %d\r\n", errorProcessCount);
			nextStatus = LTE_STA_TCP_CREATE_INIT;
			break;
			
		case LTE_STA_CREATE_IDLE:		//创建Socket完成后进入空闲状态
			if(lteCreateSocketResetFlag == 1)
			{
				lteCreateSocketResetFlag = 0;
				printf("\r\n创建Socket过程复位！\r\n");
				
				ConnectionStatus = OFFLINE;
				lteCreateSocketOkFlag = 0;
				gsm_msg.Running = 0;
				
				//清除发送失败计数和重连接错误计数
				sendFailureCount = 0;
				errorProcessCount = 0;
											
				nextStatus = LTE_STA_TCP_CREATE_INIT;
				break;
			}
			break;

		default: 		//其它状态
			printf("\r\n未知状态，重启模块！！！\r\n");
			LTE_StatusReset();							//GSM模块复位，重启
			break;	
	}
	
	if(lteCreateSocketResetFlag == 1)
	{
		lteCreateSocketResetFlag = 0;
		printf("\r\n创建Socket过程复位！\r\n");
		
		ConnectionStatus = OFFLINE;
		lteCreateSocketOkFlag = 0;
		gsm_msg.Running = 0;
		
		//清除发送失败计数和重连接错误计数
		sendFailureCount = 0;
		errorProcessCount = 0;
									
		nextStatus = LTE_STA_TCP_CREATE_INIT;
	}
}

typedef enum
{
	LTE_STA_Handler_INIT = 0,						//初始状态
	LTE_STA_SEND_DATA,									//TCP发送数据
	LTE_STA_LOAD_DATA_READY,						//等待模块应答">"，准备加载数据
	LTE_STA_LOAD_DATA,									//加载要发送的数据
	LTE_STA_SEND_DATA_ACK,							//TCP发送数据应答
	LTE_STA_WAITING_SEND_TIME,					//等待发送时间
	LTE_STA_CHECK_SEND_DATA,						//检测TCP发送数据是否已经到达服务器
	LTE_STA_CHECK_SEND_DATA_ACK,				//检测TCP发送数据是否已经到达服务器应答
	LTE_STA_REPEAT_CHECK_SEND_DATA,			//重新检测TCP发送数据是否已经到达服务器
	LTE_STA_CLOSE_SOCKET,								//关闭Socket服务
	LTE_STA_CLOSE_SOCKET_ACK,						//关闭Socket服务应答
	LTE_STA_WQITING_RECEIVE_DATA,				//等待服务器回复数据
	LTE_STA_READ_DATA,									//TCP读取接收到的数据
	LTE_STA_READ_DATA_ACK,							//TCP读取接收到的数据应答
	LTE_STA_SEND_DATA_OK,								//发送成功
	LTE_STA_HANDLER_FAILURE,						//发送失败
	LTE_STA_HANDLER_RESTART,						//数据发送任务复位
	LTE_STA_GET_SIGNAL,									//获取信号
	LTE_STA_GET_SIGNAL_ACK,							//获取信号应答
	LTE_STA_GET_DATE_TIME,							//获取日期时间
	LTE_STA_GET_DATE_TIME_ACK,					//获取日期时间应答
}_LTE_TCP_HandlerStatus;
/*
***********************************************************************
*	函 数 名: TCP_ClientHandler
*	功能说明: TCP客户端的数据收发处理
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void TCP_ClientHandler(void)
{
	static _LTE_TCP_HandlerStatus currentStatus = LTE_STA_Handler_INIT;
	static _LTE_TCP_HandlerStatus nextStatus = LTE_STA_Handler_INIT;

	char atCmdBuf[32];															//AT指令缓存
	static uint8_t waitTimeOutCount = 0;
	
	static timer getSignalTime;														//获取信号间隔时间
	static timer getDateTime;															//获取日期时间间隔时间
	static timer responseTimeout;													//应答超时时间间隔
	static timer sendTimeout;															//发送超时时间间隔
	static timer checkSendAckTimer;
	static timer receiveTimer;
	static timer waitingTimer;
	
	static uint8_t timer_ok = 0;
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&getSignalTime, CLOCK_SECOND*60);  		
		timer_set(&getDateTime, CLOCK_SECOND*60); 		
		timer_set(&responseTimeout, CLOCK_SECOND*3);
		timer_set(&sendTimeout, CLOCK_SECOND*10);
		timer_set(&receiveTimer, CLOCK_SECOND*20);
		timer_set(&checkSendAckTimer, CLOCK_SECOND*5);
		timer_set(&waitingTimer, CLOCK_SECOND*1);
	}
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{			
		case LTE_STA_Handler_INIT:				//当前处于连接正常，检查是否有数据要发送，有就对数据进行发送
			if((isSendDataMark == 1) && (ConnectionStatus == ONLINE))
			{
				isSendDataMark = 0;
				isReceiveDataMark = 0;
				nextStatus = LTE_STA_SEND_DATA;
				break;
			}
			
			if(ConnectionStatus == ONLINE)
			{
				//获取日期时间
				if(timer_expired(&getDateTime))
				{
// 					printf("\r\n获取日期时间！\r\n");
					timer_restart(&getDateTime);
					nextStatus = LTE_STA_GET_DATE_TIME;
					break;
				}
				
				//获取信号强度
				if(timer_expired(&getSignalTime))
				{
					timer_restart(&getSignalTime);
					nextStatus = LTE_STA_GET_SIGNAL;
					break;
				}
			}
			break;
			
		case LTE_STA_SEND_DATA:			//发送数据
			sprintf(atCmdBuf, "AT+QISEND=0,%d", sendDataLen);
// 			printf("\r\n%s\r\n", atCmdBuf);
			
			GSM_SendAtCmd(atCmdBuf, AT_CMD_QISEND);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_LOAD_DATA_READY;
			break;
			
		case LTE_STA_LOAD_DATA_READY:				//等待返回应答“>”	
			if(at_cmd_table[AT_CMD_QISEND-1].result == AT_CMD_CIPSEND_READY)
			{
				printf("\r\n应答 > OK\r\n");
				nextStatus = LTE_STA_LOAD_DATA;							//接收到应答					
				break;
			}
			
			if(at_cmd_table[AT_CMD_QISEND-1].result == AT_CMD_SEND_FAIL)
			{
				printf("\r\n应答> ERROR\r\n");
				seriousError = 1;
// 				errorProcessCount ++;											//发送失败+1
				printf("\r\n发送ERROR次数 = %d\r\n", errorProcessCount);
				
				nextStatus = LTE_STA_HANDLER_FAILURE;
				break;
			}
			
			if(at_cmd_table[AT_CMD_QISEND-1].result == TCP_STATUS_CLOSED)
			{
				printf("\r\n连接已经关闭，发送失败\r\n");
				seriousError = 1;
// 				errorProcessCount ++;											//发送失败+1
				printf("\r\n发送ERROR次数 = %d\r\n", errorProcessCount);
				
				nextStatus = LTE_STA_HANDLER_FAILURE;				
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n超时未应答>取消发送\r\n");	
				errorProcessCount ++;												//发送失败+1
				printf("\r\n发送ERROR次数 = %d\r\n", errorProcessCount);
				
				nextStatus = LTE_STA_HANDLER_FAILURE;
				break;
			}
			break;
			
		case LTE_STA_LOAD_DATA:				//通过串口向模块发送要发送的数据
			receiveDataMark = 0;
			memcpy(GPRS_TX_BUF, GPRS_DATA_BUF, sendDataLen);
			GSM_GPRS_SendOne(GPRS_TX_BUF, sendDataLen);
			printf("\r\n正在发送数据......\r\n");
// 			printf("\r\nStartTime = %d\r\n", time_value);
			
			timer_restart(&sendTimeout);
			nextStatus = LTE_STA_SEND_DATA_ACK;
			break;
			
		case LTE_STA_SEND_DATA_ACK:				//等待返回应答“SEND OK”		
			if(at_cmd_table[AT_CMD_QISEND-1].result == AT_CMD_CIPSEND_OK)
			{
// 				printf("\r\nEndTime = %d\r\n", time_value);
				printf("\r\n发送加载成功！\r\n");
				
				timer_restart(&waitingTimer);
				nextStatus = LTE_STA_WAITING_SEND_TIME;
				break;
			}
			
			if(at_cmd_table[AT_CMD_QISEND-1].result == AT_CMD_SEND_FAIL)
			{
				printf("\r\nEndTime = %d\r\n", time_value);
				printf("\r\n发送加载失败\r\n");
				
				sendFailureCount ++;											//发送失败+1
				printf("\r\n发送失败次数 = %d\r\n", sendFailureCount);
				
				nextStatus = LTE_STA_HANDLER_FAILURE;							
				break;
			}
			
			if(timer_expired(&sendTimeout))							//超时还未接收到应答
			{
				printf("\r\nEndTime = %d\r\n", time_value);
				printf("\r\n超时数据尚未发出，发送失败\r\n");
				
				sendFailureCount ++;											//发送失败+1
				printf("\r\n发送失败次数 = %d\r\n", sendFailureCount);
				
				nextStatus = LTE_STA_HANDLER_FAILURE;
				break;
			}
			break;
			
		case LTE_STA_WAITING_SEND_TIME:		//等待一小段时间再查询数据是否已经成功发送给对方
			//如果收到后台的应答数据，则转到读取内容
			if(receiveDataMark == 1)
			{
				receiveDataMark = 0;
	
				printf("\r\n收到server数据！\r\n");
				nextStatus = LTE_STA_SEND_DATA_OK;
				break;
			}
			
			if(timer_expired(&waitingTimer))							//超时还未接收到应答
			{
				waitTimeOutCount = 0;
				nextStatus = LTE_STA_CHECK_SEND_DATA;
				break;
			}
			break;
			
		case LTE_STA_CHECK_SEND_DATA:		//查询数据是否已发送到对方
			printf("\r\n查询数据是否已发送成功？\r\n");
			
			if(waitTimeOutCount > 6)
			{
				printf("\r\n超出发送时间数据尚未能发出！\r\n");
				sendFailureCount ++;											//发送失败+1
				printf("\r\n发送失败次数 = %d\r\n", sendFailureCount);
				
				nextStatus = LTE_STA_HANDLER_FAILURE;
				break;
			}
			
			total_send_length = 0;
			ackedBytes = 0;
			GSM_SendAtCmd("AT+QISEND=0,0", AT_CMD_CHECK_QISEND_NO);
			timer_restart(&checkSendAckTimer);
			nextStatus = LTE_STA_CHECK_SEND_DATA_ACK;
			break;
			
		case LTE_STA_CHECK_SEND_DATA_ACK:
			if(at_cmd_table[AT_CMD_CHECK_QISEND_NO-1].result == AT_CMD_SUCCESS)
			{
				at_cmd_table[AT_CMD_CHECK_QISEND_NO-1].result = AT_CMD_UNKNOWN;
				printf("\r\nBytes: tx = %d, ack = %d\r\n", total_send_length, ackedBytes);
				
				if(total_send_length == ackedBytes)
				{
					printf("\r\n数据已成功发送到对方！\r\n");
					timer_restart(&receiveTimer);
					nextStatus = LTE_STA_WQITING_RECEIVE_DATA;
					break;
				}
			}
			
			//如果收到后台的应答数据，则转到读取内容
			if(receiveDataMark == 1)
			{
				receiveDataMark = 0;
				
				printf("\r\n收到server数据！\r\n");
				nextStatus = LTE_STA_SEND_DATA_OK;
				break;
			}
			
			if(timer_expired(&checkSendAckTimer))						//超时还未接收到应答
			{
				printf("\r\n查询数据发送超时！\r\n");	
				waitTimeOutCount++;
				
				nextStatus = LTE_STA_CHECK_SEND_DATA;								//返回到连接成功状态
				break;
			}
			break;
			
		case LTE_STA_WQITING_RECEIVE_DATA:		//等待服务器回复数据
			if(receiveDataMark == 1)
			{
				receiveDataMark = 0;
				
				printf("\r\n收到server数据！\r\n");
				nextStatus = LTE_STA_SEND_DATA_OK;
				break;
			}
			
			if(timer_expired(&receiveTimer))
			{
				dataSendOkButNoAckMark = 1;
				printf("\r\n数据已经发送，但没有收到回复！\r\n");
				sendFailureCount ++;											//发送失败+1
				printf("\r\n发送失败次数 = %d\r\n", sendFailureCount);
				nextStatus = LTE_STA_Handler_INIT;
				break;
			}
			break;
			
		case LTE_STA_SEND_DATA_OK:		//数据发送成功
			isReceiveDataMark = 1;									//标志接收到数据
			errorProcessCount = 0;
			sendFailureCount = 0;
			
			nextStatus = LTE_STA_Handler_INIT;
			break;
			
		case LTE_STA_GET_SIGNAL:		//查询网络信号强度
			GSM_SendAtCmd("AT+CSQ", AT_CMD_CSQ_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_GET_SIGNAL_ACK;
			break;
			
		case LTE_STA_GET_SIGNAL_ACK:		//等待网络信号应答正常
			if(at_cmd_table[AT_CMD_CSQ_NO-1].result == AT_CMD_SUCCESS)
			{
				if((signal > 0) && (signal != 99))
				{
					printf("\r\n信号强度 = %d\r\n", signal);
					nextStatus = LTE_STA_Handler_INIT;
					break;
				}
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				nextStatus = LTE_STA_Handler_INIT;	
				break;
			}
			break;
			
		case LTE_STA_GET_DATE_TIME:		//获取日期时间
			GSM_SendAtCmd("AT+CCLK?", AT_CMD_CCLK_NO);
			timer_restart(&responseTimeout);
			nextStatus = LTE_STA_GET_DATE_TIME_ACK;
			break;
			
		case LTE_STA_GET_DATE_TIME_ACK:		//获取日期时间应答
			if(at_cmd_table[AT_CMD_CCLK_NO-1].result == AT_CMD_SUCCESS)
			{
				getDateTimeMark = 1;
				GMT_To_Beijing(&GMT_Time);
				printf("\r\nTime:%s\r\n", systemTime);
				nextStatus = LTE_STA_Handler_INIT;
				break;
			}
			if(at_cmd_table[AT_CMD_CCLK_NO-1].result == AT_CMD_FAILED)
			{
				printf("\r\nGet Time ERROR\r\n");
				nextStatus = LTE_STA_Handler_INIT;
				break;
			}
			
			if(timer_expired(&responseTimeout))						//超时还未接收到应答
			{
				printf("\r\n应答超时，Get Time失败\r\n");
				nextStatus = LTE_STA_Handler_INIT;	
				break;
			}
			break;
			
		case LTE_STA_HANDLER_FAILURE:		//数据发送失败
			printf("\r\n数据发送失败返回！\r\n");
			
			dataSendFailureMark = 1;											//标志数据发送失败
			
			nextStatus = LTE_STA_Handler_INIT;
			break;
			
		default:		//未知状态
			printf("\r\nException_未知状态，重启模块！！！\r\n");
			nextStatus = LTE_STA_Handler_INIT;
			break;		
	}
	
	if(lteHandlerResetFlag == 1)
	{
		lteHandlerResetFlag = 0;
		
		printf("\r\n数据收发过程复位！\r\n");
			
		dataSendFailureMark = 1;											//标志数据发送失败
		
		nextStatus = LTE_STA_Handler_INIT;
	}
}

/*
***********************************************************************
*	函 数 名: LTE_WorkingStatusReset
*	功能说明: LTE通信模块工作状态复位
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
static void LTE_WorkingStatusReset(void)
{
	//模块工作过程复位
	lteLoadResetFlag = 1;											//标志模块加载过程要重新复位
	lteCreateSocketResetFlag = 1;							//标志Socket创建过程要重新复位
	lteLoadCompletedFlag = 0;									//模块加载完成标志清零
	lteCreateSocketOkFlag = 0;								//模块创建Socket完成标志清零
	lteHandlerResetFlag = 1;									//标志数据收发过程复位
	
	//模块运行状态标志复位
	ConnectionStatus = OFFLINE;
	gsm_msg.Running = 0;
	
	//过程变量清零
	seriousError = 0;
	sendFailureCount = 0;
	errorProcessCount = 0;
	connectionClosedMark = 0;
}

typedef enum
{
	LTE_ER_STA_INIT = 0,									//LTE模块异常处理初始状态
	LTE_ER_STA_HANDLER,										//LTE模块异常处理状态
	LTE_ER_STA_IDLE,											//LTE模块异常处理空闲状态
}_LTE_ErrorStatus;
/*
***********************************************************************
*	函 数 名: LTE_ErrorHandler
*	功能说明: LTE通信模块异常处理任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void LTE_ErrorHandler(void)
{
	static _LTE_ErrorStatus currentStatus = LTE_ER_STA_INIT;
	static _LTE_ErrorStatus nextStatus = LTE_ER_STA_INIT;
	
	static timer responseTimeout;													//应答超时时间间隔
	static timer sendTimeout;															//发送超时时间间隔
	static timer waitingTimer;
	
	static uint8_t timer_ok = 0;
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&responseTimeout, CLOCK_SECOND*3);
		timer_set(&sendTimeout, CLOCK_SECOND*10);
		timer_set(&waitingTimer, CLOCK_SECOND*1);
	}
	
	if(seriousError == 1)
	{
		seriousError = 0;
		printf("\r\n出现严重错误-->重启！\r\n");
		LTE_WorkingStatusReset();
	}
	
	if(sendFailureCount >= 3)										//发送失败超出3次，则重启通讯模块
	{
		sendFailureCount = 0;
		printf("\r\n发送失败次数超出预设值-->重启！\r\n");
		LTE_WorkingStatusReset();
	}
	
	if(errorProcessCount >= 3)									//发送失败超出3次，则重启通讯模块
	{
		errorProcessCount = 0;
		printf("\r\n运行过程ERROR次数超出预设值-->重启！\r\n");
		LTE_WorkingStatusReset();
	}

	if(connectionClosedMark == 1)								//连接已断开
	{
		connectionClosedMark = 0;
		printf("\r\n连接已断开！\r\n");
		LTE_WorkingStatusReset();
	}
}

/*
***********************************************************************
*	函 数 名: GSM_GPRS_Task
*	功能说明: GSM_GPRS通讯任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void GSM_GPRS_Task(void)
{
	EC200X_Loading();
	TCP_ClientCreate();
	TCP_ClientHandler();
	LTE_ErrorHandler();
}

/******************** (C) COPYRIGHT 2017 CXHY *****END OF FILE*******************/
