#include "soft_update.h"
#include "soft_uart.h"
#include "stdbool.h"
#include "stdlib.h"
#include "string.h"
#include "crc.h"
#include "soft_p_2_c.h"
#include "soft_seed_device.h"
#include "soft_obstacle.h"
#include "soft_terrain.h"
#include "soft_p_2_c.h"
#include "soft_can.h"
#include "soft_crc.h"
#include "soft_update.h"
#include "soft_version.h"

/**
  * @file    Vk_Update_Device_Protocol
  * @brief   VK协议设备升级
  * @param   
  * @details 
  * @author  Zhang Sir 
 **/
uint8_t Factory_DevId[3] = {0};
void Vk_Update_Device_Protocol(void)
{
    static uint32_t send_msgtime_2HZ = 0;

    if(uart_send_is_ok(USART_2) == true)
    {
        if(uart_info.step_200_flag == true )
        {
            Update_ack_func(Update_buf[DEVICE],200,&Update_buf[PACK_NUM]);
            uart_info.step_200_flag = false;
        }
        else if(uart_info.step_201_flag == true)
        {
            Update_ack_func(Update_buf[DEVICE],201,&Update_buf[PACK_NUM]);
            uart_info.step_201_flag = false;
        }
        else if(uart_info.step_202_flag == true)
        {
            Update_ack_func(Update_buf[DEVICE],202,&Update_buf[PACK_NUM]);
            uart_info.step_202_flag = false;
        }
    }

    if(uart_info.vk_dev_update_flag == false)
        return;
    // if(uart_info.use_update_buf_flag == false)
    //     return;
    if(HAL_GetTick() - send_msgtime_2HZ < 50)
        return;

    send_msgtime_2HZ = HAL_GetTick();

    uint16_t crc = 0;
    uint8_t  can_buf[8] = {0};
    uint8_t i = 0;
    uint8_t dev_id = 0;

    //FMUPMU协议ID号10进制，设备升级协议16进制
    if(Update_buf[DEVICE] == 56)
        dev_id = 0x56;
    else if(Update_buf[DEVICE] == 51)
        dev_id = 0x11;
    else if(Update_buf[DEVICE] == 52)
        dev_id = 0x12;
    else
        dev_id = Update_buf[DEVICE];

    switch (Update_buf[UPDATE_STEP])
    {
    case UPDATE_START:
        can_buf[0] = dev_id;
        memcpy(&can_buf[1],&Update_buf[PAYLOAD - 2],4);

        switch (can_buf[0])
        {
        case UPDATE_OBS_F:
            if(Dev.Radar.facid_F == FAC_MIMO_RF)
            {
                memcpy(&can_buf[5],"TR0",3);
            }
            else if(Dev.Radar.facid_F == FAC_DM_RF)
            {
                memcpy(&can_buf[5],"DW1",3);
            }
            else if(Dev.Radar.facid_F == FAC_MOCIB_RF)
            {
                memcpy(&can_buf[5],"MZB",3);
            }
            else if(Dev.Part_radarF.facid == FAC_DM_RF)
            {
                memcpy(&can_buf[5],"D4F",3);
            }
            break;
        case UPDATE_OBS_B:
            if(Dev.Radar.facid_B == FAC_MIMO_RB)
            {
                memcpy(&can_buf[5],"TR0",3);
            }
            else if(Dev.Radar.facid_B == FAC_MOCIB_RB)
            {
                memcpy(&can_buf[5],"MZB",3);
            }
            break;
        case UPDATE_TERAIN:
            if(Dev.Radar.facid_T == FAC_MIMO_RT)
            {
                memcpy(&can_buf[5],"TR0",3);
            }
            else if(Dev.Radar.facid_T == FAC_DM_RT)
            {
                if(Dev.Part_Tradar_Link.connect_status == COMP_NORMAL)
                    memcpy(&can_buf[5],"D4T",3);
                else
                    memcpy(&can_buf[5],"DS1",3);
            }
            break;
        case UPDATE_OBS360:
            break;
        case UPDATE_SEED:
            break;
        case UPDATE_FLOW:
            break;
        case UPDATE_BMS:
            break;
        case UPDATE_DISTOR:
            break;
        case UPDATE_WEIGHT:
            if(Dev.Weight.facid == FAC_VK)
            {
                memcpy(&can_buf[5],"VK1",3);
            }
            break;
        default:
            break;
        }

        can_send_msg_normal(&can_buf[0],8,0x381400);
        break;

    case UPDATE_ING:
        while (i < (Update_buf[LEN] - 2 + 8) && uart_info.vk_dev_pack_num == (Update_buf[PACK_NUM] + Update_buf[PACK_NUM + 1] * 256))
        {
            if(i == 0)
            {
                crc = Get_Crc16( &Update_buf[PAYLOAD],Update_buf[LEN] - 2);
                can_buf[0] = 0xFE;
                can_buf[1] = 0xFE;
                can_buf[2] = dev_id;
                can_buf[3] = Update_buf[LEN] - 2;
                can_buf[4] = Update_buf[PACK_NUM];
                can_buf[5] = Update_buf[PACK_NUM + 1];
                can_buf[6] = crc & 0xff; 
                can_buf[7] = (crc >> 8) & 0xff;
            }
            else
            {
                memcpy(&can_buf[0],&Update_buf[i],8);
            }
            i += 8;
            can_send_msg_normal(&can_buf[0],8,0x401400);
            memset(&can_buf[0],0,8);
        }
        break;
    
    case UPDATE_END:
        can_buf[0] = dev_id;
        can_send_msg_normal(&can_buf[0],8,0x481400);

        uart_info.vk_dev_update_flag = false;
        if(dev_id == UPDATE_OBS_F)
        {
            if(Dev.Radar.facid_F == FAC_DM_RF)
                DM_f_info.get_radar_ver_flag = false;
            memset(&dev_obsf,0,sizeof(dev_version_content));
        }
        else if(dev_id == UPDATE_TERAIN)
        {
            if(Dev.Radar.facid_F == FAC_DM_RT)
                DM_ter_info.get_radar_ver_flag = false;
            memset(&dev_ter,0,sizeof(dev_version_content));
        } 
        break;
    default:
        break;
    }
}

