#include "sys_config.h"
#if PRODUCT_WHYW
#include "sys_processor.h"
#include "UWater_eeprom_driver.h"
#include "UWater_timer1us_driver.h"
#include "UWater_rtcc_app.h"
#include "UWater_power_app.h"
#include "UWater_gp22_app.h"
#include "UWater_pt_app.h" 
#include "UWater_DataTools_App.h"
#include "UWater_QZ_Store_App.h"
#include "UWater_frame_func_ReplyWuHanYW.h"

/*------------------------------ Variable Define ------------------------------------*/
static u8 s_eep_complete_WHYW=0;
static u8 task_complete_WHYW = PTL_PACK_BUSY;   //规约处理完成状态
static u8 g_frame_temp_buf_WHYW[UP_BUF_SIZE];	//数据部分缓冲区
static u16 g_frame_temp_len_WHYW=0;//数据部分的长度

static STRUCT_FRAME_WHYW frame_struct_WHYW; //规约信息结构体
static u8 *new_message_data_rev_WHYW;  //接收数据指针
static u8 up_deal_stat_WHYW = UP_DEAL_S0;//规约处理状态机
static DateTime whyw_protl_rtcc_time;
static u8 upload_count_flag=0;
//设置上报时间相关变量
static u32 temp_upload_delay_time;
static u32 temp_upload_set_time;
static u8 temp_upload_hour_minute_time;
/*******主动上传周期数据存储和读取相关变量*************************************/
static TYP_STATE_WHYW step_circle_data_store=WHYW_STATE_S0;
static U32_To_Float  temp_float_data;
static u32 temp_CircleData;//周期数据存储缓存
static u16 uTemp_ee_addr;//计算存储地址变量
static u8 uTemp_read_len;//计算存储数据长度变量
static UNION_2U8TOU16 u_circle_store_index_w;//周期数据存储的位置
static UNION_2U8TOU16 u_circle_store_index_r;//周期数据读取的位置
static u8 upload_data_count;//本帧记录条数
static u16 upload_packet_count;//本次上报总帧数
static u16 upload_packet_code;//本帧编号
static u8 upload_packet_data_count;//本帧记录条数
static u8 upload_circle_buf[UPLOAD_CIRCLE_MAX_LEN];//EE读取周期记录的缓存
static DateTime upload_circle_rtcc_start;//第一条数据的起始时间
static DateTime upload_circle_rtcc_end;//上报结束时间
//static DateTime store_circle_rtcc_end;//周期数据存储的最后一条记录的时间
static UNION_4U8TOU32  temp_bcd_CircleData;//上报首条数据时间

static WHYW_UNION_EE_STORE whyw_ee;
/********主动上传组帧相关变量************************************************/
static u8 upload_serial_num_sy=0;
static u8 temp_upload_step=0;
static u8 upload_frame_retry_times = 0;
static TYP_STATE_WHYW upload_frame_stat_whyw=WHYW_STATE_S0;
static u8 task_upload_complete_whyw = PTL_PACK_BUSY; //规约处理完成状态
static u8 g_upload_temp_buf_WHYW[300];	//数据部分缓冲区,实际用到244
static u16 g_upload_temp_len_WHYW=0;
static STRUCT_FRAME_WHYW upload_struct_WHYW; //规约信息结构体
//上报数据组帧变量
static UNION_2U8TOU16 temp_data_u16;
static u8 temp_data_u8;
static s16 s_temp_data=0;
static MET_STATE temp_state;
static u8 temp_buf1[16];
static u8 temp_buf2[16];
static u16 temp_data=0;
/***************************************************************
read_oline_time_ack
读水表在线延时等待的时间
说明:水表在线延时时间单位为秒，1 字节 HEX 码，14H 表示延时时间为 20 秒。
****************************************************************/
static void read_oline_time_ack(void)
{
	g_frame_temp_len_WHYW=0;
	g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] =  whyw_ee.Data.ee_nb_online_keep_time;
    up_deal_stat_WHYW  = UP_DEAL_S0;
    task_complete_WHYW = PTL_PACK_SUCCESS;
}

/***************************************************************
read_meter_time_ack
读水表实时时间
说明:日期、时间数据为 7 字节 BCD 码。
****************************************************************/
static void read_meter_time_ack(void)
{
	DateTime tempRtccTime;
    RtccGetDateTime(&tempRtccTime); //获取当前时间
	
	g_frame_temp_len_WHYW=0;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = tempRtccTime.s.second;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = tempRtccTime.s.minute;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = tempRtccTime.s.hour;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = tempRtccTime.s.day;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = tempRtccTime.s.month;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = tempRtccTime.s.year;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = 0x20;
	
    up_deal_stat_WHYW  = UP_DEAL_S0;
    task_complete_WHYW = PTL_PACK_SUCCESS;
}

/***************************************************************
read_upload_time
读水表自动上传数据的时间参数
****************************************************************/
static void read_upload_time(void)
{
	u8 temp_buf[64];
	u8 temp_index;
	DateTime tempDateTime;
	g_frame_temp_len_WHYW = 0;
	SystemGetUploadTime(&tempDateTime);//获取上报时间
	for (int i = 0; i < 48; i++)
    {
      temp_buf[i] = 0xFF;//清为各个小时都不上传
    }
	temp_index = BCD2HEX(tempDateTime.s.hour)*2;
	temp_buf[temp_index] = BCD2HEX(tempDateTime.s.minute);
    for (int i = 0; i < 48; i++)
    {
      g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = temp_buf[i];
    }	
    up_deal_stat_WHYW  = UP_DEAL_S0;
    task_complete_WHYW = PTL_PACK_SUCCESS;
}
/***************************************************************
read_interval_time_ack
读取水表数据采集间隔时间参数

说明:水表采集数据间隔时间值只能为 0x01、0x05、0x0A、0x0F、0x14、0x1E、0x3C 这 7 种
数据值(1 分钟、5 分钟、10 分钟、15 分钟、20 分钟、30 分钟、60 分钟)间隔时间点进行采
样保存数据。且采集数据时间点的分钟值必须是以整点为起始点再累加采集间隔参数的倍数
而获得的分钟值。
****************************************************************/
static void read_interval_time_ack(void)
{
	g_frame_temp_len_WHYW = 0;
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = whyw_ee.Data.ee_nb_acq_interval;

    up_deal_stat_WHYW  = UP_DEAL_S0;
    task_complete_WHYW = PTL_PACK_SUCCESS;
}
/***************************************************************
read_battery_ack
读取电池电压相关参数

说明:电压门限值为 2 字节 BCD 码，低位字节在前，含两位小数，如:35H、06H 表示电压
门限值为 6.35V。
****************************************************************/
static void read_battery_ack(void)
{
	g_frame_temp_len_WHYW = 0;
	//低电压报警值
	g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = whyw_ee.Data.ee_battery_pra[0];
	g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = whyw_ee.Data.ee_battery_pra[1];
	g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = whyw_ee.Data.ee_battery_pra[2];
	g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = whyw_ee.Data.ee_battery_pra[3];

    up_deal_stat_WHYW  = UP_DEAL_S0;
    task_complete_WHYW = PTL_PACK_SUCCESS;
}

