/*
 * communication_protocol.c
 *
 *  Created on: 2024年5月18日
 *      Author: 34509
 */

#include <communication_protocol.h>
#include "inflash.h"
#include <string.h>
#include "thread_communication.h"

SL_Mppt_Scan_Broadcast_pack g_Scan_Broadcast_pack = {
        .start_Flag = "SL",
        .address = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
        .function_Code = SL_Function_Code_Broadcast_Scan,
        .check_Bit_H = 0x36,
        .check_Bit_L = 0xE6,
        .end_Flag = 0x16,
};

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


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

/* 功能码处理表 */
SL_FuncionMsgProcTable g_MsgTbl[] =
{
    {SL_Function_Code_Read_Register,        SL_MsgProcFunc_Read_Register},
    {SL_Function_Code_Registration_request, SL_MsgProcFunc_Registration_request},
};

/**
  * @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  检测485总线是否繁忙
  * @param
  * @retval 1 繁忙
  *         0 空闲
  */
uint8_t Check_485_bus_busy(device_handle device)
{
    uart_device_info *device_info = (uart_device_info *)device;
    if((!device) || (!device_info->init))
       return 0;

    USART_ITConfig(device_info->uart_index, USART_IT_RXNE, ENABLE);

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

    USART_ITConfig(device_info->uart_index, USART_IT_RXNE, DISABLE);

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

void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
    memset(&MqUartSend_pack, 0, sizeof(MqUartSend_pack));
    MqUartSend_pack.device = device;
    MqUartSend_pack.direction = up;
    MqUartSend_pack.len = MsgLen;

    uint8_t *buf = (uint8_t *)pMsg;
    for (uint8_t var = 0; var < MsgLen; ++var) {
        MqUartSend_pack.recv_Data[var] = buf[var];
    }

    /* 发 送 消 息 到 消 息 队 列 中 */
    if (rt_mq_send(mqSend, &MqUartSend_pack, MsgLen) != RT_EOK) {
        rt_kprintf("rt_mq_send ERR\n");
    }
}

void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen)
{
    memset(&MqUartSend_pack, 0, sizeof(MqUartSend_pack));
    MqUartSend_pack.device = device;
    MqUartSend_pack.direction = down;
    MqUartSend_pack.len = SL_MPPT_REGISTRATIONREPLY_PACK_SIZE;

//    uint8_t *buf = (uint8_t *)pMsg;
//    for (uint8_t var = 0; var < MsgLen; ++var) {
//        MqUartSend_pack.recv_Data[var] = buf[var];
//    }

    SL_Mppt_RegistrationReply_pack *rrpack = (SL_Mppt_RegistrationReply_pack *)MqUartSend_pack.recv_Data;
    SL_Mppt_RegistrationRequest_pack *rpack = (SL_Mppt_RegistrationRequest_pack *)pMsg;

    rrpack->start_Flag[0] = rpack->start_Flag[0];
    rrpack->start_Flag[1] = rpack->start_Flag[1];

    rrpack->address[0] = rpack->access_Node_ID[0];
    rrpack->address[1] = rpack->access_Node_ID[1];
    rrpack->address[2] = rpack->access_Node_ID[2];
    rrpack->address[3] = rpack->access_Node_ID[3];
    rrpack->address[4] = rpack->access_Node_ID[4];
    rrpack->address[5] = rpack->access_Node_ID[5];
    rrpack->address[6] = rpack->access_Node_ID[6];
    rrpack->address[7] = rpack->access_Node_ID[7];

    rrpack->function_Code = rpack->function_Code;

    rrpack->register_Length_H = rpack->register_Length_H;
    rrpack->register_Length_L = rpack->register_Length_L;

    rrpack->registration_Status_H = 0x00;
    rrpack->registration_Status_L = 0x02;

    uint16_t crc_16 = CheckFunc(MqUartSend_pack.recv_Data, SL_MPPT_REGISTRATIONREPLY_PACK_SIZE - 3);
    rrpack->check_Bit_H = crc_16 >> 8;
    rrpack->check_Bit_L = crc_16;

    rrpack->end_Flag = 0x16;

    /* 发 送 消 息 到 消 息 队 列 中 */
    if (rt_mq_send(mqSend, &MqUartSend_pack, sizeof(MqUartSend_pack)) != RT_EOK) {
        rt_kprintf("rt_mq_send ERR\n");
    }
}


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

