/*
 * @Author: mbw
 * @Date: 2024-10-09 08:42:14
 * @LastEditors: mbw && 1600520629@qq.com
 * @LastEditTime: 2025-01-17 10:37:54
 * @FilePath: \JT-DT-YD4N02A_RTT_MRS-NT26K\bsp\src\bsp_nt26k.c
 * @Description:
 *
 * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
 */
/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2019-12-13     qiyongzhong       first version
 */

#include <at_device_nt26k.h>
#include "drv_gpio.h"
#include "bsp_nt26k.h"
#include "user_sys.h"
#include "bsp_flash.h"
#include "bsp_h308.h"
#include "stddef.h"
#include "bsp_emv.h"
#include "bsp_rtc.h"
#include "bsp_relay.h"
#include "bsp_rng.h"

#define LOG_TAG "nt26k"
#include <at_log.h>

#if IOT_MODULE_SWITCH == 1
#define NT26K_THREAD_STACK_SIZE (4096)
#define NT26K_RECV_THREAD_STACK_SIZE (4096)
#define NT26K_LIFE_THREAD_STACK_SIZE (2048)
#define NT26K_THREAD_PRIORITY 25
#define NT26K_THREAD_TICKS 50
#define NT26K_RECV_THREAD_PRIORITY 24
#define NT26K_RECV_THREAD_TICKS 10

#define NT26K_LIFE_THREAD_PRIORITY 26
#define NT26K_LIFE_THREAD_TICKS 10

// static rt_uint32_t nt26k_status = 0;
ALIGN (RT_ALIGN_SIZE)
static char nt26k_thread_stack[NT26K_THREAD_STACK_SIZE];
static struct rt_thread nt26k_thread;

ALIGN (RT_ALIGN_SIZE)
static char nt26k_recv_thread_stack[NT26K_RECV_THREAD_STACK_SIZE];
static struct rt_thread nt26k_recv_thread;

ALIGN (RT_ALIGN_SIZE)
static char nt26k_life_thread_stack[NT26K_LIFE_THREAD_STACK_SIZE];
static struct rt_thread nt26k_life_thread;

struct rt_event at_device_event;
rt_sem_t nt26k_recv_sem;
rt_sem_t nt26k_recv_heart_sem;// 用于接收心跳信号
rt_sem_t nt26k_disconnect_sem;
static rt_timer_t nt26k_timer;              // 上报心跳
static rt_timer_t nt26k_upload_timer;       // 更新本地时间定时器
static rt_timer_t nt26k_power_error_timer;  // 上电失败情况下启动定时器

rt_uint8_t nt26k_conncet_tcp_flag;
rt_uint8_t nt26k_disconnect_pdp_flag;  // PDP断开连接标志

Nt26kEventIndex nt26k_event_index;

rt_uint8_t power_on_send_flag = 0;
rt_mutex_t nt26k_mutex;
int BSP_Nt26k_Init (struct Nt26k_Ops *ops, rt_uint8_t version);
int BSP_Nt26k_Update (struct Nt26k_Ops *ops, rt_uint8_t device_type, rt_uint8_t event_type);
int Nt26k_Send_Data (struct Nt26k_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type);
int Data_Resp (struct Nt26k_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type, char *data, rt_uint8_t res);
int Nt26k_Recv_Data (struct Nt26k_Ops *ops, char *data);

static struct DataBody body;
static struct Nt26kDataFrame frame;
static struct Nt26kRecvData nt26k_recv;

struct Nt26k_Ops nt26k_ops = {
    .body = &body,
    .frame = &frame,
    .recv = &nt26k_recv,
    .init = BSP_Nt26k_Init,
    .update_data = BSP_Nt26k_Update,
    .send = Nt26k_Send_Data,
    .Resp = Data_Resp,
    // .Recv        = Nt26k_Recv_Data,//，没用到
};

static struct at_device_nt26k _dev =
    {
        NT26K_SAMPLE_DEIVCE_NAME,
        NT26K_SAMPLE_CLIENT_NAME,

        NT26K_PWR_EN_PIN,
        NT26K_RST_PIN,
        NT26K_PWR_KEY_PIN,

        NT26K_SAMPLE_RECV_BUFF_LEN,
};

static rt_uint32_t nt26k_event_flags[kNt26kMaxEventcnt] = {0};
static rt_bool_t nt26k_event_initialized = RT_FALSE;  // 是否初始化完成

typedef enum
{

    NT26K_PRIORITY_LOWEST,   // 4、优先级最低（定时心跳、浓度异常、报警触发、报警解除、传感器故障触发 传感器故障解除）
    NT26K_PRIORITY_MEDIUM,   // 2、优先级第三高 自检触发
    NT26K_PRIORITY_HIGH,     // 1、优先级第二高  掉电
    NT26K_PRIORITY_HIGHEST,  // 0 优先级最高(设备上电时的定时心跳)
} Nt26kPriority;

typedef struct
{
    Nt26kEvent event_flag;
    Nt26kPriority priority;
    const char *event_name;
    int (*send_func) (struct at_device *device, void *param);
} Nt26kEventInfo;

static void Nt26k_Set_Event (Nt26kEvent event_type)
{
    if (event_type < kNt26kMaxEventcnt)
    {
        nt26k_event_flags[event_type] = (1 << event_type);
    }
}

void Nt26k_Event_Init (void)
{
    rt_err_t ret = rt_event_init (&at_device_event, "nt26k_event", RT_IPC_FLAG_PRIO);
    if (ret == RT_EOK)
    {
        nt26k_event_initialized = RT_TRUE;
        for (Nt26kEvent event = kNt26kHeartbeatEvent; event < kNt26kMaxEventcnt; event++)
        {
            Nt26k_Set_Event (event);
        }
    }
    else
    {
        LOG_E ("nt26k_event init failed!");
    }
}

rt_uint32_t Nt26k_Get_Event_Flag (Nt26kEvent event_type)
{
    if (event_type < kNt26kMaxEventcnt)
    {
        return nt26k_event_flags[event_type];
    }
    return 0;
}

void Nt26k_Send_Event (Nt26kEvent event_type)
{
    LOG_D ("Send_Nt26k_Event = %d", event_type);
    nt26k_event_index.last_event = nt26k_event_index.current_event;
    nt26k_event_index.current_event = event_type;
    if (nt26k_event_initialized == RT_TRUE)
    {
        rt_event_send (&at_device_event, Nt26k_Get_Event_Flag (event_type));
    }
    else
    {
        LOG_E ("nt26k_event_initialized is false");
    }
}

