/*
 * @Description: 云模块-svc层
 * @Author: yangsw
 * @Date: 2021-05-21 16:27:42
 * @LastEditTime: 2023-10-16 16:41:29
 * @LastEditors: LiDa
 * @Reference:
 */

#include "svc_cloud.h"
#include "svc_cloud_protocol.h"
#include "../../flash/svc/svc_flash.h"
#include "../../nb/svc/svc_nb_core.h"
#include "../../util/util_time.h"
#include "../../bat/svc/svc_bat.h"
#include "../../key/svc/svc_key.h"
#include "../../util/util_data.h"
#include "svc_cloud_security.h"
#include "../../rtc/svc/svc_rtc.h"
#include "../../log/svc/svc_log.h"
#include "../../lcd/svc/svc_lcd.h"  
#include "../../pulse/svc/svc_pulse.h"
#include "../../pulse/svc/svc_pulse_protocol.h"
static S_Cloud s_cloud;

static void Cloud_Check_Upload_Data(void);
void Svc_Cloud_Dev_Event_CHECK();
/**
 * @brief: 云模块初始化
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */

void Svc_Cloud_Init(void)
{
#if AUTH_CLOUD
    Svc_Cloud_Post_Event(E_CLOUD_EVENT_AUTH);
#endif
    Svc_Cloud_Post_Event(E_CLOUD_EVENT_DEVICE_INFO_UPLOAD);
    Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_TOTAL_USAGE);
    Svc_Cloud_Protocol_Init();
    Svc_Lcd_Display_Upload_Reason(E_UR_PowerUp,6);
}

/**
 * @brief: 云模块是否忙
 * @param  {void}
 * @return {E_Result_Check} E_CHECK_OK:忙，E_CHECK_FAIL:空闲
 * @note:
 * @see:
 */
E_Result_Check Svc_Cloud_Is_Busy(void)
{
    /*有待处理的事件或正在发送的事件时返回忙*/
    if ((s_cloud.cloud_event != 0) || (s_cloud.e_cloud_sending_event != E_CLOUD_EVENT_NO))
    {
        return E_CHECK_OK;
    }
    else
    {

        return E_CHECK_FAIL;
    }
}

/**
 * @brief: 获取云模块相关数据结构体指针
 * @param  {void}
 * @return {S_Cloud_Data*} 云模块相关数据结构体指针
 * @note:
 * @see:
 */
S_Cloud *Svc_Cloud_Get_Data(void)
{
    return &s_cloud;
}

/**
 * @brief: 云事件推送
 * @return {void}
 * @note:
 * @see:
 * @param {E_Cloud_Event} cloud_event 需要推送的事件
 */
void Svc_Cloud_Post_Event(E_Cloud_Event_Enum cloud_event)
{
    S_Flash_Data *ps_flash_data;
    ps_flash_data = Svc_Flash_Get_Data();
    s_cloud.cloud_event |= cloud_event;
    s_cloud.s_manage.rsp_fail_cnt = 0;
    Svc_Nb_Faile_Reset();
    /*重置重发时间间隔*/
    s_cloud.s_manage.send_time_cnt = ps_flash_data->s_para.u16ReConnectTime;
}

/**
 * @brief: 云事件清除
 * @return {void}
 * @note:
 * @see:
 * @param {E_Cloud_Event} cloud_event 需要清除的事件
 */
void Svc_Cloud_Clear_Event(E_Cloud_Event_Enum cloud_event)
{
    /*清除云事件*/
    s_cloud.cloud_event &= ~cloud_event;
    /*清除正在发送的云事件*/
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_NO;

    // if ((s_cloud.cloud_dev_data_event == E_CLOUD_DEV_DATA_EVENT_NO) && (s_cloud.cloud_dev_info_event == E_CLOUD_DEV_INFO_EVENT_NO))
    // {
    //     /*清除失败重发次数*/
    //     s_cloud.s_manage.rsp_fail_cnt = 0;
    //     /*清除发送计时*/
    //     s_cloud.s_manage.send_time_cnt = 0;
    // }
}

void Svc_Cloud_Clear_Rsp_Cnt(void)
{
    /*清除失败重发次数*/
    s_cloud.s_manage.rsp_fail_cnt = 0;
    /*清除发送计时*/
    s_cloud.s_manage.send_time_cnt = 0;
}
/**
 * @brief: 获取所有触发的事件
 * @param  {void}
 * @return {gw_u16}  所有触发的事件
 * @note:
 * @see:
 */