/***************************************************************
read_nb_para_ack
读水表 NB 网络参数

IP 地址在网络参数通信帧中需要分别转换成 16 进制后再按从左到右的顺序发送，如 IP 地址为：
110.25.38.202，则通信帧中数据及顺序为：6EH、19H、26H、CAH。
端口地址在网络参数通信帧中需要转换成 16 进制后再按低位字节在前的顺序发送，如端口地址为：
5005，则通信帧中数据及顺序为：8DH、13H。
****************************************************************/
static void read_nb_para_ack(void)
{
	g_frame_temp_len_WHYW = 0;
	for (int i = 0; i < 4; i++)
	{
	   g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = Sys_data_object.P2.server_ip[i];
	}
	g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = Sys_data_object.P2.server_port.data_buf[0];
    g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = Sys_data_object.P2.server_port.data_buf[1];
	for(int i=6;i<0x38;i++)//其他网络参数不用
	{
		g_frame_temp_buf_WHYW[g_frame_temp_len_WHYW++] = 0x30;
	}			
	up_deal_stat_WHYW  = UP_DEAL_S0;
	task_complete_WHYW = PTL_PACK_SUCCESS;
}


/***************************************************************
write_online_time_ack
写水表在线延时等待的时间参数//68 10 03 00 08 22 20 33 78 04 04 00 81 11 22 0F 3B 16
说明:该通讯帧是给水表内部的实时时钟进行对时，水表实时时间数据格式与前面的相同
****************************************************************/
static void write_online_time_ack(void)
{
    switch(up_deal_stat_WHYW)
    {
        case UP_DEAL_S0:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM
            {
				g_frame_temp_len_WHYW = 0;
				if(*new_message_data_rev_WHYW > 30)
				{
					whyw_ee.Data.ee_nb_online_keep_time = 30;
				}
				else
				{
					whyw_ee.Data.ee_nb_online_keep_time = *new_message_data_rev_WHYW++;
				}
				EepWrite(&whyw_ee.Data.ee_nb_online_keep_time, EEP_ADDR_WHYW_NB_ONLINE_KEEP, 1, &s_eep_complete_WHYW);//更新EE数据
                up_deal_stat_WHYW  = UP_DEAL_S1;
            }
        }
        break;

        case UP_DEAL_S1:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM完成
            {
				up_deal_stat_WHYW  = UP_DEAL_S0;
				task_complete_WHYW = PTL_PACK_SUCCESS;
            }
        }
        break;

        default:
        {
            up_deal_stat_WHYW  = UP_DEAL_S0;
            task_complete_WHYW = PTL_PACK_FAIL;
        }
        break;
    }
}

/***************************************************************
write_upload_time_ack
写水表自动上传数据的时间参数
说明:该通讯帧为设置水表上线传送计量信息数据的时间点参数，其数据格式意义与前面相关
通讯帧中所描叙的一致。
68 10 02 00 08 22 20 33 78 
44 //ctr
33 00 
81 04 
39 //ser
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF 0A FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF //设置1点10分
7F 16
****************************************************************/
static void write_upload_time_ack(void)
{
    switch(up_deal_stat_WHYW)
    {
        case UP_DEAL_S0:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM
            {
				g_frame_temp_len_WHYW = 0;
				
                temp_upload_delay_time = (u32)((Sys_data_object.P1.met_addr[1] & 0x0F)) * 100;
				temp_upload_delay_time += (Sys_data_object.P1.met_addr[0] >> 4) * 10 + (Sys_data_object.P1.met_addr[0] & 0x0F);	//表地址后三位，0-999
				temp_upload_delay_time *= Sys_data_object.P1.report_step_len.datas;	//乘离散系数
				for(int i=0;i<48;i++)
				{
					temp_upload_hour_minute_time = *new_message_data_rev_WHYW++;
					if(0xFF != temp_upload_hour_minute_time)
					{
						temp_upload_set_time = (i/2)*3600+temp_upload_hour_minute_time*60;
						if(temp_upload_set_time>temp_upload_delay_time)
						{
							temp_upload_set_time -= temp_upload_delay_time;
						}
						else
						{
							temp_upload_set_time = 0;
						}
						Sys_data_object.P1.Time_upload_2006.s.type = UPLOAD_MODE_DAY;
						Sys_data_object.P1.Time_upload_2006.s.hour = HEX2BCD(temp_upload_set_time/3600);
						Sys_data_object.P1.Time_upload_2006.s.minute = HEX2BCD((temp_upload_set_time%3600)/60);
						EepWrite(&Sys_data_object.P1.Time_upload_2006.buf[0], FRAME_NBIot_FREQVAL, 5, &s_eep_complete_WHYW);//更新EE数据
						Frame_Para_Init();
						break;
					}
				}
                up_deal_stat_WHYW  = UP_DEAL_S1;
            }
        }
        break;

        case UP_DEAL_S1:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM完成
            {
				up_deal_stat_WHYW  = UP_DEAL_S0;
				task_complete_WHYW = PTL_PACK_SUCCESS;
            }
        }
        break;

        default:
        {
            up_deal_stat_WHYW  = UP_DEAL_S0;
            task_complete_WHYW = PTL_PACK_FAIL;
        }
        break;
    }
}

/***************************************************************
write_interval_time_ack
写水表数据采集间隔时间参数
说明:该通讯帧为设置水表数据采集间隔时间参数，其数据格式意义与前面相关通讯帧中所描
叙的一致。
****************************************************************/
static void write_interval_time_ack(void)
{
    switch(up_deal_stat_WHYW)
    {
        case UP_DEAL_S0:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM
            {
				g_frame_temp_len_WHYW = 0;
                whyw_ee.Data.ee_nb_acq_interval = *new_message_data_rev_WHYW++;
				EepWrite(&whyw_ee.Data.ee_nb_acq_interval, EEP_ADDR_WHYW_STORE_INTERVAL, 1, &s_eep_complete_WHYW);//更新EE数据
                up_deal_stat_WHYW  = UP_DEAL_S1;
            }
        }
        break;

        case UP_DEAL_S1:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM完成
            {
				up_deal_stat_WHYW  = UP_DEAL_S0;
				task_complete_WHYW = PTL_PACK_SUCCESS;
            }
        }
        break;

        default:
        {
            up_deal_stat_WHYW  = UP_DEAL_S0;
            task_complete_WHYW = PTL_PACK_FAIL;
        }
        break;
    }
}

/***************************************************************
write_battery_ack
写电池电压相关参数
说明:该通讯帧为设置水表电量低时的电压门限值和电量将耗尽时的电压门限值参数，其数据
格式意义与前面相关通讯帧中所描叙的一致。
****************************************************************/
static void write_battery_ack(void)
{
    switch(up_deal_stat_WHYW)
    {
        case UP_DEAL_S0:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM
            {
				g_frame_temp_len_WHYW = 0;
				whyw_ee.Data.ee_battery_pra[0] = *new_message_data_rev_WHYW++;
				whyw_ee.Data.ee_battery_pra[1] = *new_message_data_rev_WHYW++;
				whyw_ee.Data.ee_battery_pra[2] = *new_message_data_rev_WHYW++;
				whyw_ee.Data.ee_battery_pra[3] = *new_message_data_rev_WHYW++;
				EepWrite(whyw_ee.Data.ee_battery_pra, EEP_ADDR_WHYW_BATTERY_PRA, 4, &s_eep_complete_WHYW);//更新EE数据
                up_deal_stat_WHYW  = UP_DEAL_S1;
            }
        }
        break;

        case UP_DEAL_S1:
        {
            if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM完成
            {
				up_deal_stat_WHYW  = UP_DEAL_S0;
				task_complete_WHYW = PTL_PACK_SUCCESS;
            }
        }
        break;

        default:
        {
            up_deal_stat_WHYW  = UP_DEAL_S0;
            task_complete_WHYW = PTL_PACK_FAIL;
        }
        break;
    }
}