// 定义定时器回调函数
static void Nt26k_Ht_Timer_Cb (void *parameter)
{
    Nt26k_Send_Event (kNt26kHeartbeatEvent);
}

// 定时器回调函数,当1分钟内没有数据交互时，关闭tcp连接
static void Nt26k_Error_Timer_Cb (void *parameter)
{
    if (power_on_send_flag)  // 上电成功时，停止定时器
    {
        rt_timer_stop (nt26k_power_error_timer);
    }
    else
    {
        Nt26k_Send_Event (kNt26kPowerOnEvent);
    }
}

int _Pack_Send (struct Nt26k_Ops *ops, char *buf)
{
    char nt26k_send_buf[512] = {0};  // 发送缓冲区，用于存储最终发送的数据
                                     //    char byteArr1[512];             // 转换成字节值
    unsigned short crc16 = 0;        // 存储CRC16校验和

    struct at_device *device = at_device_get_by_name (AT_DEVICE_NAMETYPE_NETDEV, NT26K_SAMPLE_DEIVCE_NAME);
    ASSERT (device);
    crc16 = crc1021 (buf, rt_strlen (buf));
    LOG_D ("buf: %s", buf);
    LOG_D ("crc16: %X", crc16);
    // 将数据、校验和及尾部标识添加到发送缓冲区中
    if (rt_snprintf (nt26k_send_buf, sizeof (nt26k_send_buf),
                     "%s%04X%02X%02X%02X",
                     buf,
                     crc16,
                     ops->frame->tail[0],
                     ops->frame->tail[1],
                     ops->frame->tail[2]) >= sizeof (nt26k_send_buf))
    {
        // 发生缓冲区溢出
        LOG_E ("Buffer overflow in nt26k_send_buf");
        return -RT_ERROR;
    }
    // 打印调试信息
    // LOG_D("nt26k_send_buf: %s", nt26k_send_buf);
    rt_uint16_t data_len = rt_strlen (nt26k_send_buf);
    // 通过AT指令发送数据给NT26K模块
    if (at_send_data (device, nt26k_send_buf, data_len / 2) != RT_EOK)
    {
        return -RT_ERROR;
    }

    return RT_EOK;
}

/**
 * @brief 发送数据到nt26k模块
 *
 * 本函数根据提供的数据和参数构建一个格式化字符串，计算其CRC16校验和，
 * 然后将该字符串发送给NT26K模块
 *@param version 协议版本
 * @param data 要发送的十六进制数据字符串
 * @param len 数据字符串的十六进制数据格式长度
 * @param data_num 数据编号
 * @param cmd_num 命令编号
 * @return int 返回0表示成功，非零表示失败
 */
static int _Send_Handle (struct Nt26k_Ops *ops, rt_size_t data_num, rt_size_t cmd_num, const char *data)
{
    // 临时缓冲区，用于格式化数据
    char data_buf[512] = {0};
    rt_size_t data_len = rt_strlen (data);

    // 格式化数据，构建发送给NT26K模块的数据包
    rt_int32_t len = rt_snprintf (data_buf, sizeof (data_buf),
                                  "%02X%02X%02X%02X%04X%04X%02X%04X%s",
                                  ops->frame->header[0],
                                  ops->frame->header[1],
                                  ops->frame->header[2],
                                  ops->frame->version,      // 协议版本
                                  ops->frame->manufacture,  // 制造商ID
                                  data_num,
                                  cmd_num,
                                  data_len / 2,
                                  data);
    if (len < 0 || len >= sizeof (data_buf))
    {
        LOG_E ("Send Data buffer overflow");
        return -RT_ERROR;
    }

    // LOG_D("data_buf: %s", data_buf);

    return _Pack_Send (ops, data_buf);
}

// 初始化函数
int BSP_Nt26k_Init (struct Nt26k_Ops *ops, rt_uint8_t version)
{
    if (ops->frame == RT_NULL)
    {
        LOG_E ("Memory allocation failed");
        return -RT_ENOMEM;
    }
    rt_memset (ops->frame, 0, sizeof (struct Nt26kDataFrame));

    ops->frame->header[0] = 0x4A;
    ops->frame->header[1] = 0x54;
    ops->frame->header[2] = 0x34;

    ops->frame->version = version;
    ops->frame->manufacture = DEVICE_MANUFACTURE;

    ops->frame->tail[0] = 0x42;
    ops->frame->tail[1] = 0x4A;
    ops->frame->tail[2] = 0x51;

    return RT_EOK;
}

// 更新函数
int BSP_Nt26k_Update (struct Nt26k_Ops *ops, rt_uint8_t device_type, rt_uint8_t event_type)
{
    ops->body->device_type = device_type;
    ops->body->event_type = event_type;
    ops->body->hw = (rt_uint8_t)Flash_Get_SysCfg (kHwVerId);
    ops->body->sw = (rt_uint8_t)Flash_Get_SysCfg (kSwVerId);
    rt_memcpy (ops->body->imei, &nt26k, sizeof (nt26k_sys_info));                            // 直接赋值结构体数据
    rt_memcpy (&(ops->body->lel), &H308.Data, (rt_ubase_t)offsetof (TsH308Data, checksum));  // 复制除了校验码以外的数据
    ops->body->product_work_temperature = ops->body->temp;                                   // 暂时定为激光器测量的环境温度
    ops->body->work_duration = work_duration;
    ops->body->device_status = device_state_flag;
    ops->body->emv_status = emv_state_flag;
    ops->body->relay_status = relay_state_flag;

    return RT_EOK;
}