gw_u16 Svc_Cloud_Get_Event(void)
{
    return s_cloud.cloud_event;
}

/**
 * @brief: 获取正在进行的事件
 * @param  {void}
 * @return {gw_u16}  正在进行的事件
 * @note:
 * @see:
 */
gw_u16 Svc_Cloud_Get_Sending_Event(void)
{
    return s_cloud.e_cloud_sending_event;
}
/**
 * @brief: 获取处于等待处理的最高优先级事件
 * @param  {void}
 * @return {E_Cloud_Event}  处于等待处理的最高优先级事件
 * @note:
 * @see:
 */
E_Cloud_Event_Enum Svc_Cloud_Get_Pending_Event(void)
{

    if ((s_cloud.cloud_event & E_CLOUD_EVENT_RSP) == E_CLOUD_EVENT_RSP)
    {
        return E_CLOUD_EVENT_RSP;
    }
#if AUTH_CLOUD
    if ((s_cloud.cloud_event & E_CLOUD_EVENT_AUTH) == E_CLOUD_EVENT_AUTH)
    {
        return E_CLOUD_EVENT_AUTH;
    }
#endif
    if ((s_cloud.cloud_event & E_CLOUD_EVENT_DEVICE_INFO_UPLOAD) == E_CLOUD_EVENT_DEVICE_INFO_UPLOAD)
    {
        return E_CLOUD_EVENT_DEVICE_INFO_UPLOAD;
    }
    if ((s_cloud.cloud_event & E_CLOUD_EVENT_DEVICE_DATA_UPLOAD) == E_CLOUD_EVENT_DEVICE_DATA_UPLOAD)
    {
        return E_CLOUD_EVENT_DEVICE_DATA_UPLOAD;
    }
    return E_CLOUD_EVENT_NO;
}

/**
 * @brief: 锁定事件，该事件状态转为发送中
 * @return {void}
 * @note: 事件被锁定后，会触发该事件的数据上报，直到该事件解锁
 * @see:
 * @param {E_Cloud_Event} cloud_event 待锁定的事件
 */
void Svc_Cloud_Lock_Event(E_Cloud_Event_Enum cloud_event)
{
    switch (cloud_event)
    {
    case E_CLOUD_EVENT_RSP:
#if AUTH_CLOUD
    case E_CLOUD_EVENT_AUTH:
        Svc_Cloud_Unlock_Dev_Data_Event();
        Svc_Cloud_Unlock_Dev_Info_Event();
        break;
#endif
    case E_CLOUD_EVENT_DEVICE_INFO_UPLOAD:
        Svc_Cloud_Unlock_Dev_Data_Event();
        break;
    case E_CLOUD_EVENT_DEVICE_DATA_UPLOAD:
        Svc_Cloud_Unlock_Dev_Info_Event();
        break;
    default:
        break;
    }
    s_cloud.e_cloud_sending_event = cloud_event;
}

/**
 * @brief: 解锁事件，正在发送中的事件转为待处理
 * @param  {void}
 * @return {void}
 * @note: 使用该函数后，事件依然存在，只不过转为待处理，有优先级更高的事件触发时可以调用该函数
 * @see:
 */
void Svc_Cloud_Unlock_All_Event(void)
{
    /*清除正在发送的云事件*/
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_NO;
    /*正在发送的云事件回退到云事件中*/
    s_cloud.cloud_dev_info_event |= s_cloud.cloud_dev_info_sending_event;
    s_cloud.cloud_dev_info_sending_event = E_CLOUD_DEV_INFO_EVENT_NO;
    s_cloud.cloud_dev_data_event |= s_cloud.cloud_dev_data_sending_event;
    s_cloud.cloud_dev_data_sending_event = E_CLOUD_DEV_DATA_EVENT_NO;
}

/**
 * @brief:检查事件是否改变
 * @return {E_Result_Check} 检查结果
 * @note: 当待检查的事件和正在发送的事件不一致时，说明事件发生了变化，可能是优先级更高的事件插入
 * @see:
 * @param {E_Cloud_Event} e_event 待检查的事件
 */
