/************************************************************************************
 * @Copyright (c)    :(C)2017, Qindao ieslab Co., Ltd
 * @FileName   	     :pic24_nb_driver.c
 * @Author           :QDIES PLATFORM TEAM
 * @Version          :V1.0
 * @Date             :2017-03-01
 * @Description     :
 ************************************************************************************/
#include "sys_config.h"
#ifdef NB_MODULE_MN316
#ifdef	__cplusplus
extern "C"
{
#endif
 
#include "nb_uart_driver_mn316.h"
#include "nb_driver_mn316.h"
#include "stdio.h"
#include <time.h>
#include "UWater_timer1uS_driver.h"
#include "UWater_uart_driver.h"
#include "UWater_Rtcc_Driver.h"
#include "UWater_frame_app.h"
#include "nb_upload_monitor.h"

/********************************变量定义************************************/
//模组信息、网络配置、连接状态相关参数
NBIOT_PARA Nbiot_Para;
//模组数据发送指针
NBIOT_SEND_DATA Nbiot_Send_Data;
//AT指令拼接缓存
static char stringbuffer_temp[UP_BUF_SIZE*2];
//AT指令发送缓存
static char AT_BUF[50 + UP_BUF_SIZE * 2];
//任务完成情况
TYP_TASK_RESULT g_s_nbiot_task_flag = TASK_INIT;
//数据发送通道
u8 g_s_nbiot_send_type;
//模组上电标志
u8 nb_power_flag = FALSE;
//AT指令查询失败次数
u8 at_requestErrorCount=0;
//AT指令执行结果
TYP_RESULT_CODE g_at_request_res;
//AT指令索引
int g_at_index=0;
//TCP要发送数据的长度
u16 tcp_send_len=0;
char tcp_send_len_buf[8];
u8 tcp_send_len_buf_len=0;
//UDP要发送数据的长度
u16 udp_send_len=0;
char udp_send_len_buf[8];
u8 udp_send_len_buf_len=0;
//IP地址
unsigned char *coap_ip;
u16 coap_port;
unsigned char *udp_ip1;
u16 udp_port1;
unsigned char *udp_ip2;
u16 udp_port2;
u8 nbiot_temp_connect_type=NBIOT_CONNECT_COAP;
//PSM状态
TYP_PSM_STATE psm_model_state = PSM_STATE_OUT;
TYP_PSM_WAKEUP_STATE s_psm_wakeup_state = PSM_WKUPSTA_IDLE;
TYP_PSM_SLEEP_STATE s_psm_sleep_state = PSM_SLPSTA_IDLE;
//AT指令集
static STRUCT_AT_CMD AtCmdBuf[AT_CMD_COUNT]={
	/*****模组初始化指令********************/
	{AT_CODE_AT,      "AT+CMVER",                     WT_2S, RETRY_5, cst_AT_No_AT},//AT指令
	{AT_CODE_CFUN1,   "AT+CFUN=1",              WT_2S, RETRY_5, cst_AT_No_AT_CFUN},//
	{AT_CODE_CPIN,    "AT+CPIN?",               WT_2S, RETRY_5, cst_AT_No_AT_CPIN},//查询SIM卡状态,READY表示SIM卡正常识别运行
	{AT_CODE_CSQ,     "AT+CSQ",                 WT_2S, RETRY_5, cst_AT_No_AT_CSQ},//查询信号质量
	{AT_CODE_CEREG,   "AT+CEREG?",              WT_2S, RETRY_15,cst_AT_No_AT_CEREG},//查询网络注册状态
	{AT_CODE_CGACT_CK,"AT+CGACT?",              WT_5S, RETRY_30,cst_AT_No_AT_CGACT_how},//查询网络附着状态
	{AT_CODE_COPS_CK, "AT+COPS?",               WT_5S, RETRY_30,cst_AT_No_AT},//查询网络信息，运营商及网络制式 9 即 NB-IOT 网络
	{AT_CODE_CGCONTRDP, "AT+CGCONTRDP",         WT_5S, RETRY_30,cst_AT_No_AT},//查询网络下发 APN 和分配的 IP 地址。
	{AT_CODE_CGATT_CK,"AT+CGATT?",              WT_2S, RETRY_30,cst_AT_No_AT_CGATT_how},//查询网络附着状态
	{AT_CODE_CGDCONT_CK,"AT+CGDCONT?",          WT_5S, RETRY_30,cst_AT_No_AT},//查询网络附着状态
	{AT_CODE_NUESTATS,  "AT+NUESTATS=RADIO",    WT_5S, RETRY_3,cst_AT_No_AT_NUESTATS},//查询网络附着状态
 
	{AT_CODE_VERCTRL, "AT+VERCTRL?",            WT_2S, RETRY_5, cst_AT_No_VERCTRL_CK},//查询激活方式
	{AT_CODE_VERCTRL1,"AT+VERCTRL=0,1",         WT_2S, RETRY_5, cst_AT_No_AT},//设置自动激活方式
	{AT_CODE_CMEE,    "AT+CMEE=1",              WT_2S, RETRY_5, cst_AT_No_AT_CMEE},//打开ERROR错误码显示
	{AT_CODE_CGSN,    "AT+CGSN=1",              WT_2S, RETRY_5, cst_AT_No_AT_IMEI},//查询IMEI

	{AT_CODE_CIMI,    "AT+CIMI",                WT_2S, RETRY_5, cst_AT_No_AT_CIMI},//查询IMSI
	{AT_CODE_ICCID,   "AT+NCCID",               WT_2S, RETRY_5, cst_AT_No_AT_ICCID},//查询ICCID
	{AT_CODE_CFUN_CK, "AT+CFUN?",               WT_2S, RETRY_5, cst_AT_No_AT_CFUN},//查询协议栈是否打开
	{AT_CODE_CFUN0,   "AT+CFUN=0",              WT_2S, RETRY_5, cst_AT_No_AT_CFUN},//
	

	{AT_CODE_TUEINFO, "AT+TUEINFO",             WT_2S, RETRY_2, cst_AT_No_AT_TUEINFO},//查询信号状态
	{AT_CODE_CCED,    "AT+CCED=0,1",            WT_2S, RETRY_2, cst_AT_No_AT_CCED},//Single shot requested.
	{AT_CODE_CGDCONT, "AT+CGDCONT=1,\"IP\",\"", WT_2S, RETRY_1, cst_AT_No_AT},//设置APN  AT+CGDCONT=1,”IP”,”CMIOT”
	{AT_CODE_CGACT,   "AT+CGACT=1,1",           WT_20S,RETRY_2, cst_AT_No_AT_CGACT_how},//激活 PDP  //最长等待20s,期间发送AT指令无应答
	
	
	{AT_CODE_CCLK,    "AT+CCLK?",               WT_5S, RETRY_3, cst_AT_No_AT_CCLK},//查询模组时间
	 
	{AT_CODE_CTEC_CK,    "AT+CTEC?",            WT_5S, RETRY_1, cst_AT_No_AT_CCLK},//查询模组时间
	{AT_CODE_CCED_CK,    "AT+CCED=0,1",         WT_5S, RETRY_5, cst_AT_No_AT_CCLK},//查询模组时间
	/*****TCP连接指令***********************/
	{AT_CODE_NSOCR, "AT+NSOCR=STREAM,6,1234,1,AF_INET",   WT_5S, RETRY_5, cst_AT_No_AT},//创建套接字
	{AT_CODE_NSOCO, "AT+NSOCO=0,\"",WT_40S, RETRY_1, cst_AT_No_AT},//AT+NSOCO=0,"47.104.217.235",5005
	
	/*When mode set to 1(transparent mode), n(connect_id) must be 0 and no TCP/UDP connection has already been 
	established.*/
	//{AT_CODE_MIPMODE1,"AT+MIPMODE=0,1",         WT_2S, RETRY_5, cst_AT_No_AT},//设置透传连接方式 AT+MIPMODE=0,1
	//{AT_CODE_MIPOPEN, "AT+MIPOPEN=0,\"TCP\",\"",WT_5S, RETRY_5, cst_AT_No_AT_MIPOPEN},// AT+MIPOPEN=0,"TCP","58.59.6.130",21628
	{AT_CODE_MIPMODE1,"AT+MIPMODE=1,0",         WT_2S, RETRY_5, cst_AT_No_AT},//(不使用透传方式)
	{AT_CODE_MIPOPEN, "AT+MIPOPEN=1,\"TCP\",\"",WT_35S, RETRY_1, cst_AT_No_AT_MIPOPEN},// AT+MIPOPEN=1,"TCP","58.59.6.130",21628 
	{AT_CODE_MCWCREATE, "AT+MCWCREATE=",        WT_5S, RETRY_1, cst_AT_No_AT_MCWCREATE},// AT+MCWCREATE=221.229.214.202,5683
	{AT_CODE_MCWOPEN, "AT+MCWOPEN=1,300",       WT_35S, RETRY_0, cst_AT_No_AT_MCWOPEN},//AT+MCWOPEN=1,300//自动 update，lifetime 300 秒
	/*****TCP数据发送***********************/ 
	{AT_CODE_MIPSENDCOUNT,"AT+MIPSEND=1,",      WT_5S, RETRY_2, cst_AT_No_AT_MIPSENDCOUNT},//设置发送字节数
	//{AT_CODE_TCPSEND, "",                       WT_5S, RETRY_0, cst_AT_No_AT_TCPSEND},// 
	//AT+NSOSD=0,176,FEFE68,0x200
	{AT_CODE_TCPSEND, "AT+NSOSD=",              WT_5S, RETRY_0, cst_AT_No_AT_NMGS},// 
	//关闭TCP连接
	{AT_CODE_MIPCLOSE, "AT+MIPCLOSE=1",         WT_5S, RETRY_2, cst_AT_No_AT_MIPCLOSE},//AT+MIPCLOSE=0
	/*****UDP1连接指令**********************/ 
	{AT_CODE_MIPOPEN_UDP1,"AT+NSOCR=DGRAM,17,0,1",WT_5S, RETRY_1, cst_AT_No_AT_QIOPEN},// AT+MIPOPEN=1,"UDP","60.208.16.58",7833
	//Socket 数据格式配置
	{AT_CODE_NSOCFG, "AT+NSOCFG=",WT_5S, RETRY_1, cst_AT_No_AT},//AT+NSOCFG=0,1,1	
	/*****UDP1数据发送***********************/ 
	{AT_CODE_MIPSENDCOUNT_UDP1,"AT+MIPSEND=2,", WT_5S, RETRY_2, cst_AT_No_AT_MIPSENDCOUNT},//设置发送字节数
	{AT_CODE_UDPSEND1, "AT+NSOST=",           WT_5S, RETRY_0, cst_AT_No_AT_NMGS},// //AT+ECSOST=1,"183.230.174.137",6065,2,"3334"
	//关闭UDP1连接
	{AT_CODE_MIPCLOSE_UDP1, "AT+MIPCLOSE=2",    WT_5S, RETRY_2, cst_AT_No_AT_MIPCLOSE},//AT+MIPCLOSE=0
	/*****UDP2连接指令**********************/
	{AT_CODE_MIPOPEN_UDP2,"AT+MIPOPEN=3,\"UDP\",\"",WT_5S, RETRY_5, cst_AT_No_AT_MIPOPEN},// AT+MIPOPEN=1,"UDP","60.208.16.58",7833 
	/*****UDP2数据发送***********************/
	{AT_CODE_MIPSENDCOUNT_UDP2,"AT+MIPSEND=3,",  WT_5S, RETRY_2, cst_AT_No_AT_MIPSENDCOUNT},//设置发送字节数
	{AT_CODE_UDPSEND2, "",                       WT_5S, RETRY_0, cst_AT_No_AT_TCPSEND},// 
	//COAP发送数据
	{AT_CODE_MCWSEND0, "AT+MCWSEND=",            WT_5S, RETRY_0, cst_AT_No_AT_MCWSEND},//AT+MCWSEND= 
	{AT_CODE_MCWSEND1, "AT+MCWSEND=",            WT_5S, RETRY_0, cst_AT_No_AT_MCWSEND_ACKID},//AT+MCWSEND= 

	//关闭UDP2连接
	{AT_CODE_MIPCLOSE_UDP2, "AT+MIPCLOSE=3",     WT_5S, RETRY_2, cst_AT_No_AT_MIPCLOSE},//AT+MIPCLOSE=0
	//读取数据 
	{AT_CODE_READ_DATA, "AT+NSORF=",     WT_2S, RETRY_1, cst_AT_No_AT_READ_DATA},//AT+NSORF=0,32
	//设置APN  
	{AT_CODE_CGDCONT1, "AT+CGDCONT=1,\"IP\",\"",    WT_2S, RETRY_1, cst_AT_No_AT},//AT+CGDCONT=1,"IP","XINYI.COM"
	{AT_CODE_CGDCONT3, "AT+CGDCONT=3,1,\"",  WT_2S, RETRY_1, cst_AT_No_AT},//AT+CGDCONT=3,1,"cmnet"
	//关闭套接字
	{AT_CODE_NSOCL, "AT+NSOCL=",  WT_2S, RETRY_1, cst_AT_No_AT},//AT+NSOCL=0 //关闭 TCP socket
	//限制功率查询和设置
	{AT_CODE_NVGET, "AT+NV=GET,MAXULPOW",     WT_2S, RETRY_1, cst_AT_No_AT_NVGET}, 
	{AT_CODE_NVSET, "AT+NV=SET,MAXULPOW,22",  WT_2S, RETRY_1, cst_AT_No_AT_NVSET}, 
	{AT_CODE_NVSET0,"AT+NV=SET,MAXULPOW,0",  WT_2S, RETRY_1, cst_AT_No_AT_NVSET}, 
	{AT_CODE_NRB,   "AT+NRB",                 WT_2S, RETRY_1, cst_AT_No_AT_NRB},  
	//ONENET
	{AT_CODE_MIPLCREATEEX,     "AT+MIPLCREATEEX=\"",  WT_5S, RETRY_2, cst_AT_No_AT_MIPLCREATEEX},  
	{AT_CODE_MIPLADDOBJ,       "AT+MIPLADDOBJ=0,3200,1,\"1\",0,0",  WT_5S, RETRY_2, cst_AT_No_AT_MIPLADDOBJ},  
	{AT_CODE_MIPLDISCOVERRSP,  "AT+MIPLDISCOVERRSP=0,3200,1,4,\"5750\"",  WT_5S, RETRY_2, cst_AT_No_AT_MIPLDISCOVERRSP},
	{AT_CODE_MIPLOPEN,         "AT+MIPLOPEN=0,3000,30",  WT_20S, RETRY_2, cst_AT_No_AT_MIPLOPEN},
	{AT_CODE_MIPLUPDATE,       "AT+MIPLUPDATE=0,0,0",    WT_5S, RETRY_2, cst_AT_No_AT_MIPLUPDATE},
	{AT_CODE_MIPLNOTIFY,       "AT+MIPLNOTIFY=0,0,3200,0,5750,1,",    WT_5S, RETRY_2, cst_AT_No_AT},
	//下线流程
	{AT_CODE_MIPLCLOSE,        "AT+MIPLCLOSE=0",          WT_5S, RETRY_2, cst_AT_No_AT},
	{AT_CODE_MIPLDELOBJ,       "AT+MIPLDELOBJ=0,3200",    WT_5S, RETRY_2, cst_AT_No_AT},
	{AT_CODE_MIPLDELETE,       "AT+MIPLDELETE=0",         WT_5S, RETRY_2, cst_AT_No_AT},
	{AT_CODE_CPOF,             "AT+CPOF",                 WT_5S, RETRY_2, cst_AT_No_AT},
	{AT_CODE_NCSEARFCN,        "AT+NCSEARFCN",            WT_5S, RETRY_2, cst_AT_No_AT},
	
	{AT_CODE_MCWCLOSE,        "AT+MCWCLOSE",            WT_5S, RETRY_2, cst_AT_No_AT},
	{AT_CODE_MCWDELETE,        "AT+MCWDELETE",            WT_5S, RETRY_2, cst_AT_No_AT},
};  

/*****************************内部功能状态定义*********************************/
//主状态
TYP_STATE_MAIN_CONNECT g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; 
//开机状态
TYP_STEP_MODULE_POWERON s_power_on_state = MODULE_IDLE; 
//关机状态
TYP_STATE_POWER_OFF s_power_off_state = S_PWOFF_IDLE; 
//AT指令查询状态
TYP_STATE_AT_REQUEST s_at_requeset_state = AT_REQUEST_IDLE;
//模组初始化状态
TYP_MODULE_INIT s_init_state=S_MODULE_INIT_IDLE;
//COAP连接状态机
TYP_COAP_CONNECT s_coap_connect_state=S_COAP_CONNECT_IDLE;
//COAP发送数据状态
TYP_COAP_SEND s_coap_send_state = S_COAP_SEND_IDLE;
//UDP连接状态
TYP_UDP_CONNECT s_udp_connect_state = S_UDP_CONNECT_IDLE;
//UDP发送数据状态
TYP_UDP_SEND s_udp_send_state;
//UDP读取数据
TYP_READ_DATA s_read_data_state=S_READ_DATA_IDLE;
//ONNET连接状态机
TYP_ONENET_CONNECT s_onenet_connect_state = S_ONENET_CONNECT_IDLE;
//ONNET发送数据状态
TYP_ONENET_SEND s_onenet_send_state = S_ONENET_SEND_IDLE;

/*****************************内部功能状态机函数*********************************/
void NbiotInitMachine(void);
void NbiotPowerOffMachine(void);
void UdpReadDataMachine(void);
//UDP连接
void UdpStartConnect(u8 udp_num);
void UdpConnectMachine(void);
//UDP发送
void StartUdpSendData(void);
void UdpSendDataMachine(void);
//读取数据
void Tcp_UdpReadDataMachine(void);
//Coap连接
static void CoapStartConnect(void);
void CoapConnectMachine(void);
//Coap发送
void StartCoapSendData(void);
void CoapSendDataMachine(void);
//OneNet连接
void OneNetStartConnect(void);
static void OnenetConnectMachine(void);
//OneNet发送
void StartOnenetSendData(void);
void OnenetSendDataMachine(void);
//设置APN
void NbiotInitMachine_SetAPN(void);
/*****************************内部定时器接口**********************************/
void set_timer_1s(u16 time);
u16 check_timer_1s(void);
void set_timer_1ms(u16 time);
u16 check_timer_1ms(void);
void StartNbiotInit(void);
/*****************************外部接口****************************************/
void NB_Power_Disable(void) 
{
	Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, FALSE);
	nb_power_flag = FALSE;
}