int Nt26k_Send_Data (struct Nt26k_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type)
{
    int ret = 0;
    char data_buf[512] = {0};
    char temp[3];  // 临时缓冲区，用于存储每个字节的十六进制表示

    if (ops == NULL || ops->body == NULL)
    {
        // 处理 ops 或 ops->body 为 NULL 的情况
        return RT_ERROR;  // 或者抛出异常，返回错误码等
    }

    if (sizeof (struct DataBody) == 0)
    {
        data_buf[0] = '\0';  // 确保 data_buf 被正确初始化
        return RT_ERROR;
    }
    rt_memset (ops->body, 0, sizeof (struct DataBody));
    rt_mutex_take (nt26k_mutex, RT_WAITING_FOREVER);
    ret = nt26k_ops.update_data (ops, device_type, event_type);
    if (ret == RT_EOK)
    {
        for (int i = 0; i < sizeof (struct DataBody); i++)
        {
            rt_snprintf (temp, sizeof (temp), "%02X", ((rt_uint8_t *)ops->body)[i]);
            rt_memcpy (data_buf + i * 2, temp, 2);
        }
        ret = _Send_Handle (ops, data_num, cmd, data_buf);
        if (ret != RT_EOK)
        {
            ret = -ret;
        }
    }
    rt_mutex_release (nt26k_mutex);
    return ret;
}

int Data_Resp (struct Nt26k_Ops *ops, rt_uint8_t data_num, rt_uint8_t cmd, rt_uint8_t device_type, rt_uint8_t event_type, char *data, rt_uint8_t res)
{
    if (nt26k_conncet_tcp_flag != 1)
    {
        LOG_E ("nt26k_conncet_tcp_flag error");
        return -RT_ERROR;
    }

    char data_buf[512] = {0};

    rt_int32_t len = rt_snprintf (data_buf, sizeof (data_buf), "%02X%02X%30s%02X", device_type, event_type, data, res);
    if (len < 0 || len >= sizeof (data_buf))
    {
        LOG_E ("Resp Data buffer overflow");
        return -RT_ERROR;
    }
    // LOG_D("data_buf: %s", data_buf);
    return _Send_Handle (ops, data_num, cmd, data_buf);
}

int Nt26k_Recv_Data (struct Nt26k_Ops *ops, char *data)
{
    // ops->body = (struct DataBody *)rt_malloc(sizeof(struct DataBody));
    // rt_memset(ops->body, 0, sizeof(struct DataBody));
    // rt_free(ops->body);
    return RT_EOK;
}

/***************************************发送处理函数************************************************ */
/**
 * 处理定时心跳事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Heartbeat (struct at_device *device, void *param)
{

    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    int ret = 0;

    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }
    ret = device->class->device_ops->control (device, AT_DEVICE_CTRL_GET_SIGNAL, RT_NULL);
    if (ret != RT_EOK)
    {
        LOG_E ("nt26k get signal failed\n");
        return -RT_ERROR;
    }
    ret = nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_DATA_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_HEARTBEAT);
    if (ret != RT_EOK)
    {
        LOG_E ("nt26k send data failed\n");
        return ret;
    }

    return RT_EOK;
}

/**
 * 处理时间校准事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Time_Calibration (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_TIME_CALIBRATION, DEVICE_TYPE_NT26K, EVENT_TYPE_TIME_CALIBRATION))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", CMD_TYPE_TIME_CALIBRATION);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理报警事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Alarm (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_ALARM))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_ALARM);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理报警恢复事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Alarm_Recover (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_ALARM_RECOVER))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_ALARM_RECOVER);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理故障事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Fault (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_FAULT))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_FAULT);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理故障恢复事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Fault_Recover (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_FAULT_RECOVER))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_FAULT_RECOVER);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理自检事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Self_Check (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_SELF_CHECK))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_SELF_CHECK);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理消音事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Silence (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_SILENCE))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_SILENCE);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理异常事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Exception (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_EXCEPTION))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_EXCEPTION);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理电磁阀状态改变事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Valve_Status (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_VALVE_STATUS))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_VALVE_STATUS);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理风扇状态改变事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Fan_Status (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_FAN_STATUS))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_FAN_STATUS);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理温度异常事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Temp_Anomaly (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_TEMP_ANOMALY))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_TEMP_ANOMALY);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理断电事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Power_Off (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_POWER_OFF))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_POWER_OFF);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理断电事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Power_On (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_POWER_ON))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_POWER_ON);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/**
 * 处理设备故障事件
 * @param device 设备结构体指针
 * @param param 操作结构体指针
 * @return 操作结果
 */
int Nt26k_Send_Device_Failure (struct at_device *device, void *param)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    if ((device == RT_NULL) || (nt26k_ops == RT_NULL))
    {
        LOG_E ("nt26k param error\n");
        return RT_ERROR;
    }

    if (nt26k_ops->send (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_DEVICE_EVENT_REPORT, DEVICE_TYPE_NT26K, EVENT_TYPE_DEVICE_FAILURE))
    {
        LOG_E ("nt26k send cmd[%X] failed\n", EVENT_TYPE_DEVICE_FAILURE);
        return -RT_ERROR;
    }
    return RT_EOK;
}

/*这个【4、优先级最低当同时触发后，相同服务直接合并】暂时还没想好怎么做，
思路感觉就是得重新开一个线程，然后再开一个任务队列，将所有的事件，发送到任务队列
在线程中，对任务队列进行查看并处理，看目前都有哪些事件，是处于那个优先级得，如果是最低优先级，就只发送一帧数据就行了，
如果是不同优先级，按照优先级顺序发送事件，但感觉这样会使得程序更复杂，本来发送就很快，感觉没必要这样搞*/
const Nt26kEventInfo nt26k_event_info[] = {
    {kNt26kPowerOnEvent,         NT26K_PRIORITY_HIGHEST, "上电心跳事件",          Nt26k_Send_Power_On        },
    {kNt26kPowerDownEvent,       NT26K_PRIORITY_HIGH,    "掉电事件",                Nt26k_Send_Power_Off       },
    {kNt26kSelfCheckEvent,       NT26K_PRIORITY_MEDIUM,  "自检事件",                Nt26k_Send_Self_Check      },
    {kNt26kHeartbeatEvent,       NT26K_PRIORITY_LOWEST,  "定时心跳事件",          Nt26k_Send_Heartbeat       },
    {kNt26kTempAnomalyEvent,     NT26K_PRIORITY_LOWEST,  "温度异常事件",          Nt26k_Send_Temp_Anomaly    },
    {kNt26kAlarmEvent,           NT26K_PRIORITY_LOWEST,  "报警触发事件",          Nt26k_Send_Alarm           },
    {kNt26kAlarmRcyEvent,        NT26K_PRIORITY_LOWEST,  "报警解除事件",          Nt26k_Send_Alarm_Recover   },
    {kNt26kFaultEvent,           NT26K_PRIORITY_LOWEST,  "传感器故障事件",       Nt26k_Send_Fault           },
    {kNt26kFaultRcyEvent,        NT26K_PRIORITY_LOWEST,  "传感器故障解除事件", Nt26k_Send_Fault_Recover   },
    {kNt26kTimeCalibrationEvent, NT26K_PRIORITY_LOWEST,  "时间校准事件",          Nt26k_Send_Time_Calibration},
    {kNt26kSilenceEvent,         NT26K_PRIORITY_LOWEST,  "消音事件",                Nt26k_Send_Silence         },
    {kNt26kExceptionEvent,       NT26K_PRIORITY_LOWEST,  "异常事件",                Nt26k_Send_Exception       },
    {kNt26kValveStatusEvent,     NT26K_PRIORITY_LOWEST,  "电磁阀状态改变事件", Nt26k_Send_Valve_Status    },
    {kNt26kFanStatusEvent,       NT26K_PRIORITY_LOWEST,  "风机状态改变事件",    Nt26k_Send_Fan_Status      },
    {kNt26kDeviceFailureEvent,   NT26K_PRIORITY_LOWEST,  "设备失效事件",          Nt26k_Send_Device_Failure  }
};