E_Result_Check Svc_Cloud_Event_Is_Changed(E_Cloud_Event_Enum e_event)
{
    if (s_cloud.e_cloud_sending_event != e_event)
    {
        return E_CHECK_OK;
    }
    switch (e_event)
    {
    case E_CLOUD_EVENT_DEVICE_INFO_UPLOAD:
        if (s_cloud.cloud_dev_info_sending_event != s_cloud.cloud_dev_info_event)
        {
            return E_CHECK_OK;
        }
        break;
    case E_CLOUD_EVENT_DEVICE_DATA_UPLOAD:
        if (s_cloud.cloud_dev_data_sending_event != s_cloud.cloud_dev_data_event)
        {
            return E_CHECK_OK;
        }
        break;
    default:
        break;
    }
    return E_CHECK_FAIL;
}

/**
 * @brief: 重发失败次数检查
 * @param  {void}
 * @return {E_Result_Check}
 * @note: 重发失败次数大于设置的重发失败次数时返回E_CHECK_FAIL
 * @see:
 */
E_Result_Check Svc_Cloud_Event_Fail_Check(void)
{
    S_Flash_Data *ps_flash_data;
    ps_flash_data = Svc_Flash_Get_Data();
    if (s_cloud.s_manage.rsp_fail_cnt > ps_flash_data->s_para.u8ReSendCnt)
    { // 数据上报服务器失败
        return E_CHECK_FAIL;
    }
    return E_CHECK_OK;
}

/**
 * @brief: 重发计时和保持网络连接计时
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Cloud_Timer_Callback(void)
{
    if (s_cloud.s_manage.send_time_cnt > 0)
    {
        s_cloud.s_manage.send_time_cnt--;
        if (s_cloud.s_manage.send_time_cnt == 0)
        { // 重发时间已到
            s_cloud.s_manage.rsp_fail_cnt++;
            Svc_Cloud_Dev_Event_CHECK();
        }
    }
}

/**
 * @name:设备信息子事件推送
 * @param {E_Cloud_Dev_Info_Event_Enum} event
 * @return {*}
 * @note:
 */
void Svc_Cloud_Post_Dev_Info_Event(E_Cloud_Dev_Info_Event_Enum event)
{
    s_cloud.cloud_dev_info_event |= event;
    Svc_Cloud_Post_Event(E_CLOUD_EVENT_DEVICE_INFO_UPLOAD);
}

/**
 * @name: 清除设备信息上报
 * @return {*}
 * @note:
 */
void Svc_Cloud_Clear_Dev_Info_Event(void)
{
    s_cloud.cloud_dev_info_event &= ~s_cloud.cloud_dev_info_sending_event;
    s_cloud.cloud_dev_info_sending_event = E_CLOUD_DEV_INFO_EVENT_NO;
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_NO;
    if (s_cloud.cloud_dev_info_event == E_CLOUD_DEV_INFO_EVENT_NO)
    {
        Svc_Cloud_Clear_Event(E_CLOUD_EVENT_DEVICE_INFO_UPLOAD);
    }
}

/**
 * @name: 锁定设备信息上报
 * @return {*}
 * @note:
 */
void Svc_Cloud_Lock_Dev_Info_Event(void)
{
    s_cloud.cloud_dev_info_sending_event = s_cloud.cloud_dev_info_event;
    s_cloud.cloud_dev_info_event = E_CLOUD_DEV_INFO_EVENT_NO;
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_DEVICE_INFO_UPLOAD;
}

/**
 * @name:
 * @return {*}
 * @note:
 */
void Svc_Cloud_Unlock_Dev_Info_Event(void)
{
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_NO;
    s_cloud.cloud_dev_info_event |= s_cloud.cloud_dev_info_sending_event;
    s_cloud.cloud_dev_info_sending_event = E_CLOUD_DEV_INFO_EVENT_NO;
}
/**
 * @name:
 * @return {*}
 * @note:
 */
gw_u16 Svc_Cloud_Get_Dev_Info_Event(void)
{
    return s_cloud.cloud_dev_info_sending_event;
}
/**
 * @name:
 * @param {E_Cloud_Dev_Data_Event_Enum} event
 * @return {*}
 * @note:
 */
void Svc_Cloud_Post_Dev_Data_Event(E_Cloud_Dev_Data_Event_Enum event)
{
    s_cloud.cloud_dev_data_event |= event;
    Svc_Cloud_Post_Event(E_CLOUD_EVENT_DEVICE_DATA_UPLOAD);
}
/**
 * @name:
 * @return {*}
 * @note:
 */
