/*
 * zl_protocol.c
 *
 *  Created on: 2024年6月20日
 *      Author: psx
 */

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

default_Value defaultValue = {'S', 'L'\
        , 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\
        , POWERBOX\
        , RS485
        , 0x16};

SL_Mppt_para g_Mppt_Para = {0};

/* 静态函数申明 */
static void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Update_Profile(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Remote_Upgrade(device_handle device, void *pMsg, uint32_t MsgLen);

//static uint16_t SL_ReadRegisterRegistrationStatus(void *pMsg);
//static uint16_t SL_ReadRegisteraddress(void *pMsg);
//static uint16_t SL_ReadRegisterAccessNodeType(void *pMsg);
//static uint16_t SL_ReadRegisterCommunicationMethods(void *pMsg);
static uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg);
static uint16_t SL_ReadRegisterChargCurrent(void *pMsg);
static uint16_t SL_ReadRegisterDischargCurrent(void *pMsg);
static uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg);
static uint16_t SL_ReadRegisterHighSideMosTemperature(void *pMsg);
static uint16_t SL_ReadRegisterDischargMosState(void *pMsg);
static uint16_t SL_ReadRegisterMPPTMode(void *pMsg);

//static uint16_t SL_WriteRegisterRegistrationStatus(void *pMsg);
//static uint16_t SL_WriteRegisteraddress(void *pMsg);
//static uint16_t SL_WriteRegisterAccessNodeType(void *pMsg);
//static uint16_t SL_WriteRegisterCommunicationMethods(void *pMsg);
//static uint16_t SL_WriteRegisterBatteryVoltage(void *pMsg);
//static uint16_t SL_WriteRegisterBatterytemperature(void *pMsg);
//static uint16_t SL_WriteRegisterRemainingBatteryBower(void *pMsg);
//static uint16_t SL_WriteRegisterSolarOpenCircuitVoltage1(void *pMsg);
//static uint16_t SL_WriteRegisterSolarOpenCircuitVoltage2(void *pMsg);

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

/* 一次最多读写的寄存器个数，由设备决定 */
#define Register_Number_Max 5
/* 寄存器个数，由设备决定 */
#define MPPT_Register_Number 5
/* 读写的寄存器的最大起始位置，由设备决定 */
#define Register_Start_Address_Max 0x0200

/* 用于解析串口包时的长度 */
#define analyzeStartFlag 2      //长度为2时解析起始标志
#define analyzeAddress 9        //长度为9时解析地址
#define analyzeFunctionCode 10  //长度为10时解析功能码
#define analyzeWritelen 14      //功能码为写入寄存器且buffer长度为14时，可以解析出写入寄存器包的长度


/* 功能码处理表 */
SL_FuncionMsgProcTable g_MsgTbl[] =
{
    {SL_Function_Code_Read_Register,        SL_MsgProcFunc_Read_Register},
    {SL_Function_Code_Write_Register,       SL_MsgProcFunc_Write_Register},
    {SL_Function_Code_Broadcast_Scan,       SL_MsgProcFunc_Broadcast_Scan},
    {SL_Function_Code_Registration_request, SL_MsgProcFunc_Registration_request},
    {SL_Function_Code_Update_Profile,       SL_MsgProcFunc_Update_Profile},
    {SL_Function_Code_Remote_Upgrade,       SL_MsgProcFunc_Remote_Upgrade},
};

/* 寄存器处理表 */
SL_RegProcTable g_RegTblR[] =
{
//    {SL_Register_Registration_Status,           SL_ReadRegisterRegistrationStatus},
//    {SL_Register_address,                       SL_ReadRegisteraddress},
//    {SL_Register_Access_Node_Type,              SL_ReadRegisterAccessNodeType},
//    {SL_Register_Communication_Methods,         SL_ReadRegisterCommunicationMethods},
    {SL_Register_Battery_Voltage,               SL_ReadRegisterBatteryVoltage},
    {SL_Register_Charg_Current,                 SL_ReadRegisterChargCurrent},
    {SL_Register_Discharg_Current,              SL_ReadRegisterDischargCurrent},
    {SL_Register_Solar_Open_Circuit_Voltage,    SL_ReadRegisterSolarOpenCircuitVoltage},
    {SL_Register_HighSideMos_Temperature,       SL_ReadRegisterHighSideMosTemperature},
    {SL_Register_DischargMos_State,             SL_ReadRegisterDischargMosState},
    {SL_Register_MPPT_Mode,                     SL_ReadRegisterMPPTMode},
};