/**
 * 处理NT26K设备的事件
 * @param nt26k_recv_event 接收到的NT26K事件标志
 * @return
 */
int Nt26k_Process_Events (Nt26kEvent nt26k_recv_event, struct at_device *device, void *param)
{
    rt_uint8_t max_retry_count = (rt_uint8_t)Flash_Get_SysCfg (kIotRetryId);
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)param;
    const Nt26kEventInfo *event = RT_NULL;

    for (size_t i = 0; i < sizeof (nt26k_event_info) / sizeof (Nt26kEventInfo); ++i)
    {
        // 检查当前事件是否在接收到的事件标志中
        if (nt26k_recv_event == nt26k_event_info[i].event_flag)
        {
            event = &nt26k_event_info[i];
            break;
        }
    }

    if (event)  // 处理该事件
    {
        // 打印事件的名称
        LOG_D ("%s上报\n", event->event_name);
        for (size_t i = 0; i < max_retry_count; i++)
        {
            if (nt26k_conncet_tcp_flag)
            {
                if (event->send_func)
                {
#ifdef TEST_ENABLE
                    RTC_ShowTime();  // 每次发送打印下时间，容易定位问题
#endif
                    // 如果事件有关联的发送函数，则调用该发送函数
                    rt_thread_mdelay (IMEI_Delay());
                    int result = event->send_func (device, nt26k_ops);
                    if (result != RT_EOK)
                    {
                        LOG_E ("nt26k send cmd failed\n");
                    }
                    else
                    {
                        if (rt_strcmp (event->event_name, "定时心跳事件") == RT_EOK)//定时心跳是有回应的
                        {
                           if (rt_sem_take(nt26k_recv_heart_sem, 5000) == RT_EOK)
                            {
                                LOG_D ("收到心跳回复\n");
                                return RT_EOK;  // 函数执行完毕，返回0
                            }
                            else
                            {
                                LOG_E ("nt26k send cmd failed\n");//收不到说明断网了，重连下10s后再发送
                                nt26k_conncet_tcp_flag = 0;
                                rt_sem_release (nt26k_disconnect_sem);
                                rt_thread_mdelay (5000);
                                continue;
                            }
                        }
                        else  if (rt_strcmp (event->event_name, "掉电事件") == RT_EOK)//定时心跳是有回应的
                        {
                            if (device->class->device_ops->control (device, AT_DEVICE_RF_CLOSE, RT_NULL) == RT_EOK)
                            {
                                LOG_D("关闭模组");
                            }
                        }
                        else
                        {
                            return RT_EOK;  // 函数执行完毕，返回0
                        }
                    }     
                }
            }
            else
            {
                LOG_D ("断网\n");
                rt_sem_release (nt26k_disconnect_sem);
            }
            rt_thread_mdelay (5000);
        }
    }
    // 函数执行完毕，返回0
    return RT_EOK;
}

// 比较帧头和帧尾
int Compare_HeaderToTail (struct Nt26k_Ops *ops)
{
    // 比较帧头
    for (int i = 0; i < 3; i++)
    {
        if (ops->frame->header[i] != ops->recv->header[i])
        {
            LOG_E ("ops->frame->header[%x] != ops->recv->header[%x]\n", ops->frame->header[i], ops->recv->header[i]);

            return -1;
        }
    }

    // 比较帧尾
    for (int i = 0; i < 3; i++)
    {
        if (ops->frame->tail[i] != ops->recv->tail[i])
        {
            LOG_E ("ops->frame->tail[%x] != ops->recv->tail[%x]\n", ops->frame->tail[i], ops->recv->tail[i]);

            return -2;
        }
    }
    if (ops->recv->recv_data.res_num != RESPONSE_CODE_SUCCESS)  // 判断是否为成功响应
    {
        LOG_E ("ops->recv->recv_data.res_num[%x] != RESPONSE_CODE_SUCCESS\n", ops->recv->recv_data.res_num);

        return -3;
    }
    return RT_EOK;
}

void Handle_Server_Reply (struct Nt26k_Ops *ops)
{
    if ((ops->recv->recv_data.event_type == INSTRUCTION_HEART_BEAT) || (ops->recv->recv_data.event_type == EVENT_TYPE_POWER_ON))
    {
        LOG_D ("nt26k send data success\n");
    }
}

void Handle_Self_Check (struct Nt26k_Ops *ops)
{
    LOG_D ("服务器下发自检指令\n");
    char imei[16] = {0};
    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    LOG_D ("imei:%s\n", imei);

    char temp[32] = "0";
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串
    LOG_D ("temp: %s", temp);
    Send_Laser_Alarm_Event (kSelfCheckEvent);
    rt_thread_mdelay (100);
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_SELF_CHECK, temp, RESPONSE_CODE_SUCCESS);
}

void Handle_Mute (struct Nt26k_Ops *ops)
{
    LOG_D ("服务器下发消音指令\n");

    char imei[16] = {0};
    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    char temp[32] = "0";
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串

    Send_Laser_Alarm_Event (KMuteEvent);
    rt_thread_mdelay (100);
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_MUTE, temp, RESPONSE_CODE_SUCCESS);
}

