/*
 * hy_protocol.c
 *
 *  Created on: 2024年10月11日
 *      Author: psx
 */

#include "hy_protocol.h"
#include <string.h>
#include "inflash.h"
#include "pdebug.h"
#include "mppt_control.h"
#include <stdlib.h>
#include "task.h"
#include "tim.h"


HY_default_Value HY_defaultValue = {0x68\
                            , 0x48, 0x59, 0x30, 0x30, 0x30, 0x31\
                            , 0x00, 0x00, 0x00, 0x01\
                            , 0x16};

/* 读取串口数据时用该数组解析 */
static uint8_t rs485_buff[100]={0x00};


/* 电池状态数据报 */
static void HY_MsgProcFunc_batteryStatus(device_handle device, void *pMsg, uint32_t MsgLen);
/* 电量统计数据报 */
static void HY_MsgProcFunc_electricityStatistics(device_handle device, void *pMsg, uint32_t MsgLen);
/* 传感器号码配置 */
static void HY_MsgProcFunc_sensorNumberConfiguration(device_handle device, void *pMsg, uint32_t MsgLen);
/* 传感器号码查询 */
static void HY_MsgProcFunc_sensorNumberInquiry(device_handle device, void *pMsg, uint32_t MsgLen);
/* 充电阈值电压配置 */
static void HY_MsgProcFunc_chargingThresholdVoltageConfiguration(device_handle device, void *pMsg, uint32_t MsgLen);
/* 充电域值电压查询 */
static void HY_MsgProcFunc_chargingRangeVoltageQuery(device_handle device, void *pMsg, uint32_t MsgLen);
/* 复位指令 */
static void HY_MsgProcFunc_resetInstruction(device_handle device, void *pMsg, uint32_t MsgLen);

/* 充电控制配置 */
static void HY_MsgProcFunc_chargingControlConfiguration(device_handle device, void *pMsg, uint32_t MsgLen);
/* 充电控制查询 */
static void HY_MsgProcFunc_chargingControlQuery(device_handle device, void *pMsg, uint32_t MsgLen);

/* 配置协议类型 */
static void HY_MsgProcFunc_configureProtocolType(device_handle device, void *pMsg, uint32_t MsgLen);
///* 响应配置协议类型 */
//static void HY_MsgProcFunc_batteryStatus(device_handle device, void *pMsg, uint32_t MsgLen);

/* 查询电池控制盒当前配置 */
static void HY_MsgProcFunc_queryControlBoxConfiguration(device_handle device, void *pMsg, uint32_t MsgLen);
/* 查询电池控制盒软件版本 */
static void HY_MsgProcFunc_querySoftwareVersion(device_handle device, void *pMsg, uint32_t MsgLen);
/* 进入配置模式 */
static void HY_MsgProcFunc_enterConfigurationMode(device_handle device, void *pMsg, uint32_t MsgLen);

/* 配置控制盒硬件ID号 */
static void HY_MsgProcFunc_configureHardwareID(device_handle device, void *pMsg, uint32_t MsgLen);
/* 控制盒硬件ID号及通信ID号(原传感器号)查询 */
static void HY_MsgProcFunc_hardwareID_communicationIDQuery(device_handle device, void *pMsg, uint32_t MsgLen);
/* 修改通信ID号(原传感器号) */
static void HY_MsgProcFunc_modifyCommunicationID(device_handle device, void *pMsg, uint32_t MsgLen);
/* 查询主板温度值 */
static void HY_MsgProcFunc_checkMotherboardTemperature(device_handle device, void *pMsg, uint32_t MsgLen);