/* 寄存器处理表 */
SL_RegProcTable g_RegTblW[] =
{
//    {SL_Register_Registration_Status,           SL_WriteRegisterRegistrationStatus},
//    {SL_Register_address,                       SL_WriteRegisteraddress},
//    {SL_Register_Access_Node_Type,              SL_WriteRegisterAccessNodeType},
//    {SL_Register_Communication_Methods,         SL_WriteRegisterCommunicationMethods},
//    {SL_Register_Battery_Voltage,               SL_WriteRegisterBatteryVoltage},
//    {SL_Register_Battery_temperature,           SL_WriteRegisterBatterytemperature},
//    {SL_Register_Remaining_Battery_Bower,       SL_WriteRegisterRemainingBatteryBower},
//    {SL_Register_Solar_Open_Circuit_Voltage1,   SL_WriteRegisterSolarOpenCircuitVoltage1},
//    {SL_Register_Solar_Open_Circuit_Voltage2,   SL_WriteRegisterSolarOpenCircuitVoltage2},
};





/**
  * @brief  校验算法
  * @param
  * @retval
  */
uint16_t CheckFunc(uint8_t *arr_buff, uint8_t len)
{
    uint16_t crc = 0xFFFF;
    uint16_t i, j;
    for (j = 0; j < len; ++j) {
        crc = crc ^ (*arr_buff++);
        for (i = 0; i < 8; ++i) {
            if ((crc&0x0001) > 0) {
                crc = crc >> 1;
                crc = crc ^ 0xa001;
            }
            else {
                crc = crc >> 1;
            }
        }
    }
    return crc;
}

/**
  * @brief  随机延时函数,延时区间100-2500ms，分辨率10ms  
  * @param
  * @retval 延时时间
  */
int randomDelay()
{
    int minSeconds = 10;
    int maxSeconds = 250;
//    srand(SystemCoreClock);//time(NULL)替换为对应操作系统时钟
    srand(TIM_GetCounter(TIM4));
    int delaySeconds = minSeconds + rand() % (maxSeconds - minSeconds + 1);
    return delaySeconds * 10;
}

/**
  * @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
  */
void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
    SL_Mppt_Rorecv_pack *rpack = (SL_Mppt_Rorecv_pack *)pMsg;

    uint16_t Register_Number_16 = chang_8_to_16(rpack->read_Register_Number_L,rpack->read_Register_Number_H);
    if (Register_Number_16 > Register_Number_Max) {
        log_error(" Register_Number error:%x \r\n", Register_Number_16);
        return;
    }

    uint16_t Start_Address_16 = chang_8_to_16(rpack->read_Register_Start_Address_L,rpack->read_Register_Start_Address_H);
    if (Start_Address_16 > Register_Start_Address_Max) {
        log_error(" Register_Start_Address error : %x \r\n", Start_Address_16);
        return;
    }

    /* 读取寄存器数据 */
//    uint8_t reply_Data_Content[2 * 5] = {0};
    uint16_t reply_Data_Content[Register_Number_Max] = {0};
    for ( uint16_t pos = 0;  pos < Register_Number_16; pos++) {
        for (uint16_t var = 0; var < sizeof(g_RegTblR) / sizeof(SL_RegProcTable); var++) {
            if (g_RegTblR[var].regId == (Start_Address_16 + pos)) {
//                *(uint16_t *)&reply_Data_Content[pos * 2] = g_RegTblR[var].pRegProc(NULL);
                reply_Data_Content[pos] = g_RegTblR[var].pRegProc(NULL);
            }
        }
    }

    /* 打包 */
    memset(rs485_buff, 0, sizeof(rs485_buff));
    uint8_t *replay_pack = rs485_buff;
//    strlcpy(replay_pack, g_slConfigInfo.start_Flag, 2);
    *(replay_pack) =  g_slConfigInfo.start_Flag[0];
    *(replay_pack + 1) =  g_slConfigInfo.start_Flag[1];

    replay_pack += 2;