void NB_Power_Enable(void)  
{
	Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, TRUE);
	nb_power_flag = TRUE;
}

u8 If_NB_Poweron(void)
{    
	return nb_power_flag;    
}
/***************************************************************************
* @fun_name     void NbModuleIOInit(void)
* @brief        模块供电IO、模块复位、电源、PSM唤醒引脚初始化
***************************************************************************/
void NbModuleIOInit(void)
{
    stc_gpio_cfg_t stcGpioCfg;
    DDL_ZERO_STRUCT(stcGpioCfg);
    stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置
    stcGpioCfg.enDrv = GpioDrvL;      ///< 端口驱动能力配置->低驱动能力
    stcGpioCfg.enPu = GpioPuDisable;  ///< 端口上下拉配置->无
    stcGpioCfg.enPd = GpioPdDisable;
    stcGpioCfg.enOD = GpioOdDisable;  ///< 端口开漏输出配置
    stcGpioCfg.enCtrlMode = GpioAHB;  ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    Gpio_Init(BAT_NB_PORT, BAT_NB_PIN, &stcGpioCfg);  //模块供电IO
    Gpio_Init(RSTN_NB_PORT, RSTN_NB_PIN, &stcGpioCfg);
    Gpio_Init(NB_PSM_WAKE_PORT, NB_PSM_WAKE_PIN, &stcGpioCfg);
    Gpio_Init(PWR_NB_PORT, PWR_NB_PIN, &stcGpioCfg);   //电源控制脚
    Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, FALSE);
    Gpio_WriteOutputIO(PWR_NB_PORT, PWR_NB_PIN, FALSE);
	Gpio_WriteOutputIO(RSTN_NB_PORT, RSTN_NB_PIN, FALSE); 
	Gpio_WriteOutputIO(NB_PSM_WAKE_PORT , NB_PSM_WAKE_PIN, FALSE);
}
/*模组端串口调试配置*/
void NB_UartInitForGPIO(void)//debug
{
    stc_gpio_cfg_t stcGpioCfg;

	DDL_ZERO_STRUCT(stcGpioCfg);
    //PA0,PA1:配置为数字输入
    stcGpioCfg.enDir = GpioDirIn;    ///< 端口方向配置->输入
    stcGpioCfg.enDrv = GpioDrvL;     ///< 端口驱动能力配置->低驱动能力
    stcGpioCfg.enPu = GpioPuDisable; ///< 端口上下拉配置->无
    stcGpioCfg.enPd = GpioPdDisable;
    stcGpioCfg.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭
    stcGpioCfg.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    Gpio_Init(GpioPortA, GpioPin0, &stcGpioCfg);	
    Gpio_Init(GpioPortA, GpioPin1, &stcGpioCfg);
}