/***************************************************************
write_nb_para_ack
写水表 NB 网络参数
说明:该通讯帧为设置水表上线时所需的 NB 网络参数(IP 地址及端口)，其数据格式意义与前
面相关通讯帧中所描叙的一致
****************************************************************/
static void write_nb_para_ack(void)
{
    switch(up_deal_stat_WHYW)
    {
        case UP_DEAL_S0:
        {
			if(TASK_IDLE == EepIfIdle())
			{
				g_frame_temp_len_WHYW = 0;
				for (int i = 0; i < 4; i++)
				{
				    Sys_data_object.P2.server_ip[i] = *(new_message_data_rev_WHYW +i);
				}
				Sys_data_object.P2.server_port.data_buf[0] = *(new_message_data_rev_WHYW +4);
				Sys_data_object.P2.server_port.data_buf[1] = *(new_message_data_rev_WHYW +5);
				EepWrite(&Sys_data_object.P2.server_ip[0], EEP_UPDATE_UDP_IP, 6, &s_eep_complete_WHYW);//保存到UDP IP
				up_deal_stat_WHYW  = UP_DEAL_S1;
			}
        }
        break;

        case UP_DEAL_S1:
        {
			if(TASK_IDLE == EepIfIdle())//存储数据到EEPROM   
			{
				up_deal_stat_WHYW  = UP_DEAL_S0;
				task_complete_WHYW = PTL_PACK_SUCCESS;
			}
        }
        break;

        default:
        {
            up_deal_stat_WHYW  = UP_DEAL_S0;
            task_complete_WHYW = PTL_PACK_FAIL;
        }
        break;
    }
}

/***************************************************************
upload_ack
上报应答帧
说明:NB 物联网水表上线后主动发送计量数据信息通讯帧，平台收到该信息帧后便给与应
答通讯帧。当平台无需对该水表进行相关参数设置或其它操作时其应答控制码为 01H，水表
接收到该应答时可进入“离线”状态。若平台需要对该水表进行其它相关操作时，平台应答
码为 41H(D6 为“1”)，水表此时需要进行等待平台的后续相关指令帧(根据参数所设的最大
等待时间，超时而未收到平台的任何通讯帧则进入“离线”状态)，平台下发的其他通讯帧其
控制码的意义(D6 为“1”)与此相同
//68 10 02 00 08 22 20 33 78 01 07 00 90 20 14 01 00 01 00 3D 16
****************************************************************/
static void upload_ack(void)
{
	if(frame_struct_WHYW.serial_num == upload_serial_num_sy)//比较序列号
	{
		FrameSetMsgApp(MsgNbUplaod_AckOk);
	}
	g_frame_temp_len_WHYW = 0;
	up_deal_stat_WHYW  = UP_DEAL_S0;
	task_complete_WHYW = PTL_PACK_FAIL;
}
/****************************************************************************************************/
//地址判断
static u8 check_met_addr_WHYW(u8 * p_buf)
{
    u8 tmp_i = 0;
    u8 tmp_arry[8];

    for (tmp_i = 0; tmp_i < 8; tmp_i++)
    {
        tmp_arry[tmp_i] = *(p_buf + tmp_i + 1);
    }

    for (tmp_i = 1; tmp_i < 8; tmp_i++)
    {
        if ((tmp_arry[tmp_i] != Sys_data_object.P1.met_addr[tmp_i - 1]) && (tmp_arry[tmp_i] != 0xAA))
        {
            return ERROR_IES;
        }
    }

    return SUCCESS_IES;
}
//解规约
u8 crack_frame_WHYW(u16 frame_lenth, u8 *frame_buffer)
{
    u16 i;
    u16 j;
    u16 endloc = 0;
    u16 framelen = 0;

    if(*(frame_buffer + 10) != 1)
    {
        if (frame_lenth > FRAME_LEN_MAX) //检查待解帧长度是否大于数据缓冲区长度
        {
            return (ERROR_IES);
        }

        if (frame_lenth < FRAME_LEN_MIN) //检查待解帧长度是否小于最小协议帧长度
        {
            return (ERROR_IES);
        }

        for (i = 0; i < frame_lenth; i++)
        {
            if (FRAME_HEAD == *frame_buffer) //找到帧头
            {
				frame_struct_WHYW.head_site = i; //记录帧头
                if (ERROR_IES == check_met_addr_WHYW(frame_buffer)) //检查指令包含的地址和本表地址是否相同，相同返回1，不同返回0
                {
                    return (ERROR_IES);
                }

                frame_struct_WHYW.len.to_uint8[0] = *(frame_buffer + 10); 	//数据区长度
                frame_struct_WHYW.len.to_uint8[1] = *(frame_buffer + 11); 	//数据区长度

                framelen = frame_struct_WHYW.len.to_uint16 + 14; 			//帧长度 

                if (frame_struct_WHYW.len.to_uint16 > (frame_lenth - i))	//防止串口通讯规约恰巧绕过防护后造成数组越界复位
                {
                    return (ERROR_IES);
                }

                endloc = framelen - 1;

                if ((FRAME_TAIL == frame_buffer[endloc]) && (endloc <= frame_lenth)) //结束符正确，且帧长有效
                {
                    frame_struct_WHYW.chkval = 0;

                    for (j = 0; j < (framelen - 2); j++)
                    {
                        frame_struct_WHYW.chkval = frame_struct_WHYW.chkval + frame_buffer[j]; //判校验和
                    }

                    frame_struct_WHYW.chkval &= 0x00ff;

                    if (frame_struct_WHYW.chkval == frame_buffer[endloc - 1])
                    {
                        frame_struct_WHYW.frame_ctrl = *(frame_buffer + 9);  //获取控制码
                        frame_struct_WHYW.mark_DI0 = *(frame_buffer + 12);
                        frame_struct_WHYW.mark_DI1 = *(frame_buffer + 13);
                        frame_struct_WHYW.serial_num = *(frame_buffer + 14);
                        //68 10 03 00 08 22 20 33 78 04 04 00 81 11 22 0F 3B 16
						new_message_data_rev_WHYW = frame_buffer + frame_struct_WHYW.head_site + 15;	
						FrameSetMsgApp(MsgNb_FlagRcvNbFrame);  //下行指令的延时消息
                        return (SUCCESS_IES);
                    }//end if
                }
            }//end 找帧头的if

            frame_buffer++;
        }//end for()

        return (ERROR_IES);
    }
    return ERROR_IES;
}