void Svc_Cloud_Clear_Dev_Data_Event(void)
{
    s_cloud.cloud_dev_data_event &= ~s_cloud.cloud_dev_data_sending_event;
    s_cloud.cloud_dev_data_sending_event = E_CLOUD_DEV_DATA_EVENT_NO;
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_NO;
    if (s_cloud.cloud_dev_data_event == E_CLOUD_DEV_DATA_EVENT_NO)
    {
        Svc_Cloud_Clear_Event(E_CLOUD_EVENT_DEVICE_DATA_UPLOAD);
    }
}

/**
 * @name:
 * @return {*}
 * @note:
 */
void Svc_Cloud_Lock_Dev_Data_Event(void)
{
    s_cloud.cloud_dev_data_sending_event = s_cloud.cloud_dev_data_event;
    s_cloud.cloud_dev_data_event = E_CLOUD_DEV_DATA_EVENT_NO;
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_DEVICE_DATA_UPLOAD;
}

void Svc_Cloud_Dev_Event_CHECK()
{
    if (s_cloud.cloud_dev_data_event != E_CLOUD_DEV_DATA_EVENT_NO)
    {
        Svc_Cloud_Post_Event(E_CLOUD_EVENT_DEVICE_DATA_UPLOAD);
        Svc_Nb_Core_Run_Post_Event(NB_EVENT_COAP_SEND);
        Svc_Log_Printf(LOG_INFO, "Resend");
    }
    if (s_cloud.cloud_dev_info_event != E_CLOUD_DEV_INFO_EVENT_NO)
    {
        Svc_Cloud_Post_Event(E_CLOUD_EVENT_DEVICE_INFO_UPLOAD);
        Svc_Nb_Core_Run_Post_Event(NB_EVENT_COAP_SEND);
        Svc_Log_Printf(LOG_INFO, "Resend");
    }
}
/**
 * @name:
 * @return {*}
 * @note:
 */
void Svc_Cloud_Unlock_Dev_Data_Event(void)
{
    s_cloud.e_cloud_sending_event = E_CLOUD_EVENT_NO;
    s_cloud.cloud_dev_data_event |= s_cloud.cloud_dev_data_sending_event;
    s_cloud.cloud_dev_data_sending_event = E_CLOUD_DEV_DATA_EVENT_NO;
}

/**
 * @name:
 * @return {*}
 * @note:
 */
gw_u16 Svc_Cloud_Get_Dev_Data_Event(void)
{
    return s_cloud.cloud_dev_data_sending_event;
}

E_Result_Check Svc_Cloud_Sub_Event_Is_Idle()
{

    if (s_cloud.cloud_dev_info_sending_event != E_CLOUD_DEV_INFO_EVENT_NO)
    {
        return E_CHECK_FAIL;
    }
    if (s_cloud.cloud_dev_data_sending_event != E_CLOUD_DEV_DATA_EVENT_NO)
    {
        return E_CHECK_FAIL;
    }
    return E_CHECK_OK;
}

/**
 * @brief: 检查是否需要上报数据
 * @param  {void}
 * @return {void}
 * @note: 周期上报检查
 * @see:
 */