///**
//  * @brief  匹配广播地址
//  * @param  address     地址
//  * @retval 1 匹配成功
//  *         0 匹配失败
//  */
//static int Match_Broadcastaddress(uint8_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) {
//
//        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)
{
    SL_Mppt_Recv_pack *pack = (SL_Mppt_Recv_pack *)buff;

    uint32_t offset = 0;
    uint32_t len = 0;
    uint8_t r_Flag = 0;     /* 读的标志位 */
    uint8_t flag_run = 0;

    char c = 0;

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

//            /* 匹配地址  */
//            if (offset == (sizeof(pack->start_Flag) + sizeof(pack->address)) || (flag_run > 1)) {
//                /* 匹配广播地址,设备地址不做匹配  */
//                if (Match_Broadcastaddress(pack->address)) {
//                    b_Flag = 1;
//                }
//
//            }

            /* 匹配功能码  */
            if ((offset == (sizeof(pack->start_Flag) + sizeof(pack->address) + sizeof(pack->function_Code))) || (flag_run > 2)) {
                /* 读寄存器数据 */
                if (pack->function_Code == SL_Function_Code_Read_Register) {
                    r_Flag = 1;
                }

                /* 注册请求 */
                else if ((pack->function_Code == SL_Function_Code_Registration_request)) {
                    len = SL_MPPT_REGISTRATIONREQUEST_PACK_SIZE;
                    r_Flag = 0;
                }

                else {
                    if (flag_run < 2) {
                        flag_run = 2;
                    }
                    r_Flag = 0;
                    memcpy(buff, buff+1, offset-1);
                    offset--;
                    continue;
                }
            }

            if ((1 == r_Flag) && (offset == 12)) {
                SL_Mppt_ROReply_pack *rpack = (SL_Mppt_ROReply_pack *)buff;
                uint8_t Register_Number = (rpack->reply_Register_Number_H << 8) | rpack->reply_Register_Number_L;
                len = Register_Number * 2 + SL_MPPT_ROReply_PACK_SIZE - 4;
                continue;
            }

            if (offset == len) {
                 /* 读寄存器数据 */
                 if (pack->function_Code == SL_Function_Code_Read_Register) {
                     uint16_t crc_16 = buff[offset - 2] | (buff[offset - 3] << 8);

                     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;
                     }
                 }

                 else {
                     SL_Mppt_RegistrationRequest_pack *rpack = (SL_Mppt_RegistrationRequest_pack *)buff;

                     uint16_t crc_16 = rpack->check_Bit_L | (rpack->check_Bit_H << 8);
                     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)
{
    if (uart_dev_char_present(device)) {
        rt_thread_mdelay(30);
        rt_kprintf("ring_queue_length = %d \n", ring_queue_length(device));
        memset(uart_buff, 0, sizeof(uart_buff));
        int ret = uart_read_climate_pack(device, uart_buff, sizeof(uart_buff));
        if(ret > 0){
            FRT_MsgHandler(device, uart_buff, ret);
        }
    }
}


/**
  * @brief  发送串口数据
  * @param
  * @retval
  */
static void send_uart_data(uint8_t *buff)
{
    SL_UartSend_pack *upack = (SL_UartSend_pack *)buff;

    uart_dev_write(upack->device, upack->recv_Data, upack->len + 1);
}


/**
  * @brief  发送数据
  * @param
  * @retval
  */
void send_data(uint8_t *buff)
{
    SL_UartSend_pack *upack = (SL_UartSend_pack *)buff;

    if (upack->direction == down) {
        send_uart_data(buff);
    }
}