//    strlcpy(replay_pack, g_slConfigInfo.address, 7);
    *(replay_pack)     =  g_slConfigInfo.address[0];
    *(replay_pack + 1) =  g_slConfigInfo.address[1];
    *(replay_pack + 2) =  g_slConfigInfo.address[2];
    *(replay_pack + 3) =  g_slConfigInfo.address[3];
    *(replay_pack + 4) =  g_slConfigInfo.address[4];
    *(replay_pack + 5) =  g_slConfigInfo.address[5];
    *(replay_pack + 6) =  g_slConfigInfo.address[6];


    replay_pack += 7;
    *replay_pack = SL_Function_Code_Read_Register;

    replay_pack += 1;
//    *(uint16_t *)&replay_pack = rpack->read_Register_Number;
    *replay_pack = (Register_Number_16 >> 8);
    *(replay_pack + 1) = (Register_Number_16);

    replay_pack += 2;
    for (uint8_t var = 0; var < Register_Number_16 * 2; var++) {
        if (0 == (var & 0x01)) {
            *(replay_pack + var) = (reply_Data_Content[var / 2] >> 8);
        } else {
            *(replay_pack + var) = (reply_Data_Content[var / 2]);
        }
    }

    replay_pack += Register_Number_16 * 2;
    uint16_t crc_temp = CheckFunc(rs485_buff, (2 + 7 + 1 + 2 + Register_Number_16 * 2));
//    log_info("CheckFunc crc_temp: %x  \r\n", crc_temp);
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    replay_pack += 1;
    *replay_pack = g_slConfigInfo.end_Flag;

    while (1) {
        Delay_Ms(randomDelay());
        if (!Check_485_bus_busy(device)) {
//            log_info("pack : %s", (uint8_t *)&replay_pack);

//            uart_dev_write(device, (uint8_t *)&replay_pack, 16 + Register_Number_16 * 2 + 1);
            uart_dev_write(device, rs485_buff, 16 + Register_Number_16 * 2);

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

            break;
        }
    }
}


void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
    SL_Mppt_Worecv_pack *wpack = (SL_Mppt_Worecv_pack *)pMsg;
    uint8_t *buff = (uint8_t *)pMsg;

    uint16_t Register_Number = \
            chang_8_to_16(wpack->write_Register_Number_L, wpack->write_Register_Number_H);
    if (Register_Number > Register_Number_Max) {
        log_error(" Register_Number error:%x \r\n", Register_Number);
        return;
    }

    uint16_t Register_Start_Address = \
            chang_8_to_16(wpack->write_Register_Start_Address_L, wpack->write_Register_Start_Address_H);
    if (Register_Start_Address > Register_Start_Address_Max) {
        log_error(" Register_Start_Address error : %x \r\n", Register_Start_Address);
        return;
    }

    printf("in write register \n");

    uint16_t content[Register_Number_Max] = {0};

    for (uint16_t var = 0; var < Register_Number; var++) {
        content[var] = buff[14 + 2 * var] << 8 | buff[14 + 2 * var + 1];
    }

    for ( uint16_t pos = 0;  pos < Register_Number; pos++) {
        for (uint16_t i = 0; i < sizeof(g_RegTblW) / sizeof(SL_RegProcTable); i++) {
            if (g_RegTblW[i].regId == (Register_Start_Address + pos)) {
                g_RegTblW[i].pRegProc(&content[pos]);
            }
        }
    }
}

void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t MsgLen)
{
    g_recvBroadcastDevice = device;
    g_recvBroadcastRegisterNumber = MPPT_Register_Number;

    RegistrationRequestFlag = 1;

    /* 任务创立后，立即执行一次  */
    TimeSliceOffset_Register(&m_recvbroadcast, Task_recvbroadcast \
            , recvbroadcast_reloadVal, recvbroadcast_offset);
    m_recvbroadcast.runFlag = 1;
}

void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen)
{
    log_info("Registration success \r\n");
    recvbroadcast_flag = 1;
    RegistrationRequestFlag = 0;
    TimeSliceOffset_Unregister(&m_recvbroadcast);
    SL_Mppt_RegistrationReply_pack *rpack = (SL_Mppt_RegistrationReply_pack *)pMsg;
    g_Mppt_Para.Registration_Status = chang_8_to_16(rpack->registration_Status_L, rpack->registration_Status_H);

    /* 20s内不再接收广播帧 */
    TimeSliceOffset_Register(&m_sensorEnableBroadcast, Task_sensorEnableBroadcast
            , sensorEnableBroadcast_reloadVal, sensorEnableBroadcast_offset);
}