static void Cloud_Check_Upload_Data(void)
{
    gw_u8 *pu8CurTime; // 年，月，日，时，分，秒
    pu8CurTime = s_cloud.s_manage.pu8CurTime;
    gw_u32 u32CurTimes;
    u32CurTimes = s_cloud.s_manage.u32CurTime;

    gw_u32 u32UploadTime;
    gw_u32 u32UploadCycle;

    S_Flash_Data *ps_flash;
    S_Flash_Device_Para *ps_device_para;
    S_Flash_Usage_Info *ps_usage_info;

    ps_flash = Svc_Flash_Get_Data();
    ps_device_para = &ps_flash->s_para;

    u32UploadCycle = ps_device_para->u32CommCycle * 60;
    ps_usage_info = &ps_flash->s_usage_info;

    // 防止校时后重报
    if (s_cloud.s_manage.u32CurTime < s_cloud.s_manage.u32LastTime)
    {
        return;
    }
    if (ps_device_para->u8DayUptimeEnable == 1)
    { /*不上报*/
        return;
    }

    if (u32UploadCycle == 86400) // 按天，周期数据随总用量按周期日上报时间点上报
    {
        if ((pu8CurTime[3] == ps_device_para->pu8DayUploadTime[0]) && (pu8CurTime[4] == ps_device_para->pu8DayUploadTime[1]))
        { // 已到日上报时间，上报周期数据（日用量，密集用量）
            if (ps_usage_info->s_day_usage.u8NbReportFlag)
            {
                ps_usage_info->s_day_usage.u8NbReportFlag = 0;
                Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_DAY_USAGE);   // 日用量
                Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_DENSE_FLOW);  // 密集用量
                Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_TOTAL_USAGE); // 总用量

                s_cloud.s_manage.u32LastCycleUploadTime = u32CurTimes;
                s_cloud.s_manage.u32LastUploadTime = u32CurTimes;
            }
        }
        else
        {
            ps_usage_info->s_day_usage.u8NbReportFlag = 1;
        }
    }

    else if (u32UploadCycle > 86400) // 按天间隔，这个间隔一定是86400整数倍，周期数据随总用量按周期日上报时间点上报
    {
        u32UploadTime = s_cloud.s_manage.u32LastCycleUploadTime + u32UploadCycle - 3600;
        if (u32UploadTime <= u32CurTimes) // 到达时间间隔的前一小时开始查是否到时间点
        {                                 /*上一次上报的时间，在上一次上报时间校准进行补偿*/
            if ((pu8CurTime[3] == ps_device_para->pu8DayUploadTime[0]) && (pu8CurTime[4] == ps_device_para->pu8DayUploadTime[1]))
            { /*已到时间点*/
                if (ps_usage_info->s_day_usage.u8NbReportFlag)
                {
                    ps_usage_info->s_day_usage.u8NbReportFlag = 0;

                    Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_DAY_USAGE);   // 日用量
                    Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_DENSE_FLOW);  // 密集用量
                    Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_TOTAL_USAGE); // 总用量
                    s_cloud.s_manage.u32LastCycleUploadTime = u32CurTimes;
                    s_cloud.s_manage.u32LastUploadTime = u32CurTimes;
                }
            }
            else
            {
                ps_usage_info->s_day_usage.u8NbReportFlag = 1;
            }
        }
    }

    else if (u32UploadCycle < 86400) // 总用量按间隔，周期数据按日上报时间点
    {
        u32UploadTime = s_cloud.s_manage.u32LastUploadTime + u32UploadCycle;
        if (u32UploadTime <= u32CurTimes)
        {
            Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_TOTAL_USAGE);
            if ((u32UploadTime + u32UploadCycle) <= u32CurTimes)
            {                                                     // 慢了二个上报周期以上
                s_cloud.s_manage.u32LastUploadTime = u32CurTimes; // 上一次周期上报时间更新为当前时间
                s_cloud.s_manage.u32LastCycleUploadTime = u32CurTimes;
            }
            else
            {
                s_cloud.s_manage.u32LastUploadTime = u32UploadTime;
                s_cloud.s_manage.u32LastCycleUploadTime = u32UploadTime;
            }
        }
        if ((pu8CurTime[3] == ps_device_para->pu8DayUploadTime[0]) && (pu8CurTime[4] == ps_device_para->pu8DayUploadTime[1]))
        { /*已到时间点，周期数据*/
            if (ps_usage_info->s_day_usage.u8NbReportFlag)
            {
                ps_usage_info->s_day_usage.u8NbReportFlag = 0;
                Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_DAY_USAGE);  // 日用量
                Svc_Cloud_Post_Dev_Data_Event(E_CLOUD_DEV_DATA_EVENT_DENSE_FLOW); // 密集用量
            }
        }
        else
        {
            ps_usage_info->s_day_usage.u8NbReportFlag = 1;
        }
    }
    if ((pu8CurTime[3] == 0) && (pu8CurTime[4] == 0)) // 没日0点0分清除报警状态及报警已上报标志
    {
        Svc_Flash_Clear_Device_Alarm(0xFFFF);
        Svc_Key_Clear_Key_UpCnt();
        Svc_Flash_Clear_AllUpload_Alarm(); // 清除所有报警已上报标志
    }
}

/**
 * @brief: u8WakeUpCnt 增加
 * @param  {void}
 * @return {void}
 * @note:  需在RTC唤醒时调用
 * @see:
 */
void Svc_Cloud_WakeUpCnt_Increase(void)
{
    s_cloud.u8WakeUpCnt++;
}

/**
 * @brief: 检查 u8WakeUpCnt
 * @param  {void}
 * @return {gw_u8}0-未达到时间  1-达到时间
 * @note:
 * @see:
 */