void Update_Dev_Bootversion_Function(uint8_t data[])
{
    if(data[4] != 0x01)
        return;

    pmu_send = PMU_SEND_VERSION;
    switch (data[0])
    {
        case UPDATE_OBS_F:
            if(memcmp((char *)&data[1],"TR0",3) == 0)
            {
                mimo_f_info.Link.recv_time = HAL_GetTick();
                mimo_f_info.Link.boot_flag = true;
                Dev.Radar.facid_F = FAC_MIMO_RF;
            }
            else if(memcmp((char *)&data[1],"DW1",3) == 0)
            {
                DM_f_info.Link.connect_status = COMP_NORMAL;
                DM_f_info.Link.recv_time = HAL_GetTick();
                DM_f_info.Link.boot_flag = true;
                Dev.Radar.facid_F = FAC_DM_RF;
                DM_f_info.version[0] = 'D';
                DM_f_info.version[1] = 'W';
                DM_f_info.version[2] = '1';
                DM_f_info.version[3] = 'N';
                for(uint8_t i = 4;i < 10; i++)
                {
                    DM_f_info.version[i] = '0';
                }
				regist_dev_info(&dev_obsf,DEVICE_OBSF,false,NULL,0,DM_f_info.version,10,NULL,0,"dmf",6);
            }
            else if(memcmp((char *)&data[1],"MZB",3) == 0)
            {
                Dev.Part_Fradar_Link.recv_time = HAL_GetTick();
                Dev.Part_Fradar_Link.connect_status= COMP_NORMAL;
                Dev.Part_Fradar_Link.boot_flag = true;
                Dev.Radar.facid_F=FAC_MOCIB_RF;
            }
            else if(memcmp((char *)&data[1],"D4F",3) == 0)
            {
                Dev.Part_Fradar_Link.recv_time = HAL_GetTick();
                Dev.Part_Fradar_Link.connect_status = COMP_NORMAL;
                Dev.Part_radarF.facid = FAC_DM_RF;
            }
            else
            {
                DM_f_info.Link.connect_status = COMP_NORMAL;
                DM_f_info.Link.recv_time = HAL_GetTick();
                DM_f_info.Link.boot_flag = true;
                Dev.Radar.facid_F = FAC_DM_RF;

                DM_f_info.version[0] = 'D';
                DM_f_info.version[1] = 'W';
                DM_f_info.version[2] = '1';
                DM_f_info.version[3] = 'O';
                for(uint8_t i = 4;i < 10; i++)
                {
                    DM_f_info.version[i] = '0';
                }
               regist_dev_info(&dev_obsf,DEVICE_OBSF,false,NULL,0,DM_f_info.version,10,NULL,0,"dmf",6);
            }
            break;
        case UPDATE_OBS_B:
            if(memcmp((char *)&data[1],"TR0",3) == 0)
            {
                mimo_b_info.Link.connect_status = COMP_NORMAL;
                mimo_b_info.Link.recv_time = HAL_GetTick();
                mimo_b_info.Link.boot_flag = true;
                Dev.Radar.facid_B = FAC_MIMO_RB;
            }
            else if(memcmp((char *)&data[1],"MZB",3) == 0)
            {
                Dev.Part_Bradar_Link.recv_time = HAL_GetTick();
                Dev.Part_Bradar_Link.connect_status= COMP_NORMAL;
                Dev.Part_Bradar_Link.boot_flag = true;
                Dev.Radar.facid_B = FAC_MOCIB_RB;
            }
            else if(memcmp((char *)&data[1],"D4B",3) == 0)
            {
                // Dev.Part_Tradar_Link.recv_time = HAL_GetTick();
                // Dev.Part_Tradar_Link.connect_status = COMP_NORMAL;
                // Dev.Part_radarT.facid = FAC_DM_RF;
            }
            break;
        case UPDATE_TERAIN:
            if(memcmp((char *)&data[1],"TR0",3) == 0)
            {
                mimo_ter_info.Link.connect_status = COMP_NORMAL;
                mimo_ter_info.Link.recv_time = HAL_GetTick();
                mimo_ter_info.Link.boot_flag = true;
                Dev.Radar.facid_T = FAC_MIMO_RT;
            }
            else if(memcmp((char *)&data[1],"DS1",3) == 0)
            {
                DM_ter_info.Link.connect_status = COMP_NORMAL;
                DM_ter_info.Link.recv_time = HAL_GetTick();
                DM_ter_info.Link.boot_flag = true;
                Dev.Radar.facid_T = FAC_DM_RT;
                DM_ter_info.version[0] = 'D';
                DM_ter_info.version[1] = 'S';
                DM_ter_info.version[2] = '1';
                DM_ter_info.version[3] = 'N';
                for(uint8_t i = 4;i < 10; i++)
                {
                    DM_ter_info.version[i] = '0';
                }
                regist_dev_info(&dev_ter,DEVICE_TERRA,false,NULL,0,DM_ter_info.version,10,NULL,0,"dmter",6);
            }
            else if(memcmp((char *)&data[1],"D4T",3) == 0)
            {
                Dev.Part_Tradar_Link.recv_time = HAL_GetTick();
                Dev.Part_Tradar_Link.connect_status = COMP_NORMAL;
                Dev.Part_radarT.facid = FAC_DM_RF;
            }
            else
            {
                DM_ter_info.Link.connect_status = COMP_NORMAL;
                DM_ter_info.Link.recv_time = HAL_GetTick();
                DM_ter_info.Link.boot_flag = true;
                Dev.Radar.facid_T = FAC_DM_RT;

                DM_ter_info.version[0] = 'D';
                DM_ter_info.version[1] = 'S';
                DM_ter_info.version[2] = '1';
                DM_ter_info.version[3] = 'O';
                for(uint8_t i = 4;i < 10; i++)
                {
                    DM_ter_info.version[i] = '0';
                }
                regist_dev_info(&dev_ter,DEVICE_TERRA,false,NULL,0,DM_ter_info.version,10,NULL,0,"dmter",6);
            }
            break;
        case UPDATE_OBS360:
            break;
        case UPDATE_SEED:
            break;
        case UPDATE_FLOW:
            break;
        case UPDATE_BMS:
            break;
        case UPDATE_DISTOR:
            break;
        case UPDATE_WEIGHT:
            if(memcmp((char *)&data[1],"VK1",3) == 0)
            {
                
            }
            break;
        default:
            break;
    }
}