/***************************************************************************
 * @fun_name     void NbiotMainMachine()
 * @brief        NBIOT主任务机，放在主程序空间的主循环中，进行NBIOT任务处理
 ***************************************************************************/
void NbiotMainMachine(void)
{
    switch (g_s_nbiot_main_state)
    {
        case S_NBIOT_MAIN_IDLE:
		{
			if(TRUE == UdpIfNeedReadDataY7028(NBIOT_CONNECT_UDP1))
			{
				ClearUdpReadDataFlag(NBIOT_CONNECT_UDP1);
				SetRcvDataType(NB_RCV_UDP1_DATA);
				g_s_nbiot_main_state = S_NBIOT_MAIN_READ_DATA;
			}
		} 
        break;

        case S_NBIOT_MAIN_POWER_INIT:
        {
            if (TASK_INIT == g_s_nbiot_task_flag) //如果是初始状态
            {
                NbiotInitMachine(); //模块初始化状态机
            }
			else
			{
				if (TASK_SUCCESS == g_s_nbiot_task_flag) //任务成功
				{	
					u8 temp_iccid_buf[20];
					NbiotGetICCID((char*)temp_iccid_buf); //中国移动的为:898600;898602;898604;898607 中国电信898603;898611
					Nbiot_Para.Telecom = SIM_CARD_TELECOM;//电信卡
					if(temp_iccid_buf[4]=='0')
					{
						if((temp_iccid_buf[5]=='0')||(temp_iccid_buf[5]=='2')||(temp_iccid_buf[5]=='4')||(temp_iccid_buf[5]=='7'))
						{
							Nbiot_Para.Telecom = SIM_CARD_MOBILE;
						}
					}
					Nbiot_Para.net_state = NB_ON_LINE;
					g_s_nbiot_task_flag = TASK_INIT;
					g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
				}
				else //任务失败
				{
					*Nbiot_Send_Data.state = NBIOT_ERROR;
					g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
				}
				g_s_nbiot_task_flag = TASK_INIT; //清标志位
			}
        }
        break; 
		case S_NBIOT_MAIN_COAP_OPEN:
		{
			if (TASK_INIT == g_s_nbiot_task_flag)
            {
				if(Nbiot_Para.Telecom == SIM_CARD_MOBILE)//移动卡
				{
					OnenetConnectMachine();//与ONNET平台建立连接状态机
				}
				else//电信卡
				{
					CoapConnectMachine(); //与主站建立连接状态机	
				}	
            }
			else
			{
				if (TASK_SUCCESS == g_s_nbiot_task_flag)
				{
					Nbiot_Para.coap_state = CONNECT_ON_LINE;
				}
				else
				{
					Nbiot_Para.coap_state = CONNECT_OFF_LINE;
					*Nbiot_Send_Data.state = NBIOT_ERROR;
				}
				g_s_nbiot_task_flag = TASK_INIT;
				g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; 
			}
		}
		break;
		case S_NBIOT_MAIN_COAP_SEND:
		{
			if (CONNECT_ON_LINE == Nbiot_Para.coap_state)
            {
                if (TASK_INIT == g_s_nbiot_task_flag)
                {
					if(Nbiot_Para.Telecom == SIM_CARD_MOBILE)//移动卡
					{
						OnenetSendDataMachine();
					}
					else//电信卡
					{
						CoapSendDataMachine(); //数据发送状态机
					}
                }
				else//发送数据任务成功和失败都回到空闲
				{
					*Nbiot_Send_Data.state = NBIOT_SUCCESS;
					g_s_nbiot_task_flag = TASK_INIT;
					g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
				}
            }
			else
			{
				g_s_nbiot_task_flag = TASK_INIT;
				g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
			}
		}
		break;
        
		case S_NBIOT_MAIN_UDP_OPEN:
        {
            if (TASK_INIT == g_s_nbiot_task_flag)
            {
                UdpConnectMachine(); //与主站建立连接状态机
            }
			else
			{
				if (TASK_SUCCESS == g_s_nbiot_task_flag)
				{
					if(nbiot_temp_connect_type == NBIOT_CONNECT_UDP1)
					{
						 Nbiot_Para.udp1_state = CONNECT_ON_LINE;
					}
					else if(nbiot_temp_connect_type == NBIOT_CONNECT_UDP2)
					{
						 Nbiot_Para.udp2_state = CONNECT_ON_LINE;
					}   
				}
				g_s_nbiot_task_flag = TASK_INIT;
				g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; 
			}
        }
        break;

        case S_NBIOT_MAIN_UDP_SEND:
        {
            if (CONNECT_ON_LINE == Nbiot_Para.udp1_state)
            {
                if (TASK_INIT == g_s_nbiot_task_flag)
                {
                    UdpSendDataMachine(); //数据发送状态机
                }
				else//发送数据任务成功和失败都回到空闲
				{
					g_s_nbiot_task_flag = TASK_INIT;
                    g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
				}
            }
			else
			{
				g_s_nbiot_task_flag = TASK_INIT;
				g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
			}
        }
        break;
        case S_NBIOT_MAIN_POWER_OFF:
        {
            if (TASK_INIT == g_s_nbiot_task_flag)
            {
                NbiotPowerOffMachine(); //断电关机
            }
            else
            {
                g_s_nbiot_task_flag = TASK_INIT;
                g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
                Nbiot_Para.net_state = NB_OFF_LINE;
				Nbiot_Para.coap_state = CONNECT_OFF_LINE;
				Nbiot_Para.udp1_state = CONNECT_OFF_LINE;
				Nbiot_Para.udp2_state = CONNECT_OFF_LINE;
            }
        }
        break;
		case S_NBIOT_MAIN_READ_DATA:
		{
			if (TASK_INIT == g_s_nbiot_task_flag)
            {
                Tcp_UdpReadDataMachine();
            }
            else
            {
                g_s_nbiot_task_flag = TASK_INIT;
                g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
            }		
		}
		break;
        default:
        {
            g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
        }
        break;
    }
}
/***************************************************************************
 * @fun_name     u8 NbiotIfIdle()
 * @brief        查询模块的空闲状态
 ***************************************************************************/
u8 NbiotIfIdle(void)
{
    if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state)
    {
        return TASK_IDLE;
    }
    else
    {	
        return TASK_BUSY;
    }
}

/***************************************************************************
 * @fun_name     u8 NbiotIfOnline()
 * @brief        查询NBIOT是否在线
 ***************************************************************************/
u8 NbiotIfOnline(void)
{
    if (NB_ON_LINE == Nbiot_Para.net_state)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/***************************************************************************
 * @fun_name     u8 UdpIfOnline()
 * @brief        查询UDP连接是否建立
 ***************************************************************************/
//u8 UdpIfOnline(void)
//{
//    if (CONNECT_ON_LINE == Nbiot_Para.udp1_state)
//    {
//        return TRUE;
//    }
//    else
//    {
//        return FALSE;
//    }
//}
/***************************************************************************
 * @fun_name     u8 ConncetIfOnline()
 * @brief        查询连接是否在线
 ***************************************************************************/
u8 ConncetIfOnline(u8 connect_type)
{  
	if(connect_type == NBIOT_CONNECT_COAP)
	{
		if (CONNECT_ON_LINE == Nbiot_Para.coap_state)
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}
	else if(connect_type == NBIOT_CONNECT_UDP1)
	{
		if (CONNECT_ON_LINE == Nbiot_Para.udp1_state)
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}
	else if(connect_type == NBIOT_CONNECT_UDP2)
	{
		if (CONNECT_ON_LINE == Nbiot_Para.udp2_state)
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}
	return FALSE;
}
/***************************************************************************
 * @fun_name     void NbiotOnlineTask(u8 *state)
 * @brief        NBIOT上线任务
 * @param[in]    state:状态信息
 ***************************************************************************/
void NbiotOnlineTask(u8 *state)
{
    if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state)
    {
        if (!NbiotIfOnline())
        {
            if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state)
            {
                Nbiot_Send_Data.state = state; //地址拷贝
                *state = NBIOT_ING;
				g_s_nbiot_task_flag = TASK_INIT;
                g_s_nbiot_main_state = S_NBIOT_MAIN_POWER_INIT;
				StartNbiotInit();
            }
        }
        else
        {
            *state = NBIOT_ONLINE;
        }
    }
    else
    {
        *state = NBIOT_ERROR;
    }
}
/***************************************************************************
 * @fun_name     void NB_NetConnectStart
 * @brief        根据连接类型建立连接
 * @param[in]    state:状态信息
 ***************************************************************************/
void NB_NetConnectStart(unsigned char* temp_ip, u16 temp_port, u8 connect_type)
{
	if(connect_type == NBIOT_CONNECT_COAP)
	{
		coap_ip = temp_ip;
		coap_port = temp_port;
		if(Nbiot_Para.Telecom == SIM_CARD_MOBILE)//移动卡
		{
			OneNetStartConnect(); 
		}
		else//电信卡
		{
			CoapStartConnect();	
		}
		nbiot_temp_connect_type = NBIOT_CONNECT_COAP;
		g_s_nbiot_main_state = S_NBIOT_MAIN_COAP_OPEN;
	}
	else if(connect_type == NBIOT_CONNECT_UDP1)
	{
		udp_ip1 = temp_ip;
		udp_port1 = temp_port;
		UdpStartConnect(connect_type);
		g_s_nbiot_main_state = S_NBIOT_MAIN_UDP_OPEN;
	}
	else if(connect_type == NBIOT_CONNECT_UDP2)
	{
		udp_ip2 = temp_ip;
		udp_port2 = temp_port;
		UdpStartConnect(connect_type);
		g_s_nbiot_main_state = S_NBIOT_MAIN_UDP_OPEN;
	}
	g_s_nbiot_task_flag = TASK_INIT;
}
void NbiotPsmWakeupTask(void)
{
 
}
void NbiotPsmSleepTask(void)
{
 
}
void NbiotPsmCheckTask(void)
{
   
}
/***************************************************************************
 * @fun_name     void NbiotSendTask(u8 *addr, u16 len, u8 send_type,u8 *state)
 * @brief        NBIOT数据发送任务
 * @param[in]    addr：内容的首地址 len：长度
 * @param[out]   state:状态信息
 * @retval       None
 * @other        state(NBIOT_ING：查询中, NBIOT_SUCCES：成功 其他：异常)
 ***************************************************************************/