//规约处理
static u8 whyw_deal_ctrl=0;
static u8 whyw_online_wait_flag=0;
u8 up_deal_code_WHYW(void)
{
	task_complete_WHYW = PTL_PACK_BUSY;
	whyw_deal_ctrl = (frame_struct_WHYW.frame_ctrl&0xBF);//去除D6（水表在线等待位）
	if(frame_struct_WHYW.frame_ctrl&0x40)//判断是否在线等待
	{
		whyw_online_wait_flag = 1;//延时下线消息
	}
	else
	{
		whyw_online_wait_flag = 2;//立马下线消息
	}
	switch(whyw_deal_ctrl)
	{
		case READ_CTRL_DOWN:
		{
			//读水表在线延时等待时间
			if((frame_struct_WHYW.mark_DI0 == RW_ONLINE_TIME_D0)&&(frame_struct_WHYW.mark_DI1 == RW_ONLINE_TIME_D1))
			{
				 read_oline_time_ack();
			}
			//读水表实时时间
			else if((frame_struct_WHYW.mark_DI0 == RW_METER_TIME_D0)&&(frame_struct_WHYW.mark_DI1 == RW_METER_TIME_D1))
			{
				read_meter_time_ack();
			}
			//读水表自动上传数据的时间参数
			else if((frame_struct_WHYW.mark_DI0 == RW_UPLOAD_TIME_ID0)&&(frame_struct_WHYW.mark_DI1 == RW_UPLOAD_TIME_ID1))
			{
				read_upload_time();
			}
			//读取水表数据采集间隔时间参数
			else if((frame_struct_WHYW.mark_DI0 == RW_INTERVAL_TIME_ID0)&&(frame_struct_WHYW.mark_DI1 == RW_INTERVAL_TIME_ID1))
			{
				read_interval_time_ack();
			}
			//读取电池电压相关参数
			else if((frame_struct_WHYW.mark_DI0 == RW_BATTERY_D0)&&(frame_struct_WHYW.mark_DI1 == RW_BATTERY_D1))
			{
				read_battery_ack();
			}
			//读水表 NB 网络参数
			else if((frame_struct_WHYW.mark_DI0 == RW_NB_PARA_D0)&&(frame_struct_WHYW.mark_DI1 == RW_NB_PARA_D1))
			{
				read_nb_para_ack();
			}
			//水表发送当前的计量信息数据应答帧
			else if((frame_struct_WHYW.mark_DI0 == UPLOAD_DATA_D0)&&(frame_struct_WHYW.mark_DI1 == UPLOAD_DATA_D1))
			{
				upload_ack();
			}
			else
			{
				g_frame_temp_len_WHYW = 0;
				up_deal_stat_WHYW  = UP_DEAL_S0;
				task_complete_WHYW = PTL_PACK_FAIL;
			}
			frame_struct_WHYW.ack_ctrl = READ_CTRL_UP;
		}
		break;
		case WRITE_CTRL_DOWN:
		{
			//写水表在线延时等待时间
			if((frame_struct_WHYW.mark_DI0 == RW_ONLINE_TIME_D0)&&(frame_struct_WHYW.mark_DI1 == RW_ONLINE_TIME_D1))
			{
				write_online_time_ack();
			}
			//写水表实时时间
			else if((frame_struct_WHYW.mark_DI0 == RW_METER_TIME_D0)&&(frame_struct_WHYW.mark_DI1 == RW_METER_TIME_D1))
			{
				task_complete_WHYW = PTL_PACK_FAIL;
			}
			//写水表自动上传数据的时间参数
			else if((frame_struct_WHYW.mark_DI0 == RW_UPLOAD_TIME_ID0)&&(frame_struct_WHYW.mark_DI1 == RW_UPLOAD_TIME_ID1))
			{
				write_upload_time_ack();
			}
			//写水表数据采集间隔时间参数
			else if((frame_struct_WHYW.mark_DI0 == RW_INTERVAL_TIME_ID0)&&(frame_struct_WHYW.mark_DI1 == RW_INTERVAL_TIME_ID1))
			{
				write_interval_time_ack();
			}
			//写电池电压相关参数
			else if((frame_struct_WHYW.mark_DI0 == RW_BATTERY_D0)&&(frame_struct_WHYW.mark_DI1 == RW_BATTERY_D1))
			{
				write_battery_ack();
			}
			//写水表 NB 网络参数
			else if((frame_struct_WHYW.mark_DI0 == RW_NB_PARA_D0)&&(frame_struct_WHYW.mark_DI1 == RW_NB_PARA_D1))
			{
				write_nb_para_ack();
			}
			else
			{
				g_frame_temp_len_WHYW = 0;
				up_deal_stat_WHYW  = UP_DEAL_S0;
				task_complete_WHYW = PTL_PACK_FAIL;
			}
			frame_struct_WHYW.ack_ctrl = WRITE_CTRL_UP;
		}
		break;
		default:
        {    
			g_frame_temp_len_WHYW = 0;
			up_deal_stat_WHYW  = UP_DEAL_S0;
			task_complete_WHYW = PTL_PACK_FAIL;         
        }
        break;
	}
    return task_complete_WHYW;
}

void Frame_ResetDealState_WHYW(void)
{
	up_deal_stat_WHYW = UP_DEAL_S0;
}
//数据组帧函数
static void Frame_ack_WHYWBase(STRUCT_FRAME_WHYW temp_struct, u8* p_temp_buf, u16 p_temp_len, u8* p_send_buf, u16* p_send_len)
{
    u16 i = 0;
	u8 temp_cs;
	u8* p_send_buf_start;
	u8* p_send_buf_end;
	u16 temp_len;
	
	p_send_buf_start = p_send_buf;
	p_send_buf_end = p_send_buf;
	
    *p_send_buf_end++ = FRAME_HEAD_MARK;
    *p_send_buf_end++ = W_METTYPE;
    for (i = 0; i < 7; i++)
    {
        *p_send_buf_end++ = Sys_data_object.P1.met_addr[i];	//表地址
    }
    *p_send_buf_end++ = temp_struct.ack_ctrl;
    *p_send_buf_end++ = (p_temp_len+3)&0xFF; // 这里加了三个字节，di0，di1，ser
    *p_send_buf_end++ = ((p_temp_len+3)>>8)&0xFF;
    *p_send_buf_end++ = temp_struct.mark_DI0;
    *p_send_buf_end++ = temp_struct.mark_DI1;
    *p_send_buf_end++ = temp_struct.serial_num;
	//拷贝数据区
    for(i = 0; i < p_temp_len; i++)
    {
        *p_send_buf_end++ = *(p_temp_buf + i);	
    }
	//计算校验和
	temp_len = (p_send_buf_end - p_send_buf_start);
    for(i = 0; i < temp_len; i++)		
    {
        temp_cs += *p_send_buf_start;
		p_send_buf_start++;
    }
	*p_send_buf_end++ = temp_cs;
	*p_send_buf_end++ = FRAME_END_MARK;
	*p_send_len = (temp_len+2);
}
//应答数据组帧
void Frame_ack_WHYW(u8* p_send_buf, u16* p_send_len)
{
	Frame_ack_WHYWBase(frame_struct_WHYW, g_frame_temp_buf_WHYW, g_frame_temp_len_WHYW, p_send_buf, p_send_len);
}
/****************************************************************以下主动上报数据的处理*********************************************/
//上报数据组帧
void Frame_upload_WHYW(u8* p_send_buf, u16* p_send_len)
{
	upload_struct_WHYW.ack_ctrl = READ_CTRL_UP;
	upload_struct_WHYW.mark_DI0 = UPLOAD_DATA_D0;
    upload_struct_WHYW.mark_DI1 = UPLOAD_DATA_D1;
	upload_serial_num_sy++;//序列号增加
	upload_struct_WHYW.serial_num = upload_serial_num_sy;
	
	Frame_ack_WHYWBase(upload_struct_WHYW, g_upload_temp_buf_WHYW, g_upload_temp_len_WHYW, p_send_buf, p_send_len);
}