/* 功能码处理表 */
HY_FuncionMsgProcTable g_hyMsgTbl[] =
{
    {HY_batteryStatus,                          HY_MsgProcFunc_batteryStatus},
    {HY_electricityStatistics,                  HY_MsgProcFunc_electricityStatistics},
    {HY_sensorNumberConfiguration,              HY_MsgProcFunc_sensorNumberConfiguration},
    {HY_sensorNumberInquiry,                    HY_MsgProcFunc_sensorNumberInquiry},
    {HY_chargingThresholdVoltageConfiguration,  HY_MsgProcFunc_chargingThresholdVoltageConfiguration},
    {HY_chargingRangeVoltageQuery,              HY_MsgProcFunc_chargingRangeVoltageQuery},
    {HY_resetInstruction,                       HY_MsgProcFunc_resetInstruction},
    {HY_chargingControlConfiguration,           HY_MsgProcFunc_chargingControlConfiguration},
    {HY_chargingControlQuery,                   HY_MsgProcFunc_chargingControlQuery},
    {HY_configureProtocolType,                  HY_MsgProcFunc_configureProtocolType},
//    {HY_responseConfigureProtocolType,          HY_MsgProcFunc_batteryStatus},
    {HY_queryControlBoxConfiguration,           HY_MsgProcFunc_queryControlBoxConfiguration},
    {HY_querySoftwareVersion,                   HY_MsgProcFunc_querySoftwareVersion},
    {HY_enterConfigurationMode,                 HY_MsgProcFunc_enterConfigurationMode},
    {HY_configureHardwareID,                    HY_MsgProcFunc_configureHardwareID},
    {HY_hardwareID_communicationIDQuery,        HY_MsgProcFunc_hardwareID_communicationIDQuery},
    {HY_modifyCommunicationID,                  HY_MsgProcFunc_modifyCommunicationID},
    {HY_checkMotherboardTemperature,            HY_MsgProcFunc_checkMotherboardTemperature},
};

/**
  * @brief  检测485总线是否繁忙
  * @param
  * @retval 1 繁忙
  *         0 空闲
  */
uint8_t Check_485_bus_busy(device_handle device)
{
    if (device == g_bat485_uart3_handle) {
        USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
    } else {
        USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);
    }

    uint16_t num_ago = ring_queue_length(device);
    Delay_Ms(2);
    uint16_t num_now = ring_queue_length(device);

    if (device == g_bat485_uart3_handle) {
        USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
    } else {
        USART_ITConfig(USART4, USART_IT_RXNE, DISABLE);
    }

    if (num_now == num_ago) {
        return 0;
    }
    return 1;
}

/**
  * @brief  校验算法
  * @param  采用累加和取反的校验方式,将终端号码、传感器号码、控制字、数据长度和数据区的所有字节进行算术累加,抛弃高位,只保留最后单字节,将单字节取反;
  * @retval
  */
uint8_t HY_CheckFunc(uint8_t *arr_buff, uint8_t len)
{
    uint8_t temp = 0x00;
    uint32_t sum = 0x00;

    for(uint8_t i = 0; i < len; i++) {
        sum += *arr_buff++;
    }

    temp = (~sum) & 0xff;

    return temp;
}

/**
  * @brief  匹配设备地址
  * @param  address     地址
  * @retval 1 匹配成功
  *         0 匹配失败
  */
static int HY_matchhardwareID(u_int8_t hardwareID[6])
{
//    if (!strcmp(address, g_slConfigInfo.address)) {
//        log_info("Match_address fail \r\n");
//        return 1;
//    }
    if ((hardwareID[0] == g_slConfigInfo.address[0]) && \
            (hardwareID[1] == g_slConfigInfo.address[1]) && \
            (hardwareID[2] == g_slConfigInfo.address[2]) && \
            (hardwareID[3] == g_slConfigInfo.address[3]) && \
            (hardwareID[4] == g_slConfigInfo.address[4]) && \
            (hardwareID[5] == g_slConfigInfo.address[5]) && \
            (hardwareID[6] == g_slConfigInfo.address[6])) {
        log_info("Match_address success \r\n");
        return 1;
    }
    return 0;
}

/**
  * @brief  匹配广播地址
  * @param  address     地址
  * @retval 1 匹配成功
  *         0 匹配失败
  */
static int Match_Broadcastaddress(u_int8_t address[6])
{
    if (address[0] == 0xFF && \
        address[1] == 0xFF && \
        address[2] == 0xFF && \
        address[3] == 0xFF && \
        address[4] == 0xFF && \
        address[5] == 0xFF && \
        address[6] == 0xFF) {
        log_info("Match_Broadcastaddress success\r\n");
        return 1;
    }
    return 0;
}

/**
  * @brief  读取串口数据
  * @param  uart_handle 串口句柄
  * @param  buff        缓冲区
  * @param  buff_size   缓冲区长度
  * @retval
  */