void NbiotSendTask(u8 *addr, u16 len, u8 send_type,u8 *state)
{
    if ((S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state) && (len > 0) && (len <= UP_BUF_SIZE))
    {
        Nbiot_Send_Data.buf = addr; //地址拷贝
        Nbiot_Send_Data.len = len; //值拷贝
        Nbiot_Send_Data.state = state; //地址拷贝
        *state = NBIOT_ING;
		g_s_nbiot_send_type = send_type;
		g_s_nbiot_task_flag = TASK_INIT;
		if((SEND_TYPE_UDP1 == g_s_nbiot_send_type)||(SEND_TYPE_UDP2 == g_s_nbiot_send_type))
		{
			g_s_nbiot_main_state = S_NBIOT_MAIN_UDP_SEND;
			StartUdpSendData();
		}
		else
		{
			if(Nbiot_Para.Telecom == SIM_CARD_MOBILE)//移动卡
			{
				StartOnenetSendData();
			}
			else//电信卡
			{
				StartCoapSendData(); //数据发送状态机
			} 
			g_s_nbiot_main_state = S_NBIOT_MAIN_COAP_SEND; //发送NBIOT数据
		}		
    }
    else
    {
        *state = NBIOT_ERROR;
    }
}
//获取发送类型
u8 GetNbiotSendType(void)
{
	return g_s_nbiot_send_type;	
}
/***************************************************************************
 * @fun_name     u8 NbiotIfSleep()
 * @brief        是否允许休眠
 * @param[in]    None
 * @param[out]   None
 * @retval       TRUE: 允许  FALSE:不允许
 * @other        None
 ***************************************************************************/
u8 NbiotIfSleep(void)
{
    if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/***************************************************************************
 * @fun_name     void NbiotPreSleep()
 * @brief        休眠前操作
 * @param[in]    None
 * @param[out]   None
 * @retval       None
 * @other        None
 ***************************************************************************/
void NbiotPreSleep(void)
{
    NB_Power_Disable(); //切断电源
    UartPreSleep(NB_UART_COM);
    g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
	Nbiot_Para.net_state = NB_OFF_LINE;
	Nbiot_Para.coap_state = CONNECT_OFF_LINE;
	Nbiot_Para.udp1_state = CONNECT_OFF_LINE;
	Nbiot_Para.udp2_state = CONNECT_OFF_LINE;
	
	//配置NB相关引脚
	stc_gpio_cfg_t stcGpioCfg;
	DDL_ZERO_STRUCT(stcGpioCfg);	
	stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置	
	stcGpioCfg.enDrv = GpioDrvL;      ///< 端口驱动能力配置->低驱动能力	
	stcGpioCfg.enPu = GpioPuDisable;  ///< 端口上下拉配置->无
	stcGpioCfg.enPd = GpioPdDisable;	
	stcGpioCfg.enOD = GpioOdDisable;  ///< 端口开漏输出配置
	stcGpioCfg.enCtrlMode = GpioAHB;  ///< 端口输入/输出值寄存器总线控制模式配置->AHB
	Gpio_Init(BAT_NB_PORT, BAT_NB_PIN, &stcGpioCfg);  //模块供电IO
    Gpio_Init(RSTN_NB_PORT, RSTN_NB_PIN, &stcGpioCfg);
    Gpio_Init(NB_PSM_WAKE_PORT, NB_PSM_WAKE_PIN, &stcGpioCfg);
    Gpio_Init(PWR_NB_PORT, PWR_NB_PIN, &stcGpioCfg);   //电源控制脚
	
	Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, FALSE);
    Gpio_WriteOutputIO(PWR_NB_PORT, PWR_NB_PIN, FALSE);
	Gpio_WriteOutputIO(RSTN_NB_PORT, RSTN_NB_PIN, FALSE); 
	Gpio_WriteOutputIO(NB_PSM_WAKE_PORT , NB_PSM_WAKE_PIN, FALSE);	
	
	Gpio_Init(LPUART1_TX_PORT, LPUART1_TX_PIN, &stcGpioCfg);
	Gpio_WriteOutputIO(LPUART1_TX_PORT, LPUART1_TX_PIN, FALSE);	//TX也配置为输出低
	
	stcGpioCfg.enDir = GpioDirIn;   //RX输入
	Gpio_Init(LPUART1_RX_PORT, LPUART1_RX_PIN, &stcGpioCfg);
}
/***************************************************************************
 * @fun_name    void NbiotWakeSleep()
 * @brief        休眠后唤醒
 * @param[in]    None
 * @param[out]   None
 * @retval       None
 * @other        None
 ***************************************************************************/
void NbiotWakeSleep(void)
{

}
/******************************内部状态机***********************************/

/***************************************************************************
 * @fun_name     void NetModulePowerOn_Proc()
 * @brief        模组开机状态
 * @param[in] 	 None
 * @param[out] 	 None
 * @retval     	 None
 * @other        None
 ***************************************************************************/
TYP_RESULT_CODE NetModulePowerOn_Proc(void)
{
	switch(s_power_on_state)
	{
		case MODULE_IDLE://模块送电
        {  
        }
        break;
		case MODULE_POWERON://模块送电
        {  
			NbModuleIOInit();  //初始化默认模块断电
            UartInit(NB_UART_COM, BAUD9600, DATA_BIT_8, STOPBIT_1, UART_NONE_PARITY,UART_LPUART_Disable);	
            RSTN_NB_HIG();
            PWR_NB_HIG();
            NB_Power_Enable(); 						//打开电源，延时1S,等待上电稳定
            set_timer_1ms(MODULE_POWER_DELAY_TIME);
            s_power_on_state = MODULE_POWERON_WT;
        }
        break;
        case MODULE_POWERON_WT://NB模块送电
        {
            if (!check_timer_1ms())
            {
                PWR_NB_LOW();
				set_timer_1ms(MODULE_POWERKEY_DELAY_TIME);
                s_power_on_state = MODULE_POWER_KEY_ON_WT;
            }
        }
        break;
        case MODULE_POWER_KEY_ON_WT://NB模块送电
        {
            if (!check_timer_1ms())
            {
				s_power_on_state = MODULE_IDLE;
				return ResultOk;
            }
        }
        break;
		default:
		{
			s_power_on_state = MODULE_IDLE;
		}
		break;
	}
	return ResultBusy;
}
/***************************************************************************
 * @fun_name     void AT_Common_Requeset_Proc()
 * @brief        AT指令集通用查询函数
 * @param[in] 	 None
 * @param[out] 	 None
 * @retval     	 None
 * @other       中国移动的为:898600;898602;898604;898607 中国电信898603;898611
 ***************************************************************************/
int getAtIndexFromCode(TYP_AT_CMDCODE atCode)
{
    for(int i=0;i<AT_CMD_COUNT;i++)
	{
	    if(AtCmdBuf[i].AtCode == atCode)
		{
		    return i;
		}
	}
	return 0;
}
TYP_RESULT_CODE AT_Common_Requeset_Proc(TYP_AT_CMDCODE atCode, char addFlag, char* addBuf, int addLen)
{
	switch(s_at_requeset_state)
	{
		case AT_REQUEST_IDLE:
		{
			g_at_index = getAtIndexFromCode(atCode);
			at_requestErrorCount = 0;
			set_timer_1ms(500);
			s_at_requeset_state = AT_REQUEST_WT;
		}
		break;
		case AT_REQUEST_WT:
		{
			if (!check_timer_1ms())
			{
				set_timer_1s(0);
				s_at_requeset_state = AT_REQUEST_SEND;
			}
		}
		break;
		case AT_REQUEST_SEND:
		{
			if(!check_timer_1ms())
			{
				memset(AT_BUF,0,sizeof(AT_BUF));
				int i=0;
				int all_len=0;
				int str_len = strlen(AtCmdBuf[g_at_index].pAtCmdStr);
				const char *p;
				p = AtCmdBuf[g_at_index].pAtCmdStr;
				for(i=0; i<str_len; i++)
				{
					AT_BUF[i] = *p++;
					all_len++;
				}
				if(addFlag==1)
				{
					for(i=0; i<addLen; i++)
					{
						AT_BUF[str_len+i] = *addBuf++;
						all_len++;
					}
				}
				AT_BUF[all_len++] = '\r';
				/*strcpy(AT_BUF, AtCmdBuf[g_at_index].pAtCmdStr);//不能使用strcpy,否则取数据只能到0x00
				if(addFlag==1)
				{
					strcat(AT_BUF, addBuf);
				}
				strcat(AT_BUF, "\r");*/
					
				NbiotUartSend((u8*)AT_BUF, all_len, AtCmdBuf[g_at_index].CaseAtNum);//不能用strlen(AT_BUF),否则只能发送到0x00
				set_timer_1ms(1000*AtCmdBuf[g_at_index].WaitTime);
				s_at_requeset_state = AT_REQUEST_CHECK;
			}
		}
		break;
		case AT_REQUEST_CHECK:
		{
			if (NbiotCheckAtAck() == UART_OK)//返回正确的应答
            {
				s_at_requeset_state = AT_REQUEST_IDLE;
				return ResultOk;
            }
            else if ((!check_timer_1ms()) || (NbiotCheckAtAck() == UART_ERROR)) //应答超时或者错误
            {
                if (at_requestErrorCount >= AtCmdBuf[g_at_index].ErrorLimit)
                {
					s_at_requeset_state = AT_REQUEST_IDLE;
					return ResultFail;
                }
                else
                {
					at_requestErrorCount++;
                    //set_timer_1s(AtCmdBuf[g_at_index].WaitTime);
					s_at_requeset_state = AT_REQUEST_SEND;
                }
            }
		}
		break;
		default:
		{
			s_at_requeset_state = AT_REQUEST_IDLE;
			return ResultFail;
		}
	}
	return ResultBusy;
}

/***************************************************************************
 * @fun_name     void NbiotInitMachine()
 * @brief       模组初始化状态机
 * @param[in] 	 None
 * @param[out] 	 None
 * @retval     	 None
 * @other       
 ***************************************************************************/
void StartNbiotInit(void)
{
	s_init_state = S_MODULE_INIT_POWER_ON;
	s_power_on_state = MODULE_POWERON;//模块送电
}