void Handle_Close_Valve (struct Nt26k_Ops *ops)
{
    LOG_D ("服务器下发关闭阀门指令\n");

    char imei[16] = {0};
    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    char temp[32] = "0";
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串
    EMV_CLOSE_VALVE;
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_CLOSE_VALVE, temp, RESPONSE_CODE_SUCCESS);
}

void Handle_Open_Valve (struct Nt26k_Ops *ops)
{
    LOG_D ("服务器下发打开阀门指令\n");

    // char imei[16] = {0};
    // Get_IotImei(imei, FLASH_IOT_IMEI_LEN);
    // char temp[32] = "0";
    // String2Hex(temp, imei); // 将字符串转为十六进制字符串

    // // rt_uint8_t ret = BSP_Set_Emv_Status(1);
    // emv_state_flag = 1; // 电磁阀动作
    // rt_thread_mdelay(20);
    // emv_state_flag = 0;

    // ops->Resp(ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_OPEN_VALVE, temp, RESPONSE_CODE_SUCCESS);
}

void Handle_Open_Relay (struct Nt26k_Ops *ops)
{
    LOG_D ("服务器下发打开继电器指令\n");

    char imei[16] = {0};
    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    char temp[32] = "0";
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串
    relay_state_flag = 1;
    rt_thread_mdelay (10);
    // rt_uint8_t ret = BSP_Set_Relay_Status(0);
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_OPEN_RELAY, temp, RESPONSE_CODE_SUCCESS);
}

void Handle_Close_Relay (struct Nt26k_Ops *ops)
{
    LOG_D ("服务器下发关闭继电器指令\n");

    char imei[16] = {0};
    char temp[32] = "0";

    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串

    relay_state_flag = 0;
    rt_thread_mdelay (100);
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_CLOSE_RELAY, temp, RESPONSE_CODE_SUCCESS);
}

void Handle_Query_Params (struct Nt26k_Ops *ops)
{
    rt_uint8_t data[10] = {0};
    char str[64] = {0};
    LOG_D ("服务器下发查询系统参数\n");

    rt_memcpy (data, (rt_uint8_t *)FLASH_HW_VER_ADDR, sizeof (sys_config_info) - 50);
    LOG_D ("hw_ver:%02x sw_ver:%02x alarm_low:%02x alarm_high:%02x temp_alarm:%02x iot_upload_cycle:%dmin retry:%02x emagnetic:%02X relay_switch:%02X\n",
           data[0], data[1], data[2], data[3], data[4], ((data[5]) | (data[6] << 8)), data[7], data[8], data[9]);

    rt_sprintf (str, "0000000000%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
                data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9]);
    rt_thread_mdelay (100);  // 释放下线程
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_QUERY_PARAMS, str, RESPONSE_CODE_SUCCESS);
}

int Handle_Config_Params (struct Nt26k_Ops *ops)
{
    char data_buf[32] = {0};
    rt_uint8_t recv_data[16] = {0};
    rt_uint8_t flash_info[16] = {0};
    char imei[16] = {0};
    char temp[32] = "0";

    LOG_D ("服务器下发配置参数\n");

    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串

    rt_memset (data_buf, '0', 32);
    rt_memcpy (recv_data, (ops->recv->recv_data.res_data + 5), sizeof (sys_config_info) - 50);
    rt_memcpy (flash_info, (rt_uint8_t *)FLASH_HW_VER_ADDR, sizeof (sys_config_info) - 50);

    LOG_D ("hw_ver:%02x sw_ver:%02x alarm_low:%02x alarm_high:%02x temp_alarm:%02x iot_upload_cycle:%d min retry:%02x emagnetic:%02X relay_switch:%02X\n",
           flash_info[0], flash_info[1], flash_info[2], flash_info[3], flash_info[4], (flash_info[5] | (flash_info[6] << 8)), flash_info[7], flash_info[8], recv_data[9]);
    LOG_D ("recv_data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n",
           recv_data[0], recv_data[1], recv_data[2], recv_data[3], recv_data[4],
           recv_data[5], recv_data[6], recv_data[7], recv_data[8], recv_data[9],
           recv_data[10], recv_data[11], recv_data[12], recv_data[13], recv_data[14], recv_data[15]);
    LOG_D ("data:%s\n", data_buf);

    for (rt_uint8_t i = 0; i < (sizeof (sys_config_info) - 50); i++)
    {
        LOG_D ("recv_data[%d] = %d", i, recv_data[i]);
        if (recv_data[i] != flash_info[i])
        {
            if ((recv_data[2] > 25) || (recv_data[2] < 5)) /*家报的报警设定值应在5%~25%之间*/
            {
                if (ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_ACTION_FAILURE) == RT_EOK)
                {
                    LOG_W ("recv_data[3] :%d", recv_data[3]);
                    LOG_W ("配置参数超出范围，请核实后重试\n");
                }
                return RT_EOK;
            }
            else  // 如果没有超出，再写入信息
            {
                if (BSP_Flash_Write_Info (recv_data, sizeof (sys_config_info) - 50) != 0)
                {
                    rt_uint16_t iot_upload_time = (uint16_t)Flash_Get_SysCfg (kIotUploadCycleId);
                    unsigned long timeout = iot_upload_time * 60 * RT_TICK_PER_SECOND;
                    // rt_timer_stop(nt26k_timer);
                    rt_timer_control (nt26k_timer, RT_TIMER_CTRL_SET_TIME, (void *)&timeout);  // 更新上报周期
                    // rt_timer_control(nt26k_timer, RT_TIMER_CTRL_GET_TIME, &timeout);
                    // LOG_D("timeout:%d", timeout/1000/60);
                    rt_timer_start (nt26k_timer);
                    LOG_D ("上报周期由%dmin更新为%dmin", ((flash_info[5] << 8) | flash_info[6]), iot_upload_time);
                    if (ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_SUCCESS) == RT_EOK)
                    {
                        LOG_D ("配置参数写入成功\n");
                    }
                    return RT_EOK;
                }
                else
                {
                    LOG_D ("配置参数写入失败\n");
                    if (ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_ACTION_FAILURE) == RT_EOK)
                    {
                        LOG_D ("写入失败响应成功\n");
                    }
                    return RT_ERROR;
                }
            }
        }
    }
    if (ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_CONFIG_PARAMS, temp, RESPONSE_CODE_SUCCESS) == RT_EOK)
    {
        LOG_D ("配置参数没有变化\n");
    }
    return RT_EOK;
}