gw_u8 Svc_Cloud_Check_WakeUpCnt(void)
{
    if (s_cloud.u8WakeUpCnt >= Wake_Up_Check_Cnt)
    {
        s_cloud.u8WakeUpCnt = 0;
        return 1;
    }

    return 0;
}

/**
 * @brief: 时间校准
 * @return {void}
 * @note:
 * @see:
 * @param {gw_u32} 时间戳，自2000-1-1日起
 */
void Svc_Cloud_Time_Calibrate(gw_u32 u32Time)
{
    gw_s32 s32DiffTime = 0; // 云时间 - 本地时间

    gw_u8 pu8Time[6];

    s32DiffTime = (gw_s32)u32Time - s_cloud.s_manage.u32CurTime; // 与系统时间差值

    s_cloud.s_manage.u32SystemTime = u32Time;      // 更新时间戳
    Util_Time_Timestamp_To_Time(u32Time, pu8Time); // 时间戳转为日历

    if (pu8Time[0] < 23)
    { // 防止入网成功后系统下发时间为0，测试时候有发现类似问题 lida add code
        return;
    }
    Svc_Cloud_Refresh_Time();
    Svc_Cloud_SysTime_Printf();
    Svc_Cloud_Time_Set_Calibrate(); // 设置为时间已校准
    Svc_Flash_Time_Calibrate_Deal(s32DiffTime);
    Svc_Pulse_Protocol_Send_Cmd(CMD_81_SET_DEVICE_INFO,FUNC_04_CORRECT_TIME); //给模组校准时间
}

/**
 * @brief: 设置时间校准标志
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Cloud_Time_Set_Calibrate(void)
{
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    if (Svc_Cloud_Time_Is_Calibrate() == 0)
    { // 时间未校准的情况下
        ps_flash->s_other.time_manegeinit_flag = 1;
    }
}

/**
 * @brief: 时间是否已校准
 * @param  {void}
 * @return {gw_u8} 1：已校准，0：未校准
 * @note:
 * @see:
 */
gw_u8 Svc_Cloud_Time_Is_Calibrate(void)
{
    S_Flash_Data *ps_flash;
    ps_flash = Svc_Flash_Get_Data();
    return ps_flash->s_other.time_manegeinit_flag;
}

/**
 * @brief: 检查定时事件
 * @param  {void}
 * @return {void}
 * @note:
 * @see:
 */
void Svc_Cloud_Check_Timing_Event(void)
{
    /*周期上报检查,时间未校准也需要上报*/
    Cloud_Check_Upload_Data();
    if (Svc_Cloud_Time_Is_Calibrate() == 0)
    {
        return;
    }
    /*密集用量存储检查*/
    Svc_Flash_Check_Save_Dense_Usage(s_cloud.s_manage.pu8CurTime);
    Bsp_Iwdg_Feed();
    /*小时用量存储检查*/
    Svc_Flash_Check_Save_Hour_Usage(s_cloud.s_manage.pu8CurTime);
    Bsp_Iwdg_Feed();
    /*月用量存储检查*/
    Svc_Flash_Check_Save_Month_Usage(s_cloud.s_manage.pu8CurTime);
    Bsp_Iwdg_Feed();
}

/**
 * @brief: 设置通讯模组ICCID
 * @return {void}
 * @note:
 * @see:
 * @param {gw_u8} *pu8Iccid 通讯模组ICCID
 */
void Svc_Cloud_Set_Iccid(gw_u8 *pu8Iccid)
{
    S_Flash_Data *s_flash_data;
    s_flash_data = Svc_Flash_Get_Data();
    memcpy(&s_flash_data->s_para.s_nb_info.Comm_Model_Iccid, pu8Iccid, 20);
}

/**
 * @brief: 获取通讯模组ICCID
 * @return {void}
 * @note:
 * @see:
 * @param {gw_u8} *out_pu8Iccid 通讯模组ICCID
 */
void Svc_Cloud_Get_Iccid(gw_u8 *out_pu8Iccid)
{
    S_Flash_Data *s_flash_data;
    s_flash_data = Svc_Flash_Get_Data();
    memcpy(out_pu8Iccid, &s_flash_data->s_para.s_nb_info.Comm_Model_Iccid, 20);
}

/**
 * @brief: 设置保持网络连接时间
 * @return {void}
 * @note: 超时后进入休眠
 * @see:
 * @param {gw_u8} u8Time 保持网络连接时间
 */