//UDP上报数据帧
void Upload_FrameData(void)
{
    g_upload_temp_len_WHYW = 0;
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_packet_count&0xFF; //总帧数L
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = (upload_packet_count>>8)&0xFF; //总帧数H
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_packet_code&0xFF; //本帧序号L
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = (upload_packet_code>>8)&0xFF; //本帧序号H
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_packet_data_count; //本帧条数
	
	/***从EE读取***/
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_rtcc_start.s.minute; //首条数据采集时间-分
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_rtcc_start.s.hour; //首条数据采集时间-时
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_rtcc_start.s.day; //首条数据采集时间-日
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_rtcc_start.s.month; //首条数据采集时间-月
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_rtcc_start.s.year; //首条数据采集时间-年
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = 30 ; //采集间隔30分钟

	//当前累计流量(4 字节 BCD 码) :50H、56H、34H、12H 表示当前累积流量为 123456.50 m3
	for(int i=0;i<upload_packet_data_count;i++)
	{
		g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_buf[4*i+0];
		g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_buf[4*i+1];
		g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_buf[4*i+2];
		g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = upload_circle_buf[4*i+3];
	}
	//35H、06H 表示电压值为 6.35V。
	temp_data_u16.datas = HexToBcd16(PowerCheckValueSys());		
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[0];//电池电压L
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[1];//电池电压H

	 //CSQ BCD格式
	NbiotGetCSQ(&temp_data_u8);
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = HEX2BCD(temp_data_u8);//sys_get_single.to_uint8[0];
	
	//获取RSRP hex 2 字节,最高位表示符号位，“0”表示正数，“1”表示负数，D0-D14 表示其信号质量数据值。7BH、80H 表示信号质量值为-123dBm。
	NbiotGetRSRP(&s_temp_data);
	temp_data_u16.datas = -(s_temp_data/10);
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[0];
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[1]|0x80;

    //获取SNR hex  19H、00H 表示信噪比 25dB。
	NbiotGetSNR(&s_temp_data);
	if(s_temp_data<0)
	{
		temp_data_u16.datas = (-s_temp_data/10)|0x8000;
	}
	else
    {
	    temp_data_u16.datas = s_temp_data/10;
	}
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[0];
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[1];

    //获取ECL
	NbiotGetECL(&s_temp_data);
	temp_data_u16.datas = s_temp_data;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[0];
	
	//PCI  2 字节 BCD 码，高位字节在前，05H、04H 表 示 PCI 编号为 504。
    NbiotGetPCI(&temp_data);
	temp_data_u16.datas = temp_data;
	temp_data_u16.datas = HexToBcd16(temp_data_u16.datas);
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[0];
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u16.data_buf[1];

	//IMEI  如: 08H、23H、25H、89H、67H、31H、09H、60H 表示 NB 模组的 IMEI 码为 823258967310960。
	NbiotGetIMEI((char*)temp_buf1); 
	temp_buf2[0] = temp_buf1[0] - 0x30;
	for(int i=1;i<8;i++)
	{
		temp_buf2[i]  =  (temp_buf1[2*i]-0x30)&0x0F;
		temp_buf2[i] |= ((temp_buf1[2*i-1]-0x30)<<4)&0xF0;          
	}
	for(int i = 0; i < 8; i++)
	{
		g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_buf2[i];;
	}
	//IMSI 如: 09H、12H、34H、79H、68H、56H、07H、80H 表示 SIM 卡的 IMSI 码为 912347968560780
	NbiotGetIMSI((char*)temp_buf1); 
	temp_buf2[0] = temp_buf1[0] - 0x30;
	for(int i=1;i<8;i++)
	{
		temp_buf2[i]  =  (temp_buf1[2*i]-0x30)&0x0F;
		temp_buf2[i] |= ((temp_buf1[2*i-1]-0x30)<<4)&0xF0;          
	}
	for(int i = 0; i < 8; i++)
	{
		g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_buf2[i];
	}				
	//上线成功/失败次数	
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = whyw_ee.Data.ee_upload_count_success.data_buf[0];
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = whyw_ee.Data.ee_upload_count_success.data_buf[1];
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = whyw_ee.Data.ee_upload_count_fail.data_buf[0];
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = whyw_ee.Data.ee_upload_count_fail.data_buf[1];
	//表计时间
	DateTime sys_rtcc_time;
    RtccGetDateTime(&sys_rtcc_time);
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = sys_rtcc_time.s.second;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = sys_rtcc_time.s.minute;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = sys_rtcc_time.s.hour;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = sys_rtcc_time.s.day;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = sys_rtcc_time.s.month;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = sys_rtcc_time.s.year;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = 0x20;
    //状态报警信息
		temp_data_u8 = 0;
	if(UPLOAD_TYPE_FIX_TIME == GetEventUploadType()|| (UPLOAD_TYPE_RETRY_AGAIN == GetEventUploadType()))//定时上传
	{
		temp_data_u8 &=~ 0x80;//自动上线
	}
	else
	{
		temp_data_u8 |= 0x80;//触发
	}
	temp_state = FrameGetByte();
	if(temp_state.stat1bits.low_battery_voltage)
	{
		temp_data_u8 |= 0x04;//电池欠压
	}
	else
	{
		temp_data_u8 &=~0x04;//电池正常
	}
	temp_data_u8 &=~ 0x02;//先清阀门故障标志
	if(temp_state.stat1bits.valve_state==0)
	{
		temp_data_u8 &=~ 0x01;//开阀
	}
	else if(temp_state.stat1bits.valve_state==1)
	{
		temp_data_u8 |= 0x01;//关阀
	}
	else
	{
		temp_data_u8 |= 0x02;//故障
	}
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = temp_data_u8;//state0;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = 0x03;//state1; 03H:超声波水表
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = 3;//warning0;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = 4;//warning1;
    g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = 5;//warning2;
	//硬件版本
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = HARDWARE_VERSION_USED;
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = 0;
	//软件版本
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = (PROGRAME_VERSION>>16)&0xFF;
	g_upload_temp_buf_WHYW[g_upload_temp_len_WHYW++] = (PROGRAME_VERSION>>24)&0xFF;
}

/********************************************************************************
GetCircleDateTimeStart
说  明：根据采集间隔和周期数据记录条数计算周期数据起始时间
********************************************************************************/
u8 GetCircleDateTimeStart(DateTime* startTime, DateTime endTime, u32 dataCnt, u8 intervalTime)
{
	struct tm tmdt;
	struct tm *ldt;
	time_t ctt;

	tmdt.tm_year = (endTime.s.year >> 4) * 10 + (endTime.s.year & 0x0F) + 100;
	tmdt.tm_mon = (endTime.s.month >> 4) * 10 + (endTime.s.month & 0x0F) - 1;
	tmdt.tm_mday = (endTime.s.day >> 4) * 10 + (endTime.s.day & 0x0F);
	tmdt.tm_hour = (endTime.s.hour >> 4) * 10 + (endTime.s.hour & 0x0F);
	tmdt.tm_min = (endTime.s.minute >> 4) * 10 + (endTime.s.minute & 0x0F);
	tmdt.tm_sec = (endTime.s.second >> 4) * 10 + (endTime.s.second & 0x0F);
	tmdt.tm_isdst = 0;
	ctt = mktime(&tmdt);
	ctt -= (dataCnt*intervalTime*60);
	ldt = localtime(&ctt);

	startTime->s.year = ((*ldt).tm_year - 100) / 10 * 16 + ((*ldt).tm_year - 100) % 10;
	startTime->s.month = ((*ldt).tm_mon + 1) / 10 * 16 + ((*ldt).tm_mon + 1) % 10;
	startTime->s.day = ((*ldt).tm_mday) / 10 * 16 + ((*ldt).tm_mday) % 10;
	startTime->s.weekday = ((*ldt).tm_wday) / 10 * 16 + ((*ldt).tm_wday) % 10;
	startTime->s.hour = ((*ldt).tm_hour) / 10 * 16 + ((*ldt).tm_hour) % 10;
	startTime->s.minute = ((*ldt).tm_min) / 10 * 16 + ((*ldt).tm_min) % 10;
	startTime->s.second = ((*ldt).tm_sec) / 10 * 16 + ((*ldt).tm_sec) % 10;
	
	return Rtcc_Check_DateTime(startTime);
}

void GetUploadDataResetState_WHYW(void)
{
	upload_frame_stat_whyw =WHYW_STATE_S0;
	task_upload_complete_whyw = PTL_PACK_BUSY;
}
u8 GetUploadDataCheckIdle_WHYW(void)
{
	if(WHYW_STATE_S0 == upload_frame_stat_whyw)
    {
        return TASK_IDLE;
    }
    else
    {
        return TASK_BUSY;
    }
}
u8 GetUploadDataCheckTask_WHYW(void)
{
	return task_upload_complete_whyw;
}