void NbiotInitMachine_MN316(void)
{
    switch (s_init_state)
    {
		case S_MODULE_INIT_IDLE:
		{
			break;
		}
        case S_MODULE_INIT_POWER_ON://NB模块送电
        {  
			g_at_request_res = NetModulePowerOn_Proc();
			if(g_at_request_res == ResultOk)
			{
				//NB_UartInitForGPIO();//debug
				//初始化可调参数
				u8 NB_login_ask_times = FrameCheckParaApp(FramePara_NbParaLoginAckTimes);
				if (NB_login_ask_times < NET_CGATT_MIN_TIMES)
				{
					NB_login_ask_times = NET_CGATT_MIN_TIMES;
				}
				if (NB_login_ask_times > NET_CGATT_MAX_TIMES)
				{
					NB_login_ask_times = NET_CGATT_MAX_TIMES;
				}
				AtCmdBuf[getAtIndexFromCode(AT_CODE_CGATT_CK)].ErrorLimit = NB_login_ask_times;//查询网络注册状态次数
				
				if(getUploadControlPara(UP_AT_SIMPLE)!=AT_SIMPLE_NULL)
				{ 
					s_init_state = S_MODULE_INIT_CEREG_CK;
				}
				else
				{
					s_init_state = S_MODULE_INIT_AT;
				}
			}
        }
        break;
        case S_MODULE_INIT_AT:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_AT, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_NVGET;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;
		
		case S_MODULE_INIT_NVGET://功率查询
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NVGET, 0, NULL,0);
            if(g_at_request_res == ResultOk)//如果是低发射功率
			{
				s_init_state = S_MODULE_INIT_CMEE;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_NVSET;
			}
        }
        break;
		case S_MODULE_INIT_NVSET://功率设置
        {
			 if(Sys_data_object.P1.func_cfg_bytes[11] == 0x55)//降低发射功率
			 {
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NVSET, 0, NULL,0);
			 }
			 else
			 {
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NVSET0, 0, NULL,0);
			 }
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_NRB;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CMEE;
			}
        }
        break;
		
		case S_MODULE_INIT_NRB://模组复位
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NRB, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_NVGET;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_NVGET;
			}
        }
        break;

        case S_MODULE_INIT_CMEE:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CMEE, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CGSN;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;
		case S_MODULE_INIT_CGSN:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGSN, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CPIN;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;
		case S_MODULE_INIT_CPIN:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CPIN, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CIMI;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;
		case S_MODULE_INIT_CIMI:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CIMI, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_ICCID;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;
		case S_MODULE_INIT_ICCID:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_ICCID, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CFUN_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;
		case S_MODULE_INIT_CFUN_CK:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN_CK, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_GDCONT_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CFUN1;
			}
        }
        break;
		case S_MODULE_INIT_CFUN1:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN1, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{	
				s_init_state = S_MODULE_INIT_GDCONT_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_GDCONT_CK;
			}
        }
        break;

		case S_MODULE_INIT_GDCONT_CK:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGDCONT_CK, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CGDCONT_PRE;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CGDCONT_PRE;
			}
        }
        break;
		
		case S_MODULE_INIT_CGDCONT_PRE://检查是否修改APN
		{
			if(FrameCheckMsgApp(MsgNbApnChange))
			{
				FrameClearMsgApp(MsgNbApnChange);
				//获取APN参数
				memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));	
				for(int i = 0; i < Sys_data_object.P1.apn[1]; i++)
				{
					stringbuffer_temp[i] = Sys_data_object.P1.apn[2 + i];
				}	
				stringbuffer_temp[Sys_data_object.P1.apn[1]] = '\"';
				s_init_state = S_MODULE_INIT_CGDCONT;
			}
			else
			{
				s_init_state = S_MODULE_INIT_CEREG_CK;
			}
		}
		break;
				
		case S_MODULE_INIT_CGDCONT:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGDCONT, 1, stringbuffer_temp, Sys_data_object.P1.apn[1]+1);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CEREG_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CEREG_CK;
			}
        }
        break;
	
		case S_MODULE_INIT_CEREG_CK:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CEREG, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CGATT_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CGATT_CK;
			}
        }
        break; 
		case S_MODULE_INIT_CGATT_CK:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGATT_CK, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_NUESTATS_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;	

		case S_MODULE_INIT_NUESTATS_CK: 
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NUESTATS, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CSQ;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CSQ;
			}
        }
        break;	
		case S_MODULE_INIT_CSQ:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CSQ, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_COPS_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_COPS_CK;
			}
        }
        break; 
		
		case S_MODULE_INIT_COPS_CK:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_COPS_CK, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CGCONTRDP;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CGCONTRDP;
			}
        }
        break;	
		
		case S_MODULE_INIT_CGCONTRDP:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGCONTRDP, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CCLK;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CCLK;
			}
        }
        break;	
		case S_MODULE_INIT_CCLK:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CCLK, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				g_s_nbiot_task_flag = TASK_SUCCESS; //初始化任务成功
				s_init_state = S_MODULE_INIT_IDLE;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_SUCCESS; //初始化任务成功
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;	
        default:
        {
			g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
			s_init_state = S_MODULE_INIT_IDLE;
        }
        break;
    }
}
void NbiotInitMachine(void)
{
    NbiotInitMachine_MN316();
}
void NbiotInitMachine_SetAPN(void)
{
    switch (s_init_state)
    {
		case S_MODULE_INIT_IDLE:
		{
			break;
		}
        case S_MODULE_INIT_POWER_ON://NB模块送电
        {  
			g_at_request_res = NetModulePowerOn_Proc();
			if(g_at_request_res == ResultOk)
			{
				//NB_UartInitForGPIO();//debug
				//初始化可调参数
				u8 NB_login_ask_times = FrameCheckParaApp(FramePara_NbParaLoginAckTimes);
				if (NB_login_ask_times < NET_CGATT_MIN_TIMES)
				{
					NB_login_ask_times = NET_CGATT_MIN_TIMES;
				}
				if (NB_login_ask_times > NET_CGATT_MAX_TIMES)
				{
					NB_login_ask_times = NET_CGATT_MAX_TIMES;
				}
				AtCmdBuf[getAtIndexFromCode(AT_CODE_CGATT_CK)].ErrorLimit = NB_login_ask_times;//查询网络注册状态次数
				
				s_init_state = S_MODULE_INIT_AT;
			}
        }
        break;
        case S_MODULE_INIT_AT:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_AT, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CFUN0;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;
		case S_MODULE_INIT_CFUN0:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN1, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{	
				s_init_state = S_MODULE_INIT_CFUN_CK;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CFUN_CK;
			}
        }
        break;	
		case S_MODULE_INIT_CFUN_CK:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN_CK, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{
				//获取APN参数
				memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));	
				for(int i = 0; i < Sys_data_object.P1.apn[1]; i++)
				{
					stringbuffer_temp[i] = Sys_data_object.P1.apn[2 + i];
				}	
				stringbuffer_temp[Sys_data_object.P1.apn[1]] = '\"';
				s_init_state = S_MODULE_INIT_CGDCONT1;
			}
			else if(g_at_request_res == ResultFail)
			{
				//获取APN参数
				memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));	
				for(int i = 0; i < Sys_data_object.P1.apn[1]; i++)
				{
					stringbuffer_temp[i] = Sys_data_object.P1.apn[2 + i];
				}	
				stringbuffer_temp[Sys_data_object.P1.apn[1]] = '\"';
				s_init_state = S_MODULE_INIT_CGDCONT1;
			}
        } 
        break;
		case S_MODULE_INIT_CGDCONT1:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGDCONT1, 1, stringbuffer_temp, Sys_data_object.P1.apn[1]+1);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CFUN1;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CFUN1;
			}
        }
        break;
		case S_MODULE_INIT_CGDCONT3:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGDCONT3, 1, stringbuffer_temp, Sys_data_object.P1.apn[1]+1);
            if(g_at_request_res == ResultOk)
			{
				s_init_state = S_MODULE_INIT_CFUN1;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_init_state = S_MODULE_INIT_CFUN1;
			}
        }
        break;
		case S_MODULE_INIT_CFUN1:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN1, 0, NULL,0);
            if(g_at_request_res == ResultOk)
			{	
				g_s_nbiot_task_flag = TASK_SUCCESS; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
			else if(g_at_request_res == ResultFail)
			{
				g_s_nbiot_task_flag = TASK_SUCCESS; //初始化任务失败
				s_init_state = S_MODULE_INIT_IDLE;
			}
        }
        break;	

        default:
        {
			g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败
			s_init_state = S_MODULE_INIT_IDLE;
        }
        break;
    }
}

//启动连接UDP
void UdpStartConnect(u8 udp_num)
{
	nbiot_temp_connect_type = udp_num;
	s_udp_connect_state = S_UDP_CONNECT_START;
}
/***************************************************************************
 * @fun_name     void UdpConnectMachine(void)
 * @brief        连接UDP状态机
 ***************************************************************************/