/**
  * @file    mimo_obs_update_func
  * @brief   EZ雷达升级
  * @param   
  * @details 
  * @author  Zhang Sir 
 **/
uint8_t radar_node_id = 0;
ez_update EZup_par;
void mimo_obs_update_func(void)
{
    static uint32_t send_msgtime_5HZ = 0;

    if(uart_send_is_ok(USART_2) == true)
    {
        if(uart_info.step_200_flag == true )
        {
            Update_ack_func(Update_buf[DEVICE],200,&Update_buf[PACK_NUM]);
            uart_info.step_200_flag = false;
        }
        else if(uart_info.step_201_flag == true)
        {
            Update_ack_func(Update_buf[DEVICE],201,&Update_buf[PACK_NUM]);
            uart_info.step_201_flag = false;
        }
        else if(uart_info.step_202_flag == true)
        {
            Update_ack_func(Update_buf[DEVICE],202,&Update_buf[PACK_NUM]);
            uart_info.step_202_flag = false;
        }

    }

    if(EZup_par.update_flag != true)
        return;
    if(Check_Timer_Ready(&send_msgtime_5HZ,_20_HZ_) != true)
         return;
    
    uint8_t ez_can[8] = {0};
    static uint8_t frame_i = 1;
    static uint16_t data_count = 0,ez_crc = 0;
    
    if(UPDATE_END == Update_buf[UPDATE_STEP])
    {
        EZup_par.step = STEP_ENDING;
        uart_info.step_202_flag = true;
    }

    switch (EZup_par.step)
    {
    case STEP_FIND_NODE:
        for(uint8_t i = 0;i < 126;i++)
        {
            put_date_to_can(ez_can,i,0x06,0xB2,0X80,0XFF,0XFF,0XFF,0XFF);
            can_send_msg_normalstd(ez_can,8,0x3c);
        }

        break;
    case STEP_JUMP_BOOT:
        put_date_to_can(ez_can,EZup_par.node_id,0x06,0xB3,0XC1,0X42,0X4F,0X4F,0X54);
        can_send_msg_normalstd(ez_can,8,0x3c);

        put_date_to_can(ez_can,EZup_par.node_id,0x06,0xB2,0X80,0XFF,0XFF,0XFF,0XFF); //确定雷达所在区域
        can_send_msg_normalstd(ez_can,8,0x3c);

        break;
    case STEP_EASER_FLASH:
        HAL_Delay(500);
        put_date_to_can(ez_can,EZup_par.node_id,0x06,0xB4,0X42,0X00,0X00,0X00,0X00);
        ez_can[4] = (uart_info.bin_size >> 24) & 0xff;
        ez_can[5] = (uart_info.bin_size >> 16) & 0xff;
        ez_can[6] = (uart_info.bin_size >> 8) & 0xff;
        ez_can[7] = uart_info.bin_size & 0xff;
        can_send_msg_normalstd(ez_can,8,0x3c);
        break;
    case STEP_SET_OFFSET_ADR:
        put_date_to_can(ez_can,EZup_par.node_id,0x06,0xB4,0X03,0X00,0X01,0X17,0X3C);
        ez_can[4] = (EZup_par.adr_offset>> 24) & 0xff;
        ez_can[5] = (EZup_par.adr_offset >> 16) & 0xff;
        ez_can[6] = (EZup_par.adr_offset >> 8) & 0xff;
        ez_can[7] = EZup_par.adr_offset & 0xff;

        can_send_msg_normalstd(ez_can,8,0x3c);
        break;

    case STEP_SEND_DATE:
        while (uart_info.vk_dev_pack_num == (Update_buf[PACK_NUM] + Update_buf[PACK_NUM + 1] * 256) &&
            EZup_par.pack_content != PACK_WAIT)
        {
            switch (EZup_par.pack_content)
            {
            case PACK_HEAD:
                EZup_par.frame_pci = 0x10 + (((128 + 2) >> 8) & 0x7);
                EZup_par.frame_len = (128+2) & 0xff;
                put_date_to_can(ez_can,EZup_par.node_id,EZup_par.frame_pci,EZup_par.frame_len,0XB4,0XC4,0X00,0X00,0X00);
                memcpy(&ez_can[5],&Update_buf[PAYLOAD],3);
                EZup_par.pack_content = PACK_CONT;
                data_count += 3;
                break;

            case PACK_CONT:
                EZup_par.frame_pci = 0x20 + frame_i;
                ez_can[0] = EZup_par.node_id;
                ez_can[1] = EZup_par.frame_pci;
                frame_i++;

                memcpy(&ez_can[2],&Update_buf[PAYLOAD + data_count],6);
                
                data_count += 6;
                if(data_count >= 128)
                {
                    EZup_par.pack_content = PACK_CRC;
                    ez_can[7] = 0xff;
                }
                if(frame_i > 15)
                    frame_i = 0;
                break;  

            case PACK_TAIL:
                
                EZup_par.pack_content = PACK_CRC;
                break;

            case PACK_CRC:
                data_count = 0;
                frame_i = 1;
                ez_crc = crc16_ccitt(&Update_buf[PAYLOAD],128);
                put_date_to_can(ez_can,EZup_par.node_id,0X06,0xB4,0X85,(ez_crc >> 8) & 0xff,(ez_crc & 0xff),0XFF,0XFF);
                EZup_par.pack_content = PACK_WAIT; //只发一次
                break;

            default:
                break;
            }
            can_send_msg_normalstd(ez_can,8,0x3c);
            HAL_Delay(1);
        }
        break;
    case STEP_ENDING:
        put_date_to_can(ez_can,EZup_par.node_id,0x06,0xB4,0X06,0X41,0X50,0X50,0XFF);
        can_send_msg_normalstd(ez_can,8,0x3c);
        EZup_par.step = STEP_DEFAULT;
        EZup_par.update_flag = false;
        mimo_f_info.get_radar_ver_flag = false;
        mimo_b_info.get_radar_ver_flag = false;
        mimo_ter_info.get_radar_ver_flag = false;
        break;
    default:
        break;
    }
}