void Handle_Time_Calibration_Data (struct Nt26k_Ops *ops)
{
    rt_uint8_t data[10] = {0};
    TsRtcDateTime rtc_dt;
    char imei[16] = {0};
    char temp[32] = "0";

    LOG_D ("时间校准数据\n");

    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串

    rt_memcpy (data, ops->recv->recv_data.res_data, sizeof (data));

    // 提取后4个字节作为时间戳
    time_t timestamp = (data[6] << 24) | (data[7] << 16) | (data[8] << 8) | data[9];
    Timestamp_To_Rtc_DateTime (timestamp, &rtc_dt);
    // 打印结果
    LOG_I ("时间: %04d-%02d-%02d %02d:%02d:%02d (星期%d)\n",
           rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second, rtc_dt.week);
    RTC_SetTime (rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, 0); /* Setup Time */
    rt_thread_mdelay (100);                                                             // 释放下线程
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_TIME_CALIBRATION, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_TIME_CALIBRATION, temp, RESPONSE_CODE_SUCCESS);
}

// 下发修改服务器地址指令
void Handle_Sever_Addr_Set (struct Nt26k_Ops *ops)
{
    rt_uint8_t data[6] = {0};
    char imei[16] = {0};
    char temp[32] = "0";

    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串
    rt_memcpy (data, (ops->recv->recv_data.res_data + 9), FLASH_SERVER_LEN);
    LOG_D ("data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x", 0, data[0], 1, data[1], 2, data[2], 3, data[3], 4, data[4], 5, data[5]);
    Flash_Set_Sever_Data (data);
    if (Flash_Get_Sever_Data (&sever_info) != RT_EOK)
    {
        LOG_E ("服务器地址修改失败\n");
    }
    else
    {
        LOG_D ("服务器地址修改成功\n");
        ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_SEVER_ADDR, temp, RESPONSE_CODE_SUCCESS);
    }
}

void Handle_Error (struct Nt26k_Ops *ops, rt_err_t ret)
{
    LOG_E ("数据帧解析失败，错误码: %d", ret);

    char imei[16] = {0};
    char temp[32] = "0";

    Get_IotImei (imei, FLASH_IOT_IMEI_LEN);
    String2Hex (temp, imei);  // 将字符串转为十六进制字符串
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, ops->recv->cmd, temp, RESPONSE_CODE_PARSE_FAIL);
}