void SL_MsgProcFunc_Update_Profile(device_handle device, void *pMsg, uint32_t MsgLen)
{
    SL_Mppt_SOther_pack SUpdateProfile_pack = {0};

    SUpdateProfile_pack.start_Flag[0] = g_slConfigInfo.start_Flag[0];
    SUpdateProfile_pack.start_Flag[1] = g_slConfigInfo.start_Flag[1];

    SUpdateProfile_pack.address[0] = g_slConfigInfo.address[0];
    SUpdateProfile_pack.address[1] = g_slConfigInfo.address[1];
    SUpdateProfile_pack.address[2] = g_slConfigInfo.address[2];
    SUpdateProfile_pack.address[3] = g_slConfigInfo.address[3];
    SUpdateProfile_pack.address[4] = g_slConfigInfo.address[4];
    SUpdateProfile_pack.address[5] = g_slConfigInfo.address[5];
    SUpdateProfile_pack.address[6] = g_slConfigInfo.address[6];

    SUpdateProfile_pack.function_Code = SL_Function_Code_Update_Profile;

    SUpdateProfile_pack.state = 0x01;

    uint16_t crc = CheckFunc((uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE - 3);
    SUpdateProfile_pack.check_Bit_H = crc >> 8;
    SUpdateProfile_pack.check_Bit_L = crc;

    SUpdateProfile_pack.end_Flag = g_slConfigInfo.end_Flag;

    while (1) {
        Delay_Ms(randomDelay());
        if (!Check_485_bus_busy(device)) {
            uart_dev_write(device, (uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE + 1);

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

            break;
        }
    }
}

void SL_MsgProcFunc_Remote_Upgrade(device_handle device, void *pMsg, uint32_t MsgLen)
{
    SL_Mppt_SOther_pack SUpdateProfile_pack = {0};

    SUpdateProfile_pack.start_Flag[0] = g_slConfigInfo.start_Flag[0];
    SUpdateProfile_pack.start_Flag[1] = g_slConfigInfo.start_Flag[1];

    SUpdateProfile_pack.address[0] = g_slConfigInfo.address[0];
    SUpdateProfile_pack.address[1] = g_slConfigInfo.address[1];
    SUpdateProfile_pack.address[2] = g_slConfigInfo.address[2];
    SUpdateProfile_pack.address[3] = g_slConfigInfo.address[3];
    SUpdateProfile_pack.address[4] = g_slConfigInfo.address[4];
    SUpdateProfile_pack.address[5] = g_slConfigInfo.address[5];
    SUpdateProfile_pack.address[6] = g_slConfigInfo.address[6];

    SUpdateProfile_pack.function_Code = SL_Function_Code_Remote_Upgrade;

    SUpdateProfile_pack.state = 0x01;

    uint16_t crc = CheckFunc((uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE - 3);
    SUpdateProfile_pack.check_Bit_H = crc >> 8;
    SUpdateProfile_pack.check_Bit_L = crc;

    SUpdateProfile_pack.end_Flag = g_slConfigInfo.end_Flag;

    while (1) {
        Delay_Ms(randomDelay());
        if (!Check_485_bus_busy(device)) {
            uart_dev_write(device, (uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE + 1);

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

            break;
        }
    }
}


///**
//  * @brief  读取注册状态寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_ReadRegisterRegistrationStatus(void *pMsg)
//{
//    log_info(" SL_ReadRegisterRegistrationStatus ");
//    uint16_t value = g_Mppt_Para.Registration_Status;
//    return value;
//}
//
///**
//  * @brief  读取地址寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_ReadRegisteraddress(void *pMsg)
//{
//    log_info(" SL_ReadRegisteraddress ");
//
//    return 0;
//}
//
///**
//  * @brief  读取接入节点类型寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_ReadRegisterAccessNodeType(void *pMsg)
//{
//    log_info(" SL_ReadRegisterAccessNodeType ");
//    uint16_t value = g_Mppt_Para.Access_Node_Type;
//    return value;
//}
//
///**
//  * @brief  读取通信方式寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_ReadRegisterCommunicationMethods(void *pMsg)
//{
//    log_info(" SL_ReadRegisterCommunicationMethods ");
//    uint16_t value = g_Mppt_Para.Communication_Methods;
//    return value;
//}

/**
  * @brief  读取电池电压寄存器
  * @param
  * @retval
  */
uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg)
{
    log_info(" SL_ReadRegisterBatteryVoltage ");
    uint16_t value = (uint16_t)(g_Mppt_Para.Battery_Voltage * 10);
    return value;
}

/**
  * @brief  读取充电电流寄存器
  * @param
  * @retval
  */
uint16_t SL_ReadRegisterChargCurrent(void *pMsg)
{
    log_info(" SL_ReadRegisterChargCurrent ");
    uint16_t value = (uint16_t)(g_Mppt_Para.Charg_Current * 10);
    return value;
}

/**
  * @brief  读取放电电流寄存器
  * @param
  * @retval
  */
uint16_t SL_ReadRegisterDischargCurrent(void *pMsg)
{
    log_info(" SL_ReadRegisterDischargCurrent ");
    uint16_t value = (uint16_t)(g_Mppt_Para.Discharg_Current * 10);
    return value;
}

/**
  * @brief  读取太阳能开路电压寄存器
  * @param
  * @retval
  */
uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg)
{
    log_info(" SL_ReadRegisterSolarOpenCircuitVoltage ");
    uint16_t value = (uint16_t)(g_Mppt_Para.Solar_Open_Circuit_Voltage * 10);
    return value;
}

/**
  * @brief  读取高端mos管的温度寄存器
  * @param
  * @retval
  */
uint16_t SL_ReadRegisterHighSideMosTemperature(void *pMsg)
{
    log_info(" SL_ReadRegisterHighSideMosTemperature ");
    uint16_t value = (uint16_t)(g_Mppt_Para.HighSideMos_Temperature * 10);
    return value;
}

/**
  * @brief  读取放电mos管状态寄存器
  * @param
  * @retval
  */
uint16_t SL_ReadRegisterDischargMosState(void *pMsg)
{
    log_info(" SL_ReadRegisterDischargMosState ");
    uint16_t value = (uint16_t)g_Mppt_Para.DischargMos_State;
    return value;
}

/**
  * @brief  读取mppt工作模式寄存器
  * @param
  * @retval
  */
uint16_t SL_ReadRegisterMPPTMode(void *pMsg)
{
    log_info(" SL_ReadRegisterMPPTMode ");
    uint16_t value = (uint16_t)g_Mppt_Para.MPPT_Mode;
    return value;
}

///**
//  * @brief  写入注册状态寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_WriteRegisterRegistrationStatus(void *pMsg)
//{
//    log_info(" WriteRegisterRegistrationStatus %x", *(uint16_t *)pMsg);
//
//    return 0;
//}
//
///**
//  * @brief  写入地址寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_WriteRegisteraddress(void *pMsg)
//{
//    log_info(" WriteRegisteraddress %x", *(uint16_t *)pMsg);
//
//    return 0;
//}
//
///**
//  * @brief  写入接入节点类型寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_WriteRegisterAccessNodeType(void *pMsg)
//{
//    log_info(" WriteRegisterAccessNodeType %x", *(uint16_t *)pMsg);
//
//    return 0;
//}
//
///**
//  * @brief  写入通信方式寄存器
//  * @param
//  * @retval
//  */
//uint16_t SL_WriteRegisterCommunicationMethods(void *pMsg)
//{
//    log_info(" WriteRegisterCommunicationMethods %x", *(uint16_t *)pMsg);
//
//    return 0;
//}

/**
  * @brief  匹配起始标志"SL"
  * @param  start_buff  起始标志
  * @retval 1 匹配成功
  *         0 匹配失败
  */
static int Match_Startflag(uint8_t start_buff[2])
{
//    if (!strcmp(start_buff, g_slConfigInfo.start_Flag)) {
//        log_info("Match_Startflag fail \r\n");
//        return 1;
//    }
    if ((start_buff[0] == g_slConfigInfo.start_Flag[0]) && \
            (start_buff[1] == g_slConfigInfo.start_Flag[1])) {
        log_info("Match_Startflag success \r\n");
        return 1;
    }
    return 0;
}

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

    SL_Mppt_Recv_pack *pack = (SL_Mppt_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 == analyzeStartFlag || (flag_run > 0)) {
            if (!Match_Startflag(pack->start_Flag)) {
                memcpy(buff, buff+1, offset-1);
                offset--;
                continue;
            }
        }

        /* 匹配地址  */
        if (offset == analyzeAddress || (flag_run > 1)) {
            if (!((((g_Mppt_Para.Registration_Status == 2) || RegistrationRequestFlag) && Match_address(pack->address))
                    || (run_Broadcast && Match_Broadcastaddress(pack->address)))) {
                if (flag_run < 1) {
                    flag_run = 1;
                }
                memcpy(buff, buff+1, offset-1);
                offset--;
                continue;
            }
        }

        /* 匹配功能码  */
        if (offset == analyzeFunctionCode || (flag_run > 2)) {
            /* 未注册时，不处理读写和其他帧  */
            if (g_Mppt_Para.Registration_Status == 2) {
                /* 读寄存器数据 */
                if (pack->function_Code == SL_Function_Code_Read_Register) {
                    log_info("Read_Register\r\n");
                    len = SL_MPPT_RORECV_PACK_SIZE;
                }

                /* 写寄存器数据 */
                else if (pack->function_Code == SL_Function_Code_Write_Register) {
                    log_info("Write_Register\r\n");
                }

                /* 其他帧格式 */
                else if (pack->function_Code == SL_Function_Code_Update_Profile
                        || pack->function_Code == SL_Function_Code_Remote_Upgrade) {
                    len = SL_MPPT_ROTHER_PACK_SIZE;
                    log_info("Other frames\r\n");
                }

                else if (run_Broadcast) {
                    /* 广播扫描 */
                    if (pack->function_Code == SL_Function_Code_Broadcast_Scan) {
                        log_info("Broadcast_Scan\r\n");
                        len = SL_MPPT_SCAN_BROADCAST_PACK_SIZE;
                    }

                    /* 注册请求 */
                    else if (pack->function_Code == SL_Function_Code_Registration_request) {
                        log_info("Registration_request\r\n");
                        len = SL_MPPT_REGISTRATIONREPLY_PACK_SIZE;
                    }

                    else {
                        if (flag_run < 2) {
                            flag_run = 2;
                        }
                        log_info("funcode error %x\r\n", pack->function_Code);
                        memcpy(buff, buff+1, offset-1);
                        offset--;
                        continue;
                    }
                }

                else {
                    if (flag_run < 2) {
                        flag_run = 2;
                    }
                    log_info("funcode error %x\r\n", pack->function_Code);
                    memcpy(buff, buff+1, offset-1);
                    offset--;
                    continue;
                }
            }

            /* 广播扫描 */
            else if (pack->function_Code == SL_Function_Code_Broadcast_Scan) {
                log_info("Broadcast_Scan\r\n");
                len = SL_MPPT_SCAN_BROADCAST_PACK_SIZE;
            }

            /* 注册请求 */
            else if (pack->function_Code == SL_Function_Code_Registration_request) {
                log_info("Registration_request\r\n");
                len = SL_MPPT_REGISTRATIONREPLY_PACK_SIZE;
            }

            else {
                if (flag_run < 2) {
                    flag_run = 2;
                }
                log_info("funcode error %x\r\n", pack->function_Code);
                memcpy(buff, buff+1, offset-1);
                offset--;
                continue;
            }

        }

        if ((pack->function_Code == SL_Function_Code_Write_Register) && (offset >= 14)) {
            SL_Mppt_Worecv_pack *wpack = (SL_Mppt_Worecv_pack *)buff;
            uint8_t Register_Number = (wpack->write_Register_Number_H << 8) | wpack->write_Register_Number_L;
            len = Register_Number * 2 + SL_MPPT_WORECV_PACK_SIZE - 4;
            continue;
        }

        if (offset == len) {
            uint16_t crc_16 = chang_8_to_16(buff[offset - 2], buff[offset - 3]);

            if ((CheckFunc(buff, offset - 3) != crc_16)  || (buff[offset - 1] != 0x16)) {
                if (flag_run < 3) {
                    flag_run = 3;
                }
                memcpy(buff, buff+1, offset-1);
                offset--;

            } else {
                return offset;
            }
        }
    }
    return 0;
}

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

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

/**
  * @brief  读取并解析串口数据
  * @param
  * @retval
  */
void 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 = uart_read_climate_pack(device, rs485_buff, sizeof(rs485_buff));
        if(ret > 0){
            FRT_MsgHandler(device, rs485_buff, ret);
        }
    }
}