int GetUploadDataCount(void)
{
	if (whyw_ee.Data.u_circle_store_index_w.datas >= whyw_ee.Data.u_circle_store_index_r.datas)
		return (whyw_ee.Data.u_circle_store_index_w.datas - whyw_ee.Data.u_circle_store_index_r.datas);
	else 
		return (whyw_ee.Data.u_circle_store_index_w.datas + STORE_DATA_COUNT_CIRCLE - whyw_ee.Data.u_circle_store_index_r.datas);
}

void GetUploadDataMachine_WHYW(u8 data_step, u8* p_send_buf, u16* p_send_len)
{
	switch(upload_frame_stat_whyw)
	{
		case WHYW_STATE_S0:
		{
			if(data_step == UPLOAD_FRAME_REQUEST_NEW)//请求新数据包
			{
				whyw_online_wait_flag=0;//在线等待标志清除
				temp_upload_step = 0;
				upload_frame_retry_times = 0;
				upload_count_flag = 0;
				upload_frame_stat_whyw = WHYW_STATE_S1;
			}
			else if(data_step == UPLOAD_FRAME_UPLOAD_OK)//发送成功
			{
				if(upload_count_flag == 0)//记录一次上报成功
				{
					upload_count_flag = 1;
					whyw_ee.Data.ee_upload_count_success.datas++;//上报成功总次数
				}
				if(temp_upload_step == WHYW_STATE_S10)//周期记录数据发送成功,继续发送
				{
					upload_frame_stat_whyw = WHYW_STATE_S13;//保存读指针
				}
				else if(temp_upload_step == WHYW_STATE_S20)//当前包数据发送成功,任务结束
				{
					upload_frame_stat_whyw = WHYW_STATE_S5;//在线延时
				}
				upload_frame_retry_times = 0;
				SystemClearUploadAgain();//重传清0
			}
			else if(data_step == UPLOAD_FRAME_UPLOAD_RETRY)//请求重新发送
			{
				if(temp_upload_step == WHYW_STATE_S10)//周期记录数据需要重发
				{
					upload_frame_stat_whyw = WHYW_STATE_S4;
				}
				else if(temp_upload_step == WHYW_STATE_S20)//当前包数据需要重发
				{
					upload_frame_stat_whyw = WHYW_STATE_S4;
				}
				else
				{
					task_upload_complete_whyw = PTL_PACK_FAIL;//任务结束
					upload_frame_stat_whyw = WHYW_STATE_S0;
				}
			}
			else if(data_step == UPLOAD_FRAME_ONLINE_FAIL) //联网失败
			{
				  if(UPLOAD_TYPE_FIX_TIME == GetEventUploadType()||
					(UPLOAD_TYPE_RETRY_AGAIN == GetEventUploadType()))//定时上传
				{
					SystemAddUploadAgain();//重传增加
				}
				whyw_ee.Data.ee_upload_count_fail.datas++;//失败次数
				task_upload_complete_whyw = PTL_PACK_FAIL;
				upload_frame_stat_whyw = WHYW_STATE_S0;
			}
			else 
			{
				task_upload_complete_whyw = PTL_PACK_FAIL;
				upload_frame_stat_whyw = WHYW_STATE_S0;
			}
		}
		break;
		case WHYW_STATE_S1://读取记录时间
		{
			if(TASK_IDLE == EepIfIdle())
			{
				EepRead(EEP_ADDR_WHYW_LAST_RTCC, &upload_circle_rtcc_end.b[0], 7, &s_eep_complete_WHYW);
				upload_frame_stat_whyw = WHYW_STATE_S2;
			}  
		}
		break;
		case WHYW_STATE_S2://计算上报包数
		{
			if(TASK_IDLE == EepIfIdle())
			{
				upload_data_count = GetUploadDataCount();
				if(upload_data_count > 0)
				{
					upload_packet_count = (upload_data_count/UPLOAD_CIRCLE_MAX_COUNT)+1;//计算总帧数
					upload_packet_code = 0;//帧编号初始化
					upload_frame_stat_whyw = WHYW_STATE_S10;
				}
				else//还没有记录,上报一条当前数据
				{
					upload_frame_stat_whyw = WHYW_STATE_S20;
				}
			}
		}
		break;
/*>>>>>>>>>>>周期数据记录的读取>>>>>>>>>>>>>>*/
		case WHYW_STATE_S10://读取一包周期存储数据
		{
			 if(TASK_IDLE == EepIfIdle())
			 {
				temp_upload_step = WHYW_STATE_S10;
				 
				upload_data_count = GetUploadDataCount();
				 if(upload_data_count >0)//还有数据要发送
				 {
					if((upload_data_count/UPLOAD_CIRCLE_MAX_COUNT)>0)
					{
						upload_packet_data_count = UPLOAD_CIRCLE_MAX_COUNT;
					}
					else
					{
						upload_packet_data_count = (upload_data_count%UPLOAD_CIRCLE_MAX_COUNT);
					}
					if((whyw_ee.Data.u_circle_store_index_r.datas + upload_packet_data_count) < STORE_DATA_COUNT_CIRCLE)//没有超过边界,读一次
					{
						uTemp_ee_addr = EEP_ADDR_WHYW_STORE_CIRCLE + whyw_ee.Data.u_circle_store_index_r.datas*4;
						uTemp_read_len =  upload_packet_data_count*STORE_DATA_SIZE_CIRCLE;
						EepRead(uTemp_ee_addr, &upload_circle_buf[0], uTemp_read_len, &s_eep_complete_WHYW);
						upload_frame_stat_whyw = WHYW_STATE_S12;
					}
					else//超过边界,读两次
					{
						uTemp_ee_addr = EEP_ADDR_WHYW_STORE_CIRCLE + whyw_ee.Data.u_circle_store_index_r.datas*4;
						uTemp_read_len = (whyw_ee.Data.u_circle_store_index_r.datas + upload_packet_data_count - STORE_DATA_COUNT_CIRCLE)*STORE_DATA_SIZE_CIRCLE;
						EepRead(uTemp_ee_addr, &upload_circle_buf[0], uTemp_read_len, &s_eep_complete_WHYW);
						upload_frame_stat_whyw = WHYW_STATE_S11;
					}
				 }
				 else//没有数据发送了
				 {
						upload_frame_stat_whyw = WHYW_STATE_S5;//在线延时
				 }
			 }
		}
		break;
		
		case WHYW_STATE_S11://等待读取完成1
		{
			 if(TASK_IDLE == EepIfIdle())
			 {
				uTemp_ee_addr = EEP_ADDR_WHYW_STORE_CIRCLE;
				EepRead(uTemp_ee_addr, &upload_circle_buf[uTemp_read_len], (upload_packet_data_count - uTemp_read_len), &s_eep_complete_WHYW);
				upload_frame_stat_whyw = WHYW_STATE_S12;
			 }
		}
		break;
		case WHYW_STATE_S12://等待读取完成2
		{
			 if(TASK_IDLE == EepIfIdle())
			 {
				upload_packet_code++;//帧编号
				if(ERROR == GetCircleDateTimeStart(&upload_circle_rtcc_start, upload_circle_rtcc_end, (upload_data_count-1), 30))//计算时间
				{
					//保存的时间格式不正确,初始化读写指针,上报当前数据
					whyw_ee.Data.u_circle_store_index_w.datas = 0;
					whyw_ee.Data.u_circle_store_index_r.datas = 0;
					upload_frame_stat_whyw = WHYW_STATE_S20;
				}
				else
				{
					upload_frame_stat_whyw = WHYW_STATE_S3;
				}
			 }
		}
		break;
		case WHYW_STATE_S13://存储读指针,收到上报应答后存储
		{
			if(TASK_IDLE == EepIfIdle())
			{
				whyw_ee.Data.u_circle_store_index_r.datas += upload_packet_data_count; 
				whyw_ee.Data.u_circle_store_index_r.datas %= STORE_DATA_COUNT_CIRCLE;//越界之后从起始位置计算
				EepWrite(whyw_ee.Data.u_circle_store_index_r.data_buf, EEP_ADDR_WHYW_CIRCLE_INDEX_R, 2, &s_eep_complete_WHYW);
				upload_frame_stat_whyw = WHYW_STATE_S10;//继续获取下一包数据
			}  
		}
		break;
/*>>>>>>>>>>>当前数据上报>>>>>>>>>>>>>>*/
		case WHYW_STATE_S20://上报当前数据
		{
			temp_upload_step = WHYW_STATE_S20;
			upload_packet_count = 1;//本次上报总帧数
			upload_packet_code = 1;//本帧编号
			upload_packet_data_count = 1;//本帧记录条数
			temp_float_data.gp22_u32 =  Gp30CheckDataApp(2);
			temp_CircleData  = (u32)(temp_float_data.gp22_float);
			temp_bcd_CircleData.datas = HexToBcd32(temp_CircleData);
			for(int i=0;i<4;i++)
			{
				upload_circle_buf[i] = temp_bcd_CircleData.data_buf[i];
			}
			RtccGetDateTime(&upload_circle_rtcc_start);//当前时间做为“首条数据采集时间”
			upload_frame_stat_whyw = WHYW_STATE_S3;
		}
		break;
/*>>>>>>>>>>>组上传数据帧>>>>>>>>>>>>>>*/	
		case WHYW_STATE_S3://组上传帧
		{
			Upload_FrameData();
			Frame_upload_WHYW(p_send_buf,p_send_len);
			task_upload_complete_whyw = PTL_PACK_SUCCESS;
			upload_frame_stat_whyw = WHYW_STATE_S0;
		}
		break;
/*>>>>>>>>>>>数据发送失败后重试>>>>>>>>>>>>>>*/	
		case WHYW_STATE_S4://重试
		{
			if(upload_frame_retry_times < 2) 
			{
				upload_frame_retry_times++;
				upload_frame_stat_whyw = WHYW_STATE_S3;
			} 
			else//重新发送失败2次的处理
			{	
				if((UPLOAD_TYPE_FIX_TIME == GetEventUploadType())|| //定时上传
					(UPLOAD_TYPE_RETRY_AGAIN == GetEventUploadType()))//重传
				{
					SystemAddUploadAgain();//重传增加
				}
				whyw_ee.Data.ee_upload_count_fail.datas++;//失败次数
				task_upload_complete_whyw = PTL_PACK_FAIL;
				upload_frame_stat_whyw = WHYW_STATE_S0;
			}
		}
		break;
/*>>>>>>>>>>>网络延时下线>>>>>>>>>>>>>>*/	
		case WHYW_STATE_S5://网络延时下线
		{
			if(whyw_online_wait_flag == 1)//需要在线等待
			{
				whyw_online_wait_flag = 0;
				if(whyw_ee.Data.ee_nb_online_keep_time>30)
				{
					whyw_ee.Data.ee_nb_online_keep_time = 15;
				}
				Set100msTimer(TIMER_100MS_UPLOAD_MONITOR, 10*whyw_ee.Data.ee_nb_online_keep_time);
				upload_frame_stat_whyw = WHYW_STATE_S6;
			}
			else//无需等待
			{
				task_upload_complete_whyw = PTL_PACK_FAIL;
				upload_frame_stat_whyw = WHYW_STATE_S0;
			}
		}
		break;
		case WHYW_STATE_S6://等待时间到
		{
			if(whyw_online_wait_flag == 1)//重新计时
			{
				whyw_online_wait_flag = 0;
				if(whyw_ee.Data.ee_nb_online_keep_time>30)
				{
					whyw_ee.Data.ee_nb_online_keep_time = 15;
				}
				Set100msTimer(TIMER_100MS_UPLOAD_MONITOR, 10*whyw_ee.Data.ee_nb_online_keep_time);
			}
			else if(whyw_online_wait_flag == 2)//等待期间收到立马下线消息
			{
				whyw_online_wait_flag = 0;
				task_upload_complete_whyw = PTL_PACK_FAIL;
				upload_frame_stat_whyw = WHYW_STATE_S0;
			}
			if(0 == Check100msTimer(TIMER_100MS_UPLOAD_MONITOR))
			{
				task_upload_complete_whyw = PTL_PACK_FAIL;
				upload_frame_stat_whyw = WHYW_STATE_S0;
			}
		}
		break;
		
		default:
		{
			task_upload_complete_whyw = PTL_PACK_FAIL;
			upload_frame_stat_whyw = WHYW_STATE_S0;
		}
		break;
	}
}