void Handle_Instruction_Down (struct Nt26k_Ops *ops)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)ops;

    switch (nt26k_ops->recv->recv_data.event_type)
    {
    case INSTRUCTION_DOWN_SELF_CHECK:
        Handle_Self_Check (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_MUTE:
        Handle_Mute (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_CLOSE_VALVE:
        Handle_Close_Valve (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_OPEN_VALVE:
        Handle_Open_Valve (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_OPEN_RELAY:
        Handle_Open_Relay (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_CLOSE_RELAY:
        Handle_Close_Relay (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_QUERY_PARAMS:
        Handle_Query_Params (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_CONFIG_PARAMS:
        Handle_Config_Params (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_TIME_CALIBRATION:
        Handle_Time_Calibration_Data (nt26k_ops);
        break;
    case INSTRUCTION_DOWN_SEVER_ADDR:
        Handle_Sever_Addr_Set (nt26k_ops);
        break;
    }
}

void Handle_Time_Calibration (struct Nt26k_Ops *ops)
{
    rt_uint8_t data[10] = {0};
    LOG_D ("服务器下发时间校准数据\n");
    rt_memcpy (data, ops->recv->recv_data.res_data, sizeof (data));
    TsRtcDateTime rtc_dt;
    // 提取后4个字节作为时间戳
    time_t timestamp = (data[6] << 24) | (data[7] << 16) | (data[8] << 8) | data[9];
    Timestamp_To_Rtc_DateTime (timestamp, &rtc_dt);
    // 打印结果
    LOG_I ("时间: %04d-%02d-%02d %02d:%02d:%02d (星期%d)\n",
           rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second, rtc_dt.week);
    RTC_SetTime (rtc_dt.year, rtc_dt.month, rtc_dt.day, rtc_dt.hour, rtc_dt.minute, rtc_dt.second); /* Setup Time */
    ops->Resp (ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, INSTRUCTION_DOWN_TIME_CALIBRATION, NT26K_DEFIENE_DATA, RESPONSE_CODE_SUCCESS);
}

void Handle_Cmd_Type (struct Nt26k_Ops *ops)
{
    struct Nt26k_Ops *nt26k_ops = (struct Nt26k_Ops *)ops;

    switch (nt26k_ops->recv->cmd)
    {
    case CMD_TYPE_SERVER_REPLY:
        Handle_Server_Reply (nt26k_ops);
        break;
    case CMD_TYPE_INSTRUCTION_DOWN:
        Handle_Instruction_Down (nt26k_ops);
        break;
    case CMD_TYPE_TIME_CALIBRATION:
        Handle_Time_Calibration (nt26k_ops);
        break;
    default:
        nt26k_ops->Resp (nt26k_ops, DATA_SERIAL_NUM, CMD_TYPE_INSTRUCTION_REPLY, DEVICE_TYPE_NT26K, ops->recv->cmd, NT26K_DEFIENE_DATA, RESPONSE_CODE_PARSE_FAIL);
        break;
    }
}

void Analyze_Recv_Frame (struct at_device *device, struct Nt26k_Ops *ops)
{
    rt_err_t ret = RT_EOK;

    ret = Compare_HeaderToTail (ops);
    if (ret == RT_EOK)
    {
        Handle_Cmd_Type (ops);
    }
    else
    {
        Handle_Error (ops, ret);
    }
}

/*
上电模式
发送一包数据后，转换到检测模式 120分钟发送一次数据
当有事件发生时，发送一包事件数据包
*/
static void Nt26k_Send_Thread_Entry (void *param)
{
    rt_err_t result = RT_EOK;
    rt_uint32_t nt26k_recv_event;
    LOG_D ("nt26k thread entry\n");

    struct Nt26k_Ops *ops = (struct Nt26k_Ops *)param;
    struct at_device_nt26k *nt26k = &_dev;
    struct at_device *device = at_device_get_by_name (AT_DEVICE_NAMETYPE_NETDEV, nt26k->device_name);
    RT_ASSERT (device);

    if (ops->init (ops, PROTOCOL_VERSION) != RT_EOK)
    {
        LOG_E ("nt26k init failed\n");
    }
    else
    {
        LOG_D ("nt26k init success\n");
        rt_completion_wait (&nt26k_init_complate, RT_WAITING_FOREVER);  // wait for nt26k init finish
        Nt26k_Send_Event (kNt26kPowerOnEvent);
    }
    while (1)
    {
        result = rt_event_recv (&at_device_event,
                                Nt26k_Get_Event_Flag (kNt26kPowerOnEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kHeartbeatEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kSelfCheckEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kSilenceEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kExceptionEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kValveStatusEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kFanStatusEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kTempAnomalyEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kPowerOnEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kPowerDownEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kAlarmEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kAlarmRcyEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kFaultEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kFaultRcyEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kDeviceFailureEvent) |
                                    Nt26k_Get_Event_Flag (kNt26kTimeCalibrationEvent),
                                RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
                                RT_WAITING_FOREVER, &nt26k_recv_event);  // 这个事件一般是设备端发生了变化，发送到服务器时调用

        if (result == RT_EOK)
        {
            if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kPowerOnEvent))
            {
                result = Nt26k_Process_Events (kNt26kPowerOnEvent, device, ops);  // 当上电心跳包发送不成功时，其他事件不启动
                if (result)
                {
                    power_on_send_flag = 0;
                    rt_timer_start (nt26k_power_error_timer);  // 启动重连定时器， 3min一次，直到发送成功
                    LOG_E ("nt26k send data failed result = [%d]\n", result);
                }
                else
                {
                    rt_timer_start (nt26k_timer);         // 当上电心跳包发送成功时, 开始心跳包周期发送

                    rt_timer_start (nt26k_upload_timer);  // 周期修改时间更新
                    power_on_send_flag = 1;
                }
            }
            if (power_on_send_flag)
            {
                if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kHeartbeatEvent))
                {
                    result = Nt26k_Process_Events (kNt26kHeartbeatEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kTimeCalibrationEvent))
                {
                    Time_Calibration (device);
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kAlarmEvent))
                {
                    result = Nt26k_Process_Events (kNt26kAlarmEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kAlarmRcyEvent))
                {
                    result = Nt26k_Process_Events (kNt26kAlarmRcyEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kFaultEvent))
                {
                    if (device_state_flag != 1)  // 当设备失效时，只上报失效信息
                    {
                        result = Nt26k_Process_Events (kNt26kFaultEvent, device, ops);
                        if (result)
                        {
                            LOG_E ("nt26k send data failed result = [%d]\n", result);
                        }
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kFaultRcyEvent))
                {
                    result = Nt26k_Process_Events (kNt26kFaultRcyEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kSelfCheckEvent))
                {
                    result = Nt26k_Process_Events (kNt26kSelfCheckEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kSilenceEvent))
                {
                    result = Nt26k_Process_Events (kNt26kSilenceEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kExceptionEvent))
                {
                    result = Nt26k_Process_Events (kNt26kExceptionEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kValveStatusEvent))
                {
                    result = Nt26k_Process_Events (kNt26kValveStatusEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kFanStatusEvent))
                {
                    result = Nt26k_Process_Events (kNt26kFanStatusEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kTempAnomalyEvent))
                {
                    result = Nt26k_Process_Events (kNt26kTempAnomalyEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kPowerDownEvent))
                {
                    nt26k_event_initialized = RT_FALSE;  // 当接收到掉电事件时，发送完成后删除事件，不再接收其他事件
                    result = Nt26k_Process_Events (kNt26kPowerDownEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
                else if (nt26k_recv_event & Nt26k_Get_Event_Flag (kNt26kDeviceFailureEvent))
                {
                    result = Nt26k_Process_Events (kNt26kDeviceFailureEvent, device, ops);
                    if (result)
                    {
                        LOG_E ("nt26k send data failed result = [%d]\n", result);
                    }
                }
            }
        }
    }
}

static void Nt26k_Recv_Thread_Entry (void *parameter)
{
    struct Nt26k_Ops *ops = (struct Nt26k_Ops *)parameter;
    struct at_device_nt26k *nt26k = &_dev;
    struct at_device *device = at_device_get_by_name (AT_DEVICE_NAMETYPE_NETDEV, nt26k->device_name);
    RT_ASSERT (device);

    LOG_D ("nt26k recv thread entry\n");

    while (1)
    {
        rt_sem_take (nt26k_recv_sem, RT_WAITING_FOREVER);  // 这个主要用来处理的数据
        /*对数据帧进行分析，判断所处的是对服务器响应还是指令下发*/
        Analyze_Recv_Frame (device, ops);
    }
}

static void Nt26k_Life_Thread_Entry (void *parameter)
{

    struct at_device_nt26k *nt26k = &_dev;
    struct at_device *device = at_device_get_by_name (AT_DEVICE_NAMETYPE_NETDEV, nt26k->device_name);
    RT_ASSERT (device);
    rt_err_t ret;
    rt_uint32_t delay_n = 1;
    rt_uint32_t delay_t = 80000;

    LOG_D ("nt26k_life_thread entry\n");

    while (1)
    {
        ret = rt_sem_take (nt26k_disconnect_sem, RT_WAITING_FOREVER);
        if (ret == RT_EOK)
        {
            if (!nt26k_conncet_tcp_flag)
            {
                LOG_D ("重连网络中...\n");
                at_response_t resp = at_create_resp (64, 0, 5000);
                if (resp == RT_NULL)
                {
                    LOG_E ("No memory for response structure!");
                    at_delete_resp (resp);
                }
                if (device->class->device_ops->control (device, AT_DEVICE_CTRL_POWER_OFF, RT_NULL) == RT_EOK)
                {
                    LOG_D("AT device power off success");
                    rt_thread_mdelay(1000);
                    if (device->class->device_ops->control (device, AT_DEVICE_CTRL_POWER_ON, RT_NULL) == RT_EOK)
                    {
                         LOG_D("AT device power on success");
                         /* disable echo */
                        at_obj_exec_cmd(device->client, resp, "ATE0");
                        /*AT+QICFG="dataformat"  设置收发模式*/
                        if (at_obj_exec_cmd (device->client, resp, "AT+QICFG=\"dataformat\",%d,%d", AT_NSONMI_MODE_DEFAULT, AT_NSONMI_MODE_DEFAULT) != RT_EOK)
                        {
                            LOG_E ("AT+QICFG=\"dataformat\" error\n");
                        }
                        /*设置显示模式*/
                        if (at_obj_exec_cmd (device->client, resp, "AT+QICFG=\"viewmode\",1") != RT_EOK)
                        {
                            LOG_E ("AT+QICFG=\"viewmode\" error\n");
                        }
                        /*设置保活信息*/
                        if (at_obj_exec_cmd (device->client, resp, "AT+QICFG=\"tcp/keepalive\",1,10000,100,10") != RT_EOK)
                        {
                            LOG_E ("AT+QICFG=\"tcp/keepalive\" error\n");
                        }
                        if (at_obj_exec_cmd (device->client, resp, "AT+QICFG=\"passiveclosed\",1") != RT_EOK)
                        {
                            LOG_E ("AT+QICFG=\"passiveclosed\" error\n");
                        }
                        if (at_obj_exec_cmd (device->client, resp, "AT+CGACT=1,1") != RT_EOK)
                        {
                            LOG_E ("AT+CGACT=1,1 error\n");
                        }
                        if (device->class->device_ops->control (device, AT_DEVICE_CTRL_NET_CONN, RT_NULL) == RT_EOK)
                        {
                            LOG_D ("重连网络成功\n");
                            nt26k_conncet_tcp_flag = RT_TRUE;
                            delay_n =0;
                        }
                        else
                        {
                            delay_t = (rt_uint32_t)(2^(delay_n - 1) * delay_t);
                            LOG_D ("重连网络失败,等待%d s后重连\n", delay_t);
                            rt_thread_mdelay (delay_t);
                            delay_n++;
                            rt_sem_release (nt26k_disconnect_sem);
                        }
                        at_delete_resp (resp);
                    }
                }
            }
            else
            {
                delay_n = 0;
            }
        }
    }
}


// 定时器回调函数,当1分钟内没有数据交互时，关闭tcp连接
static void Nt26k_Upload_Timer_Cb (void *parameter)
{
    Nt26k_Send_Event (kNt26kTimeCalibrationEvent);  // 更新下时间
}

int BSP_Nt26k_Thread_Init (void)
{
    rt_err_t ret;

    Nt26k_Event_Init();
    rt_uint32_t iot_upload_time = (uint16_t)Flash_Get_SysCfg (kIotUploadCycleId);
    unsigned long timeout = iot_upload_time * 60 * RT_TICK_PER_SECOND;
    LOG_I ("上报服务器周期：%d分钟", iot_upload_time);
    nt26k_mutex = rt_mutex_create ("nt26k_mutex", RT_IPC_FLAG_PRIO);
    if (nt26k_mutex == RT_NULL)
    {
        LOG_E ("nt26k_mutex create failed");
    }
    nt26k_recv_sem = rt_sem_create ("nt26k_recv", 0, RT_IPC_FLAG_PRIO);
    if (nt26k_recv_sem == RT_NULL)
    {
        LOG_E ("nt26k_recv_sem create failed");
    }
    nt26k_recv_heart_sem = rt_sem_create ("nt26k_recv_heart", 0, RT_IPC_FLAG_PRIO);
    if (nt26k_recv_heart_sem == RT_NULL)
    {
        LOG_E ("nt26k_recv_heart_sem create failed");
    }
    nt26k_disconnect_sem = rt_sem_create ("nt26k_life", 0, RT_IPC_FLAG_PRIO);
    if (nt26k_disconnect_sem == RT_NULL)
    {
        LOG_E ("nt26k_disconnect_sem create failed");
    }
    // 创建定时器
    nt26k_timer = rt_timer_create ("heartbeat",
                                   Nt26k_Ht_Timer_Cb,        // 回调函数
                                   RT_NULL,                  // 参数
                                   timeout,                  // 定时周期（120分钟）
                                   RT_TIMER_FLAG_PERIODIC);  // 周期性定时器

    if (nt26k_timer == RT_NULL)
    {
        rt_kprintf ("创建定时器失败\n");
        return -1;
    }
    nt26k_power_error_timer = rt_timer_create ("nt26k_error_timer",
                                               Nt26k_Error_Timer_Cb,
                                               RT_NULL,
                                               3 * 60 * RT_TICK_PER_SECOND,  // （3分钟）
                                               RT_TIMER_FLAG_PERIODIC);
    nt26k_upload_timer = rt_timer_create ("nt26k_upload_timer",
                                          Nt26k_Upload_Timer_Cb,
                                          RT_NULL,
                                          24 * 60 * 60 * RT_TICK_PER_SECOND,
                                          RT_TIMER_FLAG_PERIODIC);

    ret = rt_thread_init (&nt26k_thread,
                          "nt26k_send_thread",
                          Nt26k_Send_Thread_Entry,
                          &nt26k_ops,
                          &nt26k_thread_stack[0],
                          sizeof (nt26k_thread_stack),
                          NT26K_THREAD_PRIORITY,
                          NT26K_THREAD_TICKS);
    rt_thread_startup (&nt26k_thread);

    ret = rt_thread_init (&nt26k_recv_thread,
                          "nt26k_recv_thread",
                          Nt26k_Recv_Thread_Entry,
                          &nt26k_ops,
                          &nt26k_recv_thread_stack[0],
                          sizeof (nt26k_recv_thread_stack),
                          NT26K_RECV_THREAD_PRIORITY,
                          NT26K_RECV_THREAD_TICKS);
    rt_thread_startup (&nt26k_recv_thread);

    ret = rt_thread_init (&nt26k_life_thread,
                          "nt26k_life_thread",
                          Nt26k_Life_Thread_Entry,
                          &nt26k_ops,
                          &nt26k_life_thread_stack[0],
                          sizeof (nt26k_life_thread_stack),
                          NT26K_LIFE_THREAD_PRIORITY,
                          NT26K_LIFE_THREAD_TICKS);
    rt_thread_startup (&nt26k_life_thread);

    return ret;
}

// INIT_APP_EXPORT(BSP_Nt26k_Thread_Init);

static int nt26k_device_register (void)
{
    struct at_device_nt26k *nt26k = &_dev;

    return at_device_register (&(nt26k->device),
                               nt26k->device_name,
                               nt26k->client_name,
                               AT_DEVICE_CLASS_NT26K,
                               (void *)nt26k);
}

INIT_COMPONENT_EXPORT(nt26k_device_register);

#endif  // IOT_MODULE_SWITCH