u8 UDP_send_num;
void UdpConnectMachine_MN316(void)
{
	switch (s_udp_connect_state)
    {
		case S_UDP_CONNECT_IDLE:
		{
			break;
		}
        case S_UDP_CONNECT_START:
        {			
			s_udp_connect_state = S_UDP_CONNECT_MIPOPEN;
        }
        break;
		case S_UDP_CONNECT_MIPOPEN:
        {
			if(nbiot_temp_connect_type == NBIOT_CONNECT_UDP1)
			{
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPOPEN_UDP1, 0, NULL,0);
			}
			else if(nbiot_temp_connect_type == NBIOT_CONNECT_UDP2)
			{
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPOPEN_UDP2, 0, NULL,0);
			}
            if(g_at_request_res == ResultOk)
			{
				udp_send_len=0;
				stringbuffer_temp[udp_send_len++] = NbiotGetSocketCode();
				stringbuffer_temp[udp_send_len++] = ',';
				stringbuffer_temp[udp_send_len++] = '0';
				stringbuffer_temp[udp_send_len++] = ',';
				stringbuffer_temp[udp_send_len++] = '1';
				stringbuffer_temp[udp_send_len++] = '\r';
				s_udp_connect_state = S_UDP_CONNECT_NSOCFG;
			}
			else if(g_at_request_res == ResultFail)
			{
				
				g_s_nbiot_task_flag = TASK_FAIL; //任务失败
				s_udp_connect_state = S_UDP_CONNECT_IDLE;
			}
        }
        break;
		case S_UDP_CONNECT_NSOCFG: 
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NSOCFG, 1, stringbuffer_temp,udp_send_len);
            if(g_at_request_res == ResultOk)
			{
                g_s_nbiot_task_flag = TASK_SUCCESS; //成功
				s_udp_connect_state = S_UDP_CONNECT_IDLE;
			}
			else if(g_at_request_res == ResultFail)
			{
				
				g_s_nbiot_task_flag = TASK_FAIL; //任务失败
				s_udp_connect_state = S_UDP_CONNECT_IDLE;
			}
		}
		break;
		default:
		{
			g_s_nbiot_task_flag = TASK_FAIL; 
			s_udp_connect_state = S_UDP_CONNECT_IDLE;
			break;
		}
	}
}
void UdpConnectMachine(void)
{
   UdpConnectMachine_MN316();
}
//
void StartUdpSendData(void)
{
	s_udp_send_state = S_UDP_SEND_START;
}
// 
void UdpSendDataMachine_ML302(void)
{
	unsigned char *nbiot_ip;
    u16 nbiot_port;
	switch (s_udp_send_state)
	{ 
		case S_UDP_SEND_IDLE:
		{
		}
		break;
		case S_UDP_SEND_START:
		{			
			udp_send_len = 0;
			NbiotClearMsg();
			memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));
			 //内容
			if(nbiot_temp_connect_type == NBIOT_CONNECT_UDP1)
			{
				nbiot_port = udp_port1;
				nbiot_ip = udp_ip1;
			}
			else if(nbiot_temp_connect_type == NBIOT_CONNECT_UDP2)
			{
				nbiot_port = udp_port2;
				nbiot_ip = udp_ip2;
			}
			// AT+NSOST=0,114.116.144.151,1000,3,333231,101
			stringbuffer_temp[udp_send_len++] = NbiotGetSocketCode();
			stringbuffer_temp[udp_send_len++] = ',';
			//IP 的存储仍然使用水表原来格式，不保存“.”号，使用时加入
			int i;
			for (i = 0; i < 4; i++)
			{
				if (nbiot_ip[i] < 10)
				{
					stringbuffer_temp[udp_send_len++] = nbiot_ip[i] + 0x30;
				}
				else if (nbiot_ip[i] < 100)
				{
					stringbuffer_temp[udp_send_len++] = (nbiot_ip[i] / 10) + 0x30;
					stringbuffer_temp[udp_send_len++] = (nbiot_ip[i] % 10) + 0x30;
				}
				else
				{
					stringbuffer_temp[udp_send_len++] = (nbiot_ip[i] / 100) + 0x30;
					stringbuffer_temp[udp_send_len++] = (nbiot_ip[i] / 10) % 10 + 0x30;
					stringbuffer_temp[udp_send_len++] = (nbiot_ip[i] % 10) + 0x30;
				}
				stringbuffer_temp[udp_send_len++] = '.';
			}
			udp_send_len--; //消除多余的点号
			stringbuffer_temp[udp_send_len++] = ',';
			stringbuffer_temp[udp_send_len++] = ((nbiot_port) / 10000) + 0x30;
			stringbuffer_temp[udp_send_len++] = (((nbiot_port) % 10000) / 1000) + 0x30;
			stringbuffer_temp[udp_send_len++] = (((nbiot_port) % 1000) / 100) + 0x30;
			stringbuffer_temp[udp_send_len++] = (((nbiot_port) % 100) / 10) + 0x30;
			stringbuffer_temp[udp_send_len++] = ((nbiot_port) % 10) + 0x30;
			stringbuffer_temp[udp_send_len++] = ',';
			//数据长度
			if (Nbiot_Send_Data.len < 10)
			{
				stringbuffer_temp[udp_send_len++] = Nbiot_Send_Data.len + 0x30;
			}
			else if (Nbiot_Send_Data.len < 100)
			{
				stringbuffer_temp[udp_send_len++] = (Nbiot_Send_Data.len / 10) + 0x30;
				stringbuffer_temp[udp_send_len++] = (Nbiot_Send_Data.len % 10) + 0x30;
			}
			else
			{
				stringbuffer_temp[udp_send_len++] = (Nbiot_Send_Data.len / 100) + 0x30;
				stringbuffer_temp[udp_send_len++] = (Nbiot_Send_Data.len / 10) % 10 + 0x30;
				stringbuffer_temp[udp_send_len++] = (Nbiot_Send_Data.len % 10) + 0x30;
			}
			stringbuffer_temp[udp_send_len++] = ',';
			//数据内容
//			for (i = 0; i < Nbiot_Send_Data.len; i++)//获取发送数据内容
//			{
//				stringbuffer_temp[udp_send_len++] = *(Nbiot_Send_Data.buf + i);//数据发送十六进制格式
//			}

            for (i = 0; i < Nbiot_Send_Data.len; i++)//获取发送数据内容
            {
                if ((*(Nbiot_Send_Data.buf + i) >> 4) >= 0x0A)
                {
                    stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x37;
                }
                else
                {
                    stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x30;
                }

                if ((*(Nbiot_Send_Data.buf + i) & 0x0F) >= 0x0A)
                {
                    stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x37;
                }
                else
                {
                    stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x30;
                }
            }
			if(++UDP_send_num == 0)
            {
                UDP_send_num = 1;
            }
			stringbuffer_temp[udp_send_len++] = ',';
			stringbuffer_temp[udp_send_len++] = '0'+(UDP_send_num%10);
			stringbuffer_temp[udp_send_len++] = '\r';
			s_udp_send_state = S_UDP_SEND_DATA;
		}
		break; 
		case S_UDP_SEND_DATA://发送数据
		{
			if(g_s_nbiot_send_type == SEND_TYPE_UDP1)
			{
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_UDPSEND1, 1, stringbuffer_temp, udp_send_len);
			}
			else if(g_s_nbiot_send_type == SEND_TYPE_UDP2)
			{
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_UDPSEND2, 1, stringbuffer_temp, udp_send_len);
			}
            if(g_at_request_res == ResultOk)
			{
				
                g_s_nbiot_task_flag = TASK_SUCCESS; //成功
				s_udp_send_state = S_UDP_SEND_IDLE;
			}
			else if(g_at_request_res == ResultFail)
			{
				
                g_s_nbiot_task_flag = TASK_FAIL; //失败
				s_udp_send_state = S_UDP_SEND_IDLE;
			}
		}
		break;
		default:
		{
			g_s_nbiot_task_flag = TASK_FAIL; //失败
			s_udp_send_state = S_UDP_SEND_IDLE;
		}
		break;
	}
}
void UdpSendDataMachine(void)
{
	UdpSendDataMachine_ML302();
} 

//读取数据
void Tcp_UdpReadDataMachine(void)
{	
    switch (s_read_data_state)
    {
        case S_READ_DATA_IDLE:
        {
            NbiotClearMsg();
			memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));
			tcp_send_len=0;
			stringbuffer_temp[tcp_send_len++] = NbiotGetSocketCode();
			stringbuffer_temp[tcp_send_len++] = ',';
			stringbuffer_temp[tcp_send_len++] = '5';
			stringbuffer_temp[tcp_send_len++] = '1';
			stringbuffer_temp[tcp_send_len++] = '2';
			stringbuffer_temp[tcp_send_len++] = '\r';
			s_read_data_state = S_READ_DATA_START;
        }
        break;

        case S_READ_DATA_START:
        {
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_READ_DATA, 1, stringbuffer_temp, tcp_send_len);
				if(g_at_request_res == ResultOk)
				{
					s_read_data_state = S_READ_DATA_IDLE;
					g_s_nbiot_task_flag = TASK_SUCCESS; //成功
				}
				else if(g_at_request_res == ResultFail)
				{
					g_s_nbiot_task_flag = TASK_FAIL; //失败
					s_read_data_state = S_READ_DATA_IDLE;
				}
        }
        break;
        default:
        {
            s_read_data_state = S_READ_DATA_IDLE;
        }
        break;
    }	
}

/***************************************************************************
 * @fun_name     void CoapConnectMachine_MN316_ONENET()
 * @brief        MN316连接移动OneNet平台状态机
 ***************************************************************************/
#define AT_COMMAND_SEND_INTERVAL_TIME  500

static void CoapStartConnect(void)
{
	s_coap_connect_state = S_COAP_CONNECT_START;
}

static void CoapConnectMachine_MN316_CTWing(void)
{
	static int ip_len=0;
    switch (s_coap_connect_state)
    {
		case S_COAP_CONNECT_IDLE:
		{
			break;
		}
		case S_COAP_CONNECT_START: //任务开始
		{
			memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));
			ip_len=0;
			//IP 的存储仍然使用水表原来格式，不保存“.”号，使用时加入
			int i;
			for (i = 0; i < 4; i++)
			{
				if (coap_ip[i] < 10)
				{
					stringbuffer_temp[ip_len++] = coap_ip[i] + 0x30;
				}
				else if (coap_ip[i] < 100)
				{
					stringbuffer_temp[ip_len++] = (coap_ip[i] / 10) + 0x30;
					stringbuffer_temp[ip_len++] = (coap_ip[i] % 10) + 0x30;
				}
				else
				{
					stringbuffer_temp[ip_len++] = (coap_ip[i] / 100) + 0x30;
					stringbuffer_temp[ip_len++] = (coap_ip[i] / 10) % 10 + 0x30;
					stringbuffer_temp[ip_len++] = (coap_ip[i] % 10) + 0x30;
				}
				stringbuffer_temp[ip_len++] = '.';
			}
			ip_len--; //消除多余的点号
			stringbuffer_temp[ip_len++] = ',';
			stringbuffer_temp[ip_len++] = ((coap_port) / 10000) + 0x30;
			stringbuffer_temp[ip_len++] = (((coap_port) % 10000) / 1000) + 0x30;
			stringbuffer_temp[ip_len++] = (((coap_port) % 1000) / 100) + 0x30;
			stringbuffer_temp[ip_len++] = (((coap_port) % 100) / 10) + 0x30;
			stringbuffer_temp[ip_len++] = ((coap_port) % 10) + 0x30;
			stringbuffer_temp[ip_len++] = '\r';
			
			s_coap_connect_state = S_CTWING_MCWCREATE;
		}
		break;
    case S_CTWING_MCWCREATE://配置登录信息AT+MCWCREATE=221.229.214.202,5683
    {
		g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MCWCREATE, 1, stringbuffer_temp,ip_len);
		if(g_at_request_res == ResultOk)
		{
			s_coap_connect_state = S_CTWING_MCWOPEN;
		}
		else if(g_at_request_res == ResultFail)
		{
			
			g_s_nbiot_task_flag = TASK_FAIL; //任务失败
			s_coap_connect_state = S_COAP_CONNECT_IDLE;
		}
    }
    break;

    case S_CTWING_MCWOPEN://模组将注册至 CTWing 平台。 AT+MCWOPEN=1,300//自动 update，lifetime 300 秒
    {
        g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MCWOPEN, 0, NULL,0);
		if(g_at_request_res == ResultOk)
		{
			
			g_s_nbiot_task_flag = TASK_SUCCESS; //成功
			s_coap_connect_state = S_COAP_CONNECT_IDLE;
		}
		else if(g_at_request_res == ResultFail)
		{
			
			g_s_nbiot_task_flag = TASK_FAIL; //任务失败
			s_coap_connect_state = S_COAP_CONNECT_IDLE;
		}
    }
    break;

    default:
    {
        s_coap_connect_state = S_COAP_CONNECT_IDLE; //状态机回归初始状态
    }
    break;
    }
}
void CoapConnectMachine(void)
{
    CoapConnectMachine_MN316_CTWing();
}