u8 NB_SS_Control_GetPara(NB_SS_ControlParaTypeDef paraType)
{
	switch(paraType)
	{
	    case NB_HistroyReadIndex://历史数据的读指针
		{
			return Sys_data_object.P1.histroy_w;
		}
		case NB_UploadFailTimes://失败次数
		{
			u8 temp_fail_times=0;
			temp_fail_times = GetUploadDataCount();
			return temp_fail_times;
		}
		default:
			break;
	}
	return 0;
}

/*************************************************************数据存储部分************/
static void WHYW_Store_InitApp(void)
{
	TYP_STATE_WHYW tmp_init_stat;

	if(Sys_data_object.P3.FirstPowerOnFlag == FIRST_POWER_ON_FLAG)
	{
		tmp_init_stat = WHYW_STATE_S10;
	}
	else
	{
		tmp_init_stat = WHYW_STATE_S20;
	}
    while (tmp_init_stat != WHYW_STATE_S0)
    {
      switch (tmp_init_stat)
      {
        case WHYW_STATE_S0:
        { 
        }
		break;
		//第一次上电流程
        case WHYW_STATE_S10:
        {
            if(TASK_IDLE == EepIfIdle())
            {
				whyw_ee.Data.u_circle_store_index_w.datas = 0;//周期数据存储的位置
				whyw_ee.Data.u_circle_store_index_r.datas = 0;//周期数据读取的位置
				RtccGetDateTime(&whyw_ee.Data.store_circle_rtcc_end);//最后一条记录的时间7字节
				whyw_ee.Data.ee_nb_online_keep_time = 10;//在线延时时间 1字节 10s
				whyw_ee.Data.ee_nb_acq_interval = 30;//表数据采集记录间隔时间 1字节 采集间隔30分钟
				whyw_ee.Data.ee_battery_pra[0]=0x00;//电池电压相关参数
				whyw_ee.Data.ee_battery_pra[1]=0x03;
				whyw_ee.Data.ee_battery_pra[2]=0x00;
				whyw_ee.Data.ee_battery_pra[3]=0x03;
				whyw_ee.Data.ee_upload_count_success.datas =0;//上报成功总次数
				whyw_ee.Data.ee_upload_count_fail.datas = 0;//上报失败总次数
                EepWrite(&whyw_ee.data_buf[0], EEP_ADDR_WHYW_CIRCLE_INDEX_W, EE_PRA_SIZE_WHYW, &s_eep_complete_WHYW);
                tmp_init_stat = WHYW_STATE_S1;
            }
        }
		break;
		//非第一次上电
		case WHYW_STATE_S20:
        {
            if (TASK_IDLE == EepIfIdle())
            {
                EepRead(EEP_ADDR_WHYW_CIRCLE_INDEX_W, &whyw_ee.data_buf[0], EE_PRA_SIZE_WHYW, &s_eep_complete_WHYW);
                tmp_init_stat = WHYW_STATE_S21;				
            }		
        }
		break;
		case WHYW_STATE_S21:
        {
            if (TASK_IDLE == EepIfIdle())
            {
				if((u_circle_store_index_w.datas>=STORE_DATA_COUNT_CIRCLE)||(u_circle_store_index_r.datas>=STORE_DATA_COUNT_CIRCLE))
				{
					whyw_ee.Data.u_circle_store_index_w.datas = 0;
					whyw_ee.Data.u_circle_store_index_r.datas = 0;
					RtccGetDateTime(&whyw_ee.Data.store_circle_rtcc_end);
					EepWrite(&whyw_ee.data_buf[0], EEP_ADDR_WHYW_CIRCLE_INDEX_W, EE_PRA_SIZE_WHYW, &s_eep_complete_WHYW);
				}
                tmp_init_stat = WHYW_STATE_S1;
            }
        }
		break;	
		
		case WHYW_STATE_S1:
		{
			if (TASK_IDLE == EepIfIdle())
            {
				tmp_init_stat = WHYW_STATE_S0;	
            }
		}
		break;
		
		default:
		{
			tmp_init_stat  = WHYW_STATE_S0;
		    break;
		}
      }
      EepMachineDriver();
    }
}