void Svc_Cloud_Set_Keep_Alive_Time(gw_u8 u8Time)
{
    Svc_Log_Printf(LOG_INFO, "Svc_Cloud_Set_Keep_Alive_Time");
    s_cloud.s_manage.u8KeepAliveTime = u8Time;
}

void Svc_Cloud_Set_Stop_Alive_Time()
{
    s_cloud.s_manage.u8KeepAliveTime = 0;
}

/**
 * @brief: 等待下发命令
 * @param  {void}
 * @return {gw_u8} 剩余等待时间
 * @note:
 * @see:
 */
gw_u8 Svc_Cloud_Wait_Cmd(void)
{
    return s_cloud.s_manage.u8KeepAliveTime;
}

/**
 * @brief: 更新时间戳
 * @return {void}
 * @note:
 * @see:
 * @param {gw_u32} u32Time 时间戳
 */
void Svc_Cloud_Update_Time(gw_u32 u32Time)
{
    s_cloud.s_manage.u32CurTime = u32Time;
}

/**
 * @brief: 刷新时间戳
 * @return {void}
 * @note:
 * @see:
 * @param {void}
 */
void Svc_Cloud_Refresh_Time(void)
{
    Svc_Rtc_Get_Time(&s_cloud.s_manage.u32CurTime, &s_cloud.s_manage.u32LastTime);
    Util_Time_Timestamp_To_Time(s_cloud.s_manage.u32CurTime, s_cloud.s_manage.pu8CurTime);
    Util_Time_Timestamp_To_Time(s_cloud.s_manage.u32LastTime, s_cloud.s_manage.pu8LastTime);
}

/**
 * @brief: 获取当前时间戳
 * @param  {void}
 * @return {gw_u32} 当前时间戳
 * @note:
 * @see:
 */
gw_u32 Svc_Cloud_Get_Time(void)
{
    return s_cloud.s_manage.u32CurTime;
}

/**
 * @name:
 * @return {*}
 * @note:
 */
E_Result_Check Svc_Cloud_Protocol_Has_More_Check(void)
{
    S_Flash_Data *s_flash_data;
    s_flash_data = Svc_Flash_Get_Data();
    if (s_flash_data->s_para.s_nb_info.comm_info.has_more == 1)
    {
        return E_CHECK_OK;
    }
    return E_CHECK_FAIL;
}

void Svc_Cloud_Protocol_Timer_Callback()
{
    S_Flash_Data *s_flash_data;
    s_flash_data = Svc_Flash_Get_Data();
    if (s_flash_data->s_para.s_nb_info.comm_info.has_more == 1)
    {
        if (s_flash_data->s_para.s_nb_info.comm_info.has_more_cnt > 0)
        {
            s_flash_data->s_para.s_nb_info.comm_info.has_more_cnt--;
        }
        else
        {
            s_flash_data->s_para.s_nb_info.comm_info.has_more = 0;
        }
    }
    if (s_cloud.s_manage.u8KeepAliveTime > 0)
    {
        s_cloud.s_manage.u8KeepAliveTime--;
        if (s_cloud.s_manage.u8KeepAliveTime == 0)
        {
            Svc_Log_Printf(LOG_INFO, "No time");
            Svc_Cloud_Unlock_All_Event();                    // 解锁所有云事件
            Svc_Cloud_Clear_Event(E_CLOUD_EVENT_ALL);        // 清除所有云事件
            Svc_Nb_Core_Run_Clear_Event(NB_EVENT_COAP_SEND); // 清除NB发送udp数据事件
        }
    }
}
void Svc_Cloud_Time_Printf(char *PrintInfo, gw_u8 *PrintTime)
{
    Svc_Log_Printf(LOG_INFO, "%s : %d-%d-%d,%d:%d:%d \r\n", PrintInfo, PrintTime[0], PrintTime[1], PrintTime[2], PrintTime[3], PrintTime[4], PrintTime[5]);
}

void Svc_Cloud_SysTime_Printf(void)
{
    Svc_Cloud_Time_Printf("now system time", s_cloud.s_manage.pu8CurTime);
    Svc_Cloud_Time_Printf("last system time", s_cloud.s_manage.pu8LastTime);
}

E_Result_Check Svc_Cloud_Time_Check(void)
{
    if (s_cloud.s_manage.u32CurTime < s_cloud.s_manage.u32LastTime)
    {
        return E_CHECK_FAIL;
    }
    else
    {
        return E_CHECK_OK;
    }
}