void StartCoapSendData(void)
{
    s_coap_send_state = S_COAP_SEND_START;
} 
/***************************************************************************
* @fun_name     void CoapSendDataMachine_BC25_ONENET()
* @brief        BC25向移动ONENET平台发送数据状态机
***************************************************************************/
void CoapSendDataMachine_MN316_CTWing(void)
{
    switch (s_coap_send_state)
    {
		case S_COAP_SEND_IDLE:
		{
		}
		break;
		case S_COAP_SEND_START:
		{
			tcp_send_len  = 0;
			NbiotClearMsg();
			memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));
			memset(tcp_send_len_buf,0,sizeof(tcp_send_len_buf));
			//发送数据长度
			if (Nbiot_Send_Data.len < 10)
			{
				tcp_send_len_buf[0] = Nbiot_Send_Data.len + 0x30;
				tcp_send_len_buf_len = 1;
			}
			else if (Nbiot_Send_Data.len < 100)
			{
				tcp_send_len_buf[0] = (Nbiot_Send_Data.len / 10) + 0x30;
				tcp_send_len_buf[1] = (Nbiot_Send_Data.len % 10) + 0x30;
				tcp_send_len_buf_len = 2;
			}
			else
			{
				tcp_send_len_buf[0] = (Nbiot_Send_Data.len / 100) + 0x30;
				tcp_send_len_buf[1] = (Nbiot_Send_Data.len / 10) % 10 + 0x30;
				tcp_send_len_buf[2] = (Nbiot_Send_Data.len % 10) + 0x30;
				tcp_send_len_buf_len = 3;
			}
			//填充发送数据长度
			for (int i = 0; i < tcp_send_len_buf_len; i++)
			{
				stringbuffer_temp[tcp_send_len++] = tcp_send_len_buf[i];
			}
			stringbuffer_temp[tcp_send_len++] = ',';
			//填充发送数据内容
			for (int i = 0; i < Nbiot_Send_Data.len; i++)
			{
				if ((*(Nbiot_Send_Data.buf + i) >> 4) >= 0x0A)
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x37;
				}
				else
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x30;
				}
				if ((*(Nbiot_Send_Data.buf + i) & 0x0F) >= 0x0A)
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x37;
				}
				else
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x30;
				}
			}	
			stringbuffer_temp[tcp_send_len++] = ',';
            if(1)
            {
				stringbuffer_temp[tcp_send_len++] = '1';
				stringbuffer_temp[tcp_send_len++] = '\r';
				s_coap_send_state = S_COAP_SEND_DATA1;
            }
            else
            {
				stringbuffer_temp[tcp_send_len++] = '0';
				stringbuffer_temp[tcp_send_len++] = '\r';
				s_coap_send_state = S_COAP_SEND_DATA0;
            }
		}
		break;
		case S_COAP_SEND_DATA0:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MCWSEND0, 1, stringbuffer_temp, tcp_send_len);
			if(g_at_request_res == ResultOk)
			{
				*Nbiot_Send_Data.state = NBIOT_SUCCESS;
				g_s_nbiot_task_flag = TASK_SUCCESS; 
				s_coap_send_state = S_COAP_SEND_IDLE;
			}
			else if(g_at_request_res == ResultFail) 
			{
				*Nbiot_Send_Data.state = NBIOT_ERROR;
				g_s_nbiot_task_flag = TASK_FAIL; //任务失败
				s_coap_send_state = S_COAP_SEND_IDLE;
			}
		}
		break;
		case S_COAP_SEND_DATA1:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MCWSEND1, 1, stringbuffer_temp, tcp_send_len);
			if(g_at_request_res == ResultOk)
			{
				*Nbiot_Send_Data.state = NBIOT_SUCCESS;
				g_s_nbiot_task_flag = TASK_SUCCESS; 
				s_coap_send_state = S_COAP_SEND_IDLE;
			}
			else if(g_at_request_res == ResultFail)
			{
				*Nbiot_Send_Data.state = NBIOT_ERROR;
				g_s_nbiot_task_flag = TASK_FAIL; //任务失败
				s_coap_send_state = S_COAP_SEND_IDLE;
			}
		}
		break;

		default:
		{
			s_coap_send_state = S_COAP_SEND_IDLE;
		}
		break;
    }
}


void CoapSendDataMachine(void)
{
    CoapSendDataMachine_MN316_CTWing();
}

//OnenetConnectMachine
void OneNetStartConnect(void)
{
	s_onenet_connect_state = S_ONENET_CONNECT_START;
}
	
static void OnenetConnectMachine(void)
{
    static int ip_len=0;

	switch(s_onenet_connect_state)
	{
		case S_ONENET_CONNECT_IDLE:
		{
		
		}
		break;
		case S_ONENET_CONNECT_START:
		{
			memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));
			ip_len=0;
			//IP 的存储仍然使用水表原来格式，不保存“.”号，使用时加入
			int i;
			for (i = 0; i < 4; i++)
			{
				if (coap_ip[i] < 10)
				{
					stringbuffer_temp[ip_len++] = coap_ip[i] + 0x30;
				}
				else if (coap_ip[i] < 100)
				{
					stringbuffer_temp[ip_len++] = (coap_ip[i] / 10) + 0x30;
					stringbuffer_temp[ip_len++] = (coap_ip[i] % 10) + 0x30;
				}
				else
				{
					stringbuffer_temp[ip_len++] = (coap_ip[i] / 100) + 0x30;
					stringbuffer_temp[ip_len++] = (coap_ip[i] / 10) % 10 + 0x30;
					stringbuffer_temp[ip_len++] = (coap_ip[i] % 10) + 0x30;
				}
				stringbuffer_temp[ip_len++] = '.';
			}
			ip_len--; //消除多余的点号
			stringbuffer_temp[ip_len++] = '\"';
			stringbuffer_temp[ip_len++] = ',';
			stringbuffer_temp[ip_len++] = '0';
			stringbuffer_temp[ip_len++] = '\r';
			s_onenet_connect_state = S_ONENET_MIPLCREATEEX;
		}
		break;
		case S_ONENET_MIPLCREATEEX:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLCREATEEX, 1, stringbuffer_temp, ip_len);
            if(g_at_request_res == ResultOk)
			{
				s_onenet_connect_state = S_ONENET_MIPLADDOBJ;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_onenet_connect_state = S_ONENET_MIPLADDOBJ;
			}
		}
		break;
		case S_ONENET_MIPLADDOBJ:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLADDOBJ, 0, NULL, 0);
            if(g_at_request_res == ResultOk)
			{
				s_onenet_connect_state = S_ONENET_MIPLDISCOVERRSP;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_onenet_connect_state = S_ONENET_MIPLDISCOVERRSP;
			}
		}
		break;
		case S_ONENET_MIPLDISCOVERRSP:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLDISCOVERRSP, 0, NULL, 0);
            if(g_at_request_res == ResultOk)
			{
				s_onenet_connect_state = S_ONENET_MIPLOPEN;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_onenet_connect_state = S_ONENET_MIPLOPEN;
			}
		}
		break;
		case S_ONENET_MIPLOPEN:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLOPEN, 0, NULL, 0);
            if(g_at_request_res == ResultOk)
			{
				s_onenet_connect_state = S_ONENET_MIPLUPDATE;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_onenet_connect_state = S_ONENET_MIPLUPDATE;
			}
		}
		break;
		case S_ONENET_MIPLUPDATE:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLUPDATE, 0, NULL, 0);
			if(g_at_request_res == ResultOk)
			{
				*Nbiot_Send_Data.state = NBIOT_SUCCESS;
				g_s_nbiot_task_flag = TASK_SUCCESS; //成功
				s_onenet_connect_state = S_ONENET_CONNECT_IDLE;
			}
			else if(g_at_request_res == ResultFail)
			{
				*Nbiot_Send_Data.state = NBIOT_ERROR;
				g_s_nbiot_task_flag = TASK_FAIL; //任务失败
				s_onenet_connect_state = S_ONENET_CONNECT_IDLE;
			}
		}
		break;
		default:
		{
			s_onenet_connect_state = S_ONENET_CONNECT_IDLE; 
		}
		break;
	}
}

void StartOnenetSendData(void)
{
	s_onenet_send_state = S_ONENET_SEND_START;
}