void EZ_Radar_UpdateCanRecvHookFunction(uint32_t CanID, uint8_t data[], uint8_t len)
{
    if(data[1] == 0x06 && data[2] == 0xF2 && data[3] == 0xAA) //搜索节点
    {
        EZup_par.node_id = data[0];
        EZup_par.step = STEP_JUMP_BOOT;
    }
    else if(data[1] == 0x06 && data[2] == 0xF2 && data[3] == 0x55) //确定在boot
    {
        EZup_par.node_id = data[0];
        EZup_par.step = STEP_EASER_FLASH;
    }
    else if(data[0] == EZup_par.node_id && data[1] == 0x06 && data[2] == 0xF4 && //擦FLASH  //CRC校验回复一样？
        data[3] == 0x00 && data[4] == 0xFF && data[5] == 0xFF && data[6] == 0xFF && data[7] == 0xFF)
    {
        if(EZup_par.step == STEP_EASER_FLASH )
        {
            EZup_par.step = STEP_SET_OFFSET_ADR;
            uart_info.step_200_flag = true;
        }
        else if(EZup_par.step == STEP_SEND_DATE || EZup_par.step == STEP_WAIT)
        {
            EZup_par.adr_offset += 128;
            uart_info.vk_dev_pack_num++;
            EZup_par.step = STEP_SET_OFFSET_ADR;
            uart_info.step_201_flag = true;
        }
    }
    else if(data[0] == EZup_par.node_id && data[1] == 0x06 && data[2] == 0xF4 &&
        data[3] == 0x00 && (data[4] == 0x04 || data[4] == 0x08) && data[5] == 0x00 && data[6] == 0xFF && data[7] == 0xFF) //设置地址偏移    
    {
        EZup_par.step = STEP_SEND_DATE;
        EZup_par.pack_content = PACK_HEAD;
    }
    else if(data[0] == EZup_par.node_id && data[1] == 0x06 && data[2] == 0xF4 && //校验错误
        data[3] == 0x07 && data[4] == 0xFF && data[5] == 0xFF && data[6] == 0xFF && data[7] == 0xFF)
    {
        EZup_par.step = STEP_SET_OFFSET_ADR;
    }

}