//周期数据存储状态机
static void WHYWStore_Machine(void)
{
	switch(step_circle_data_store)
	{
		case WHYW_STATE_S0:
		{
			if (RtccCheckMsgApp(RtccMsg_OtherProtl))
			{
				RtccClearMsgApp(RtccMsg_OtherProtl);
				RtccGetDateTime(&whyw_protl_rtcc_time);
				if((whyw_protl_rtcc_time.s.minute==0x00)||(whyw_protl_rtcc_time.s.minute==0x30))//半小时
				{
					FrameSetMsgApp(MsgShenYang_CircleSave);//周期数据存储
				}
			}
			if(FrameCheckMsgApp(MsgShenYang_CircleSave))//周期数据存储消息
			{
				FrameClearMsgApp(MsgShenYang_CircleSave);	
				step_circle_data_store = WHYW_STATE_S1;
			}		
			else if(FrameCheckMsgApp(Msg_ClearHisOther))//清表数据
			{
				FrameClearMsgApp(Msg_ClearHisOther);
				step_circle_data_store = WHYW_STATE_S10;
			}
		}
		break;
		case WHYW_STATE_S1://存储数据
		{
			if(TASK_IDLE == EepIfIdle())
			{
				//获取当前流量
				temp_float_data.gp22_u32 =  Gp30CheckDataApp(2);
				temp_CircleData  = (u32)(temp_float_data.gp22_float);
				temp_bcd_CircleData.datas = HexToBcd32(temp_CircleData);
				if(whyw_ee.Data.u_circle_store_index_w.datas >= STORE_DATA_COUNT_CIRCLE)
				{
					whyw_ee.Data.u_circle_store_index_w.datas = 0;
				}
				uTemp_ee_addr = EEP_ADDR_WHYW_STORE_CIRCLE + whyw_ee.Data.u_circle_store_index_w.datas*STORE_DATA_SIZE_CIRCLE;
				EepWrite(temp_bcd_CircleData.data_buf, uTemp_ee_addr, STORE_DATA_SIZE_CIRCLE, &s_eep_complete_WHYW);
				step_circle_data_store = WHYW_STATE_S2;
			}  
		}
		break;
		case WHYW_STATE_S2: //存储指针
		{
			if(TASK_IDLE == EepIfIdle())
			{
				whyw_ee.Data.u_circle_store_index_w.datas++;
				if(whyw_ee.Data.u_circle_store_index_w.datas >= STORE_DATA_COUNT_CIRCLE)
				{
					whyw_ee.Data.u_circle_store_index_w.datas = 0;
				}
				EepWrite(whyw_ee.Data.u_circle_store_index_w.data_buf, EEP_ADDR_WHYW_CIRCLE_INDEX_W, 2, &s_eep_complete_WHYW);
				step_circle_data_store = WHYW_STATE_S3;
			}  
		}
		break;
		case WHYW_STATE_S3: //存储时间
		{
			if(TASK_IDLE == EepIfIdle())
			{
				RtccGetDateTime(&whyw_ee.Data.store_circle_rtcc_end);
				EepWrite(&whyw_ee.Data.store_circle_rtcc_end.b[0], EEP_ADDR_WHYW_LAST_RTCC, 7, &s_eep_complete_WHYW);
				step_circle_data_store = WHYW_STATE_S4;
			}  
		}
		break;
		case WHYW_STATE_S4: //存储成功失败次数
		{
			if(TASK_IDLE == EepIfIdle())
			{
				whyw_ee.Data.ee_upload_count_fail.datas++;//失败次数
				EepWrite(&whyw_ee.Data.ee_upload_count_success.data_buf[0], EEP_ADDR_WHYW_UPLOAD_SUCCESS, 4, &s_eep_complete_WHYW);
				step_circle_data_store = WHYW_STATE_S5;
			}  
		}
		break;
		case WHYW_STATE_S5: //等待存储完成
		{
			if(TASK_IDLE == EepIfIdle())
			{
				//RtccAdjustDateTime(1,1800-10);//debug
				step_circle_data_store = WHYW_STATE_S0;
			}  
		}
		break;
		
		 case WHYW_STATE_S10://清表数据后,参数恢复初始值
        {
            if(TASK_IDLE == EepIfIdle())
            {
				whyw_ee.Data.u_circle_store_index_w.datas = 0;//周期数据存储的位置
				whyw_ee.Data.u_circle_store_index_r.datas = 0;//周期数据读取的位置
				RtccGetDateTime(&whyw_ee.Data.store_circle_rtcc_end);//最后一条记录的时间7字节
				whyw_ee.Data.ee_nb_online_keep_time = 10;//在线延时时间 1字节 10s
				whyw_ee.Data.ee_nb_acq_interval = 30;//表数据采集记录间隔时间 1字节 采集间隔30分钟
				whyw_ee.Data.ee_battery_pra[0]=0x00;//电池电压相关参数
				whyw_ee.Data.ee_battery_pra[1]=0x03;
				whyw_ee.Data.ee_battery_pra[2]=0x00;
				whyw_ee.Data.ee_battery_pra[3]=0x03;
				whyw_ee.Data.ee_upload_count_success.datas =0;//上报成功总次数
				whyw_ee.Data.ee_upload_count_fail.datas = 0;//上报失败总次数
                EepWrite(&whyw_ee.data_buf[0], EEP_ADDR_WHYW_CIRCLE_INDEX_W, EE_PRA_SIZE_WHYW, &s_eep_complete_WHYW);
                step_circle_data_store = WHYW_STATE_S0;
            }
        }
		break;
		default:
		{
			step_circle_data_store = WHYW_STATE_S0;
			break;
		}
	}
}

//规约数据存储部分初始化
void DataStoreInit(void)
{
	Quanzhou_Store_InitApp();
	WHYW_Store_InitApp();
}
//规约数据存储状态机
void DataStoreMachine(void)
{
	Quanzhou_Store_Machine();//冻结数据存储
	WHYWStore_Machine();
}

//规约数据存储休眠判断
u8 DataStoreIfIdle(void)
{
	if(step_circle_data_store == WHYW_STATE_S0)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}


#endif