void OnenetSendDataMachine(void)
{
    switch (s_onenet_send_state)
    {
		case S_ONENET_SEND_IDLE:
		{
		}
		break;
		case S_ONENET_SEND_START: 
		{
			tcp_send_len  = 0;
			NbiotClearMsg();
			memset(stringbuffer_temp,0,sizeof(stringbuffer_temp));
			//发送数据长度
			if (Nbiot_Send_Data.len < 10)
			{
				stringbuffer_temp[tcp_send_len++] = Nbiot_Send_Data.len + 0x30;
			}
			else if (Nbiot_Send_Data.len < 100)
			{
				stringbuffer_temp[tcp_send_len++] = (Nbiot_Send_Data.len / 10) + 0x30;
				stringbuffer_temp[tcp_send_len++] = (Nbiot_Send_Data.len % 10) + 0x30;
			}
			else
			{
				stringbuffer_temp[tcp_send_len++] = (Nbiot_Send_Data.len / 100) + 0x30;
				stringbuffer_temp[tcp_send_len++] = (Nbiot_Send_Data.len / 10) % 10 + 0x30;
				stringbuffer_temp[tcp_send_len++] = (Nbiot_Send_Data.len % 10) + 0x30;
			}
			stringbuffer_temp[tcp_send_len++] = ',';
			//填充发送数据内容
			for (int i = 0; i < Nbiot_Send_Data.len; i++)
			{
				if ((*(Nbiot_Send_Data.buf + i) >> 4) >= 0x0A)
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x37;
				}
				else
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x30;
				}
				if ((*(Nbiot_Send_Data.buf + i) & 0x0F) >= 0x0A)
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x37;
				}
				else
				{
					stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x30;
				}
			}	
			stringbuffer_temp[tcp_send_len++] = ',';
			stringbuffer_temp[tcp_send_len++] = '0';
			stringbuffer_temp[tcp_send_len++] = ',';
			stringbuffer_temp[tcp_send_len++] = '0';
			stringbuffer_temp[tcp_send_len++] = ',';
			stringbuffer_temp[tcp_send_len++] = '7';
			s_onenet_send_state = S_ONENET_SEND_DATA0;
		}
		break;
		case S_ONENET_SEND_DATA0:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLNOTIFY, 1, stringbuffer_temp, tcp_send_len);
			if(g_at_request_res == ResultOk)
			{
				*Nbiot_Send_Data.state = NBIOT_SUCCESS;
				g_s_nbiot_task_flag = TASK_SUCCESS; 
				s_coap_send_state = S_COAP_SEND_IDLE;
			}
			else if(g_at_request_res == ResultFail) 
			{
				*Nbiot_Send_Data.state = NBIOT_ERROR;
				g_s_nbiot_task_flag = TASK_FAIL; //任务失败
				s_coap_send_state = S_COAP_SEND_IDLE;
			}
		}
		break;

		default:
		{
			s_coap_send_state = S_COAP_SEND_IDLE;
		}
		break;
    }
}
/***************************************************************************
 * @fun_name    static void NbiotPowerOffMachine()
 * @brief        关机状态机
 ***************************************************************************/
void NbiotPowerOffMachine(void) //先注销网络然后断电关机
{
    switch (s_power_off_state)
    {
		case S_PWOFF_IDLE:
		{
		}
		break;
		case S_PWOFF_START:
		{
			if (Nbiot_Para.net_state == NB_ON_LINE)
			{
				if(Nbiot_Para.Telecom == SIM_CARD_TELECOM)//电信卡
				{
					s_power_off_state = S_PWOFF_MCWCLOSE;
				}
				else
				{
					s_power_off_state = S_PWOFF_MIPLCLOSE;
				}
			}
			else
			{
				s_power_off_state = S_PWOFF_CFUN0;
			}
			
		}
		break;
		//->电信
		case S_PWOFF_MCWCLOSE:
		{
			if(ConncetIfOnline(NBIOT_CONNECT_COAP) == TRUE)
			{
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MCWCLOSE, 0, NULL,0); 
				if(g_at_request_res == ResultOk)
				{
					s_power_off_state = S_PWOFF_MCWDELETE;
				}
				else if(g_at_request_res == ResultFail)
				{
					s_power_off_state = S_PWOFF_MCWDELETE;
				}
			}
			else
			{
				s_power_off_state = S_PWOFF_UDPCLOSE;
			}
		}
		break;
		//->电信
		case S_PWOFF_MCWDELETE:
		{
			if(ConncetIfOnline(NBIOT_CONNECT_COAP) == TRUE)
			{
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MCWDELETE, 0, NULL,0); 
				if(g_at_request_res == ResultOk)
				{
					s_power_off_state = S_PWOFF_UDPCLOSE;
				}
				else if(g_at_request_res == ResultFail)
				{
					s_power_off_state = S_PWOFF_UDPCLOSE;
				}
			}
		}
		break;
		//->移动
        case S_PWOFF_MIPLCLOSE:
        {
			if(ConncetIfOnline(NBIOT_CONNECT_COAP) == TRUE)
			{
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLCLOSE, 0, NULL,0); 
				if(g_at_request_res == ResultOk)
				{
					s_power_off_state = S_PWOFF_MIPLDELOBJ;
				}
				else if(g_at_request_res == ResultFail)
				{
					s_power_off_state = S_PWOFF_MIPLDELOBJ;
				}
			}
			else
			{
				s_power_off_state = S_PWOFF_UDPCLOSE;
			}
        }
        break;
		//->移动
        case S_PWOFF_MIPLDELOBJ:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLDELOBJ, 0, NULL,0); 
			if(g_at_request_res == ResultOk)
			{
				s_power_off_state = S_PWOFF_MIPLDELETE;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_power_off_state = S_PWOFF_MIPLDELETE;
			}
        }
        break;
		//->移动
        case S_PWOFF_MIPLDELETE:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPLDELETE, 0, NULL,0); 
			if(g_at_request_res == ResultOk)
			{
				s_power_off_state = S_PWOFF_UDPCLOSE;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_power_off_state = S_PWOFF_UDPCLOSE;
			}
        }
        break;
		
		case S_PWOFF_UDPCLOSE: 
        {
			if(ConncetIfOnline(NBIOT_CONNECT_UDP1) == TRUE)
			{
				stringbuffer_temp[0] = NbiotGetSocketCode();
				g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NSOCL, 1, stringbuffer_temp,1);
				if(g_at_request_res == ResultOk)
				{
					s_power_off_state = S_PWOFF_CPOF;
				}
				else if(g_at_request_res == ResultFail)
				{
					s_power_off_state = S_PWOFF_CPOF;
				}
			}
			else
			{
				s_power_off_state = S_PWOFF_CPOF;
			}
        }
        break;
		case S_PWOFF_CPOF:
        {
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CPOF, 0, NULL,0); 
			if(g_at_request_res == ResultOk)
			{
				s_power_off_state = S_PWOFF_PW_DOWN;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_power_off_state = S_PWOFF_PW_DOWN;
			}
        }
        break; 
		//->清频点
		case S_PWOFF_CFUN0:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN0, 0, NULL,0); 
			if(g_at_request_res == ResultOk)
			{
				s_power_off_state = S_PWOFF_NCSEARFCN;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_power_off_state = S_PWOFF_NCSEARFCN;
			}
		}
		break;
		//->清频点
		case S_PWOFF_NCSEARFCN:
		{
			g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_NCSEARFCN, 0, NULL,0); 
			if(g_at_request_res == ResultOk)
			{
				s_power_off_state = S_PWOFF_PW_DOWN;
			}
			else if(g_at_request_res == ResultFail)
			{
				s_power_off_state = S_PWOFF_PW_DOWN;
			}
		}
		break;
		
        case S_PWOFF_PW_DOWN:
        {
			if (!check_timer_1s())
			{
				NB_Power_Disable(); //切断电源
				set_timer_1s(1);
				s_power_off_state = S_PWOFF_PW_DOWN_WAIT;
				Nbiot_Para.net_state = NB_OFF_LINE;
				Nbiot_Para.coap_state = CONNECT_OFF_LINE;
				Nbiot_Para.udp1_state = CONNECT_OFF_LINE;
				Nbiot_Para.udp2_state = CONNECT_OFF_LINE;
			}
        }
        break;

        case S_PWOFF_PW_DOWN_WAIT:
        {
            if (!check_timer_1s())
            {
                NbiotPreSleep();
                g_s_nbiot_task_flag = TASK_SUCCESS;
                s_power_off_state = S_PWOFF_IDLE;
            }
        }
        break;

        default:
        {
            s_power_off_state = S_PWOFF_IDLE;
        }
        break;
    }
}

/***************************************************************************
 * @fun_name    定时器资源
 * @brief       该内部接口主要为了方便记忆及使用
 ***************************************************************************/
void set_timer_1s(u16 time)
{
    Set100msTimer(TIMER_100MS_NBIOT, time * 10);
}

u16 check_timer_1s(void)
{
    return Check100msTimer(TIMER_100MS_NBIOT);
}

void set_timer_1ms(u16 time)
{
    Set5msTimer(TIMER_5MS_NBIOT, time / 5);
}

u16 check_timer_1ms(void)
{
    return Check5msTimer(TIMER_5MS_NBIOT);
}

/***************************************************************************
 * @fun_name     void StartPowerOffTask()
 * @brief        关机接口
 ***************************************************************************/
void StartPowerOffTask(void)
{	
    g_s_nbiot_task_flag = TASK_INIT;
    g_s_nbiot_main_state = S_NBIOT_MAIN_POWER_OFF;
	s_power_off_state = S_PWOFF_START;	
}

//NB强制关机
void NbForcePowerOff(void)
{
    NB_Power_Disable();
	Nbiot_Para.net_state = NB_OFF_LINE;
	Nbiot_Para.coap_state = CONNECT_OFF_LINE;
	Nbiot_Para.udp1_state = CONNECT_OFF_LINE;
	Nbiot_Para.udp2_state = CONNECT_OFF_LINE;
    g_s_nbiot_task_flag = TASK_INIT;
    g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE;
	s_at_requeset_state = AT_REQUEST_IDLE;
}


UNION_4U8TOU32 net_state_data;
u32 sys_get_net_state(void)
{
	s16 s_temp_data=0;
	if(g_s_nbiot_main_state ==S_NBIOT_MAIN_POWER_INIT)
	{
		net_state_data.data_buf[0] = 1;
		net_state_data.data_buf[1] = s_init_state;
		//net_state_buf[2]CEREG
		//net_state_buf[3]cgatt
	}
	else if(g_s_nbiot_main_state ==  S_NBIOT_MAIN_COAP_OPEN)
	{
		net_state_data.data_buf[0] = 2;
		net_state_data.data_buf[1] = s_coap_connect_state;
	}
	else if(If_NB_Poweron()==FALSE)
	{
		net_state_data.data_buf[0] = 3;
		//rsrp
		NbiotGetRSRP(&s_temp_data);
		net_state_data.data_buf[1] = -(s_temp_data/10);
		//SNR
		NbiotGetSNR(&s_temp_data);
		if(s_temp_data<0)
		{
			net_state_data.data_buf[2] = (-s_temp_data)|0x80;
		}
		else
		{
			net_state_data.data_buf[2] = s_temp_data/10;
		}
		//CSQ
		 NbiotGetCSQ(&net_state_data.data_buf[3]); 
	}
	return net_state_data.datas;
}

void sys_set_net_state(u8 state, u8 data)
{
	net_state_data.data_buf[state] = data;
}
TYP_PSM_STATE getPsmState(void)
{
    return PSM_STATE_OUT;//不进入PSM模式
}	
#ifdef	__cplusplus
}
#endif

#endif