static int HY_uart_read_climate_pack(device_handle uart_handle,uint8_t *buff, uint32_t buff_size)
{
    uint32_t offset = 0;
    uint32_t len = 0;
    uint8_t flag_run = 0;
    char c = 0;

    HY_Recv_pack *pack = (HY_Recv_pack *)buff;

    buff_size--; //预留一个'\0'位置
    for (; offset < buff_size;){
        if (ring_queue_length(uart_handle) == 0) {
            break;
        }

        c = uart_dev_in_char(uart_handle);

        buff[offset++] = c;

        /* 匹配起始标志位 */
        if (offset == HY_analyzeStartFlag || (flag_run > 0)) {
            if (pack->start_Flag != HY_defaultValue.start_Flag) {
                memcpy(buff, buff+1, offset-1);
                offset--;
                continue;
            }
        }

        /* 匹配硬件ID  */
        if (offset == HY_analyzeHardwareID || (flag_run > 1)) {
            if (HY_matchhardwareID(pack->hardwareID) || Match_Broadcastaddress(pack->hardwareID)) {
                if (flag_run < 1) {
                    flag_run = 1;
                }
                memcpy(buff, buff+1, offset-1);
                offset--;
                continue;
            }
        }




    }

    return 0;
}

/**
  * @brief  处理一条消息
  * @param
  * @retval
  */
static void HY_FRT_MsgHandler(device_handle device, uint8_t *pMsg, uint32_t MsgLen)
{
    HY_Recv_pack *pack = (HY_Recv_pack *)pMsg;

    for (u_int16_t i = 0; i < sizeof(g_hyMsgTbl) / sizeof(HY_FuncionMsgProcTable); i++){
        if (pack->controlWord == g_hyMsgTbl[i].msgId){
            g_hyMsgTbl[i].pMsgProc(device, pMsg, MsgLen);
        }
    }
}


/**
  * @brief  读取并解析串口数据
  * @param
  * @retval
  */
void HY_read_and_process_uart_data(device_handle device)
{
//    printf("ring_queue_length = %d \n", ring_queue_length(device));
//    if (ring_queue_length(device) > 10) {uart_dev_char_present(device_handle device)
    if (uart_dev_char_present(device)) {
        Delay_Ms(20);
//        printf("ring_queue_length = %d \n", ring_queue_length(device));
        memset(rs485_buff, 0, sizeof(rs485_buff));
        int ret = HY_uart_read_climate_pack(device, rs485_buff, sizeof(rs485_buff));
        if(ret > 0){
            HY_FRT_MsgHandler(device, rs485_buff, ret);
        }
    }
}












/* 电池状态数据报 */
void HY_MsgProcFunc_batteryStatus(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 电量统计数据报 */
void HY_MsgProcFunc_electricityStatistics(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 传感器号码配置 */
void HY_MsgProcFunc_sensorNumberConfiguration(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 传感器号码查询 */
void HY_MsgProcFunc_sensorNumberInquiry(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 充电阈值电压配置 */
void HY_MsgProcFunc_chargingThresholdVoltageConfiguration(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 充电域值电压查询 */
void HY_MsgProcFunc_chargingRangeVoltageQuery(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 复位指令 */
void HY_MsgProcFunc_resetInstruction(device_handle device, void *pMsg, uint32_t MsgLen)
{

}


/* 充电控制配置 */
void HY_MsgProcFunc_chargingControlConfiguration(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 充电控制查询 */
static void HY_MsgProcFunc_chargingControlQuery(device_handle device, void *pMsg, uint32_t MsgLen)
{

}


/* 配置协议类型 */
void HY_MsgProcFunc_configureProtocolType(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

///* 响应配置协议类型 */
//static void HY_MsgProcFunc_batteryStatus(device_handle device, void *pMsg, uint32_t MsgLen);

/* 查询电池控制盒当前配置 */
void HY_MsgProcFunc_queryControlBoxConfiguration(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 查询电池控制盒软件版本 */
void HY_MsgProcFunc_querySoftwareVersion(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 进入配置模式 */
void HY_MsgProcFunc_enterConfigurationMode(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 配置控制盒硬件ID号 */
void HY_MsgProcFunc_configureHardwareID(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 控制盒硬件ID号及通信ID号(原传感器号)查询 */
void HY_MsgProcFunc_hardwareID_communicationIDQuery(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 修改通信ID号(原传感器号) */
void HY_MsgProcFunc_modifyCommunicationID(device_handle device, void *pMsg, uint32_t MsgLen)
{

}

/* 查询主板温度值 */
void HY_MsgProcFunc_checkMotherboardTemperature(device_handle device, void *pMsg, uint32_t MsgLen)
{

}