#include "base_core_user.h"
#include "base_core.h"
#include "function.h"
#include "string.h"
#include "platform_interface.h"
#include "stdint.h"
/*
* a,增加如上头文件;
* b, rf接收 void Upgrade_RfSendCallBack(uint8_t *data, uint16_t len)
* c ,100ms timer isr void Upgrade_TickHandler(void)
* d ,rf 发送 uint8_t Upgrade_TxPayload(uint8_t *Payload, uint32_t Length);
* e ,rf发送完成 void Upgrade_WaitRfSendOK()
* f ,us delay uint16_t Upgrade_DelayUs(uint32_t time)
* g , CRC calc uint16_t Upgrade_CRC(uint16_t crc_value, uint8_t *ptr, uint16_t len)
* h ,

*/
#if (UPDATE_KP_2)

void set_tx_ok_flag(unsigned char flag);
unsigned char get_tx_ok_flag(void);
//void RF24L01_RxOn(unsigned char rf_seq);
static void update_request_pkt_to_pc(unsigned char, unsigned short pkt_id);

struct update_STR
{

    //don't change next variable sequence!!!!
    unsigned char Hver;
    unsigned char Sver[3];
    unsigned char crc[2];
    unsigned char file_len[4];
	unsigned char br;
    //sequence limit over

    unsigned int timer_cnt; //100ms timer
    unsigned char start_end_flag;
    unsigned char data_[1056];
    unsigned char data_ok_flag;
};
struct update_STR update={0};

#define WAIT_TXOK_TIMER 500

void log_debug(const char *string, ...)
{
}

void basic_delay_us_update(unsigned int time)
{
    unsigned int i = 0;
    while (time--)
    {
        i = 30;
        while (i--)
            ;
    }
}

unsigned char update_get_status(void)
{
    return 0;
}

void update_monitor_sdk_connect(void)
{
}

unsigned char update_kp_progress(void)
{
}

void updat__exit(void)
{
	platform.rf_init(3);//add by Gavin 20211013解决键盘固件升级停止后信标不正常的情况
	if(kernel.custom_rf_sync_code)
		platform.rf_update_sync_code( kernel.custom_rf_sync_code,4,get_main_rf_hard_id());//20230215 同步码需要同时更新，否则加密基站升级后连不上键盘	
	
	basic_delay_us_update(1000);
	
    base_core.switch_send_beacon(1);
    update.start_end_flag = 0;
    update_request_pkt_to_pc(9, 0x0000);
}

//--------------------------------------------------------
//enum DOWN_step
//{
//    Down_Start = 1,
//    Down_Stop,
//    Down_ASK,
//};
unsigned char Down_Start = 1;
unsigned char Down_Stop =2;

typedef union
{
    uint16_t u16;
    uint8_t u8[2];
} U8_U16;

typedef union
{
    uint32_t u32;
    uint8_t u8[4];
} U8_U32;

typedef struct
{
    uint8_t Buf[1024];
    uint16_t PackCount;
    uint16_t SendCount;
    U8_U16 CRC;
} DOWNLOAD_TRANSPORT_PACK_TEF;

typedef struct
{
    uint8_t TranSportPos; //当前传输序号
    uint8_t QueryPos;
    uint8_t ASK_POS;
    uint16_t DownBlockNum;
    uint8_t Step;
    uint8_t CheckNext;
    uint8_t ResendMAX;
    uint8_t ResendCount;
    uint8_t LostBitBUF[64];
    uint8_t MatchCode[4];
    uint8_t ATC[4];
    uint8_t SN_BUF[48];
    uint8_t SN_Count;
    U8_U32 Len;
    U8_U16 ALLCRC;
    DOWNLOAD_TRANSPORT_PACK_TEF Pack;

} APP_DOWNLOAD_TEF;

typedef enum
{
    DOWN_IDLE = 0,
    DOWN_START,
    DOWN_PASSTHROUGH,
    DOWN_PASSTHROUGHEND,
    DOWN_QUERY,
    DOWN_END,
} Down_FSM22_Def;

Down_FSM22_Def DownFSM = 0;

APP_DOWNLOAD_TEF DownLoad = {0};

//判断一段buf的bit位是否1
uint8_t Upgrade_GetBit(uint8_t *buf, uint16_t bit)
{
    uint8_t i, j;
    i = bit / 8; ///这个是第几个字节
    j = bit % 8; ///这个是这个字节的第几个bit

    if (buf[i] & (1 << j))
        return 1;
    else
        return 0;
}

//一段buf的bit位置0
void Upgrade_ClrBit(uint8_t *buf, uint16_t bit)
{
    uint8_t i, j;
    i = bit / 8; ///这个是第几个字节
    j = bit % 8; ///这个是这个字节的第几个bit

    buf[i] &= ~(1 << j);
}

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//————————————————————————————————————————————————————需要修改部分———————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

uint8_t Upgrade_TxPayload(uint8_t *Payload, uint32_t Length)
{
    //return Platform.RF_TxPack(Payload, Length);
    set_tx_ok_flag(0);
    platform.rf_send_data(Payload, Length, base_core.get_mainRF_hard_id());
    return 1;
}

uint16_t Upgrade_CRC(uint16_t crc_value, uint8_t *ptr, uint16_t len)
{
    //return Platform.CRC16(crc_value, ptr, len);
    crc_value = crc16(ptr, len);
    return crc_value;
}

uint16_t Upgrade_DelayUs(uint32_t time)
{
    //co_delay_us(time);
    basic_delay_us_update(time);
}

void Upgrade_WaitRfSendOK()
{
    uint8_t status;
    uint16_t wait = WAIT_TXOK_TIMER;

    while (wait)
    {
        // status = HS6621C_Read_Status();
        // if ((HS6621C_STATUS_TX_DS & status))
        // {
        //     HS6621C_write_byte(HS6621C_BANK0_STATUS, status);
        //     return;
        // }
        if (get_tx_ok_flag())
            return;
        Upgrade_DelayUs(2);
        wait--;
    }
}

// #define LOADSTART 0X40000
// #define LOADLEN 0X36000
// static uint16_t DownCheckBinCrc(uint32_t addr, uint32_t len)
// {
//     uint32_t flash_addr;
//     uint32_t code_len;
//     uint16_t crc_calc;
//     uint32_t count;
//     uint8_t buf[128];

//     flash_addr = addr;
//     code_len = len;
//     crc_calc = 0;

//     Disable_Interrupt();

//     while (code_len)
//     {
//         if (code_len >= 128)
//             count = 128;
//         else
//             count = code_len;

//         Platform.FLASH_Read(flash_addr, buf, count);
//         crc_calc = Upgrade_CRC(crc_calc, buf, (uint16_t)count);
//         flash_addr += count;
//         code_len -= count;
//     }
//     Enable_Interrupt();

//     return crc_calc;
// }

//获取总CRC 总长
//void Upgrade_ParameterInit(void)
void Upgrade_ParameterInit(unsigned char *mac, unsigned short crc, unsigned int totoal_len)
{
    //uint8_t testbuf[1024];

    // DownLoad.ATC[0] = KeyConect.ATC[0];
    // DownLoad.ATC[1] = KeyConect.ATC[1];
    // DownLoad.ATC[2] = KeyConect.ATC[2];
    // DownLoad.ATC[3] = KeyConect.ATC[3];
    memcpy(DownLoad.ATC, mac, 4);

    DownLoad.ALLCRC.u16 = crc; //DownCheckBinCrc(LOADSTART, LOADLEN);  //这个换成SDK传过来的大小与CRC

    DownLoad.Len.u32 = totoal_len; //LOADLEN;

    DownLoad.DownBlockNum = totoal_len / 1024; //LOADLEN / 1024; //数量

    log_debug("\nC:%x", DownLoad.ALLCRC.u16);
}

void Upgrade_GetNextPack(uint8_t *data)
{
    //Platform.FLASH_Read(LOADSTART + DownLoad.Pack.PackCount * 1024U, data, 1024);
}
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

void Upgrade_SendBeacon(uint8_t mode, uint8_t Count)
{
    static uint8_t temp = 0;
    uint8_t buf[33] = {0};
    uint16_t Crc = 0;

    buf[0] = DownLoad.ATC[0];
    buf[1] = DownLoad.ATC[1];
    buf[2] = DownLoad.ATC[2];
    buf[3] = DownLoad.ATC[3];
    buf[4] = 0x42;
    buf[5] = 0x01;                  //类型
    buf[6] = DownLoad.TranSportPos; //POS
    buf[7] = mode;                  //操作

    buf[8] = 0xff;
    buf[9] = 0xff;

    buf[10] = 0x00; //SN
    buf[11] = 0x00;
    buf[12] = 0x00;
    buf[13] = 0x00;

    buf[14] = DownLoad.Len.u8[0];
    buf[15] = DownLoad.Len.u8[1];
    buf[16] = DownLoad.Len.u8[2];
    buf[17] = DownLoad.Len.u8[3];

    buf[18] = DownLoad.ALLCRC.u8[0]; //CRC
    buf[19] = DownLoad.ALLCRC.u8[1];

    buf[20] = DownLoad.ASK_POS;
	buf[21] =update.Hver ;	
	memcpy(buf+22,update.Sver,3);
	buf[25] = update.br;
	
    Crc = Upgrade_CRC(0, buf + 4, 27) & 0xFF;
    buf[31] = Crc;

    while (Count)
    {
        Upgrade_TxPayload(buf, 32);
        Upgrade_WaitRfSendOK();
        Upgrade_DelayUs(50);
        Count--;
    }
}

void Upgrade_BeaconQuery(void)
{
    uint8_t sendbuf[64] = {0};
    U8_U16 crc;

    sendbuf[0] = DownLoad.ATC[0];
    sendbuf[1] = DownLoad.ATC[1];
    sendbuf[2] = DownLoad.ATC[2];
    sendbuf[3] = DownLoad.ATC[3];

    sendbuf[4] = 0xfe;
    sendbuf[5] = 0x48;
    sendbuf[6] = 0xde;
    sendbuf[7] = 0x7f;

    sendbuf[8] = 1;    //后续数据片区
    sendbuf[9] = 0x02; //询问CMD

    crc.u16 = Upgrade_CRC(0, DownLoad.SN_BUF, 48); //计算CRC校验

    sendbuf[10] = crc.u8[0];
    sendbuf[11] = crc.u8[1];

    sendbuf[12] = DownLoad.QueryPos; //询问序号

    memcpy(sendbuf + 16, DownLoad.SN_BUF, 48);

    memset(DownLoad.SN_BUF, 0, 48);
    DownLoad.SN_Count = 0;

    Upgrade_TxPayload(sendbuf, 32);
    Upgrade_WaitRfSendOK();
    Upgrade_DelayUs(20);

    Upgrade_TxPayload(sendbuf + 32, 32);
    Upgrade_WaitRfSendOK();
}
void Upgrade_SendPassThroughPack(uint8_t count)
{
    //发头
    uint8_t buf[33] = {0};

    buf[0] = DownLoad.ATC[0];
    buf[1] = DownLoad.ATC[1];
    buf[2] = DownLoad.ATC[2];
    buf[3] = DownLoad.ATC[3];

    DownLoad.MatchCode[0] = 0xfe;
    DownLoad.MatchCode[1] = 0x48;
    DownLoad.MatchCode[2] = 0xde;
    DownLoad.MatchCode[3] = 0x7f;

    buf[4] = DownLoad.MatchCode[0];
    buf[5] = DownLoad.MatchCode[1];
    buf[6] = DownLoad.MatchCode[2];
    buf[7] = DownLoad.MatchCode[3];

    buf[8] = 32;   //数据片区
    buf[9] = 0x01; //CMD

    buf[10] = DownLoad.Pack.CRC.u8[0];
    buf[11] = DownLoad.Pack.CRC.u8[1];
    buf[12] = DownLoad.TranSportPos; //该次传输序号
    buf[13] = count;                 //当前包序号
	
	buf[14] =update.Hver ;	
	//memcpy(buf+22,update.Sver,3);
	buf[15] = update.br;
	
    Upgrade_TxPayload(buf, 32);
    Upgrade_WaitRfSendOK();
    Upgrade_DelayUs(200);

    for (uint8_t i = 0; i < 32; i++)
    {
        Upgrade_TxPayload(DownLoad.Pack.Buf + (32 * i), 32);
        Upgrade_WaitRfSendOK();
        Upgrade_DelayUs(20);
    }
    //发数据
}

//uint8_t NextPack[1024] = {0};
//函数作用：查询基站Server是否已经获取到上次数据
//return:  0 表示成功获取到该包数据
//         1 表示还在获取中
//         ...等等其他失败原因
//data     成功获取到的时候 将1K数据写入改地址
//         失败不要写入改地址任何数据
uint8_t Upgrade_CheckNextPackArrive(uint8_t *data)
{
    if (update.data_ok_flag)
    {
        memcpy(data, update.data_, 1024);
        return 0;
    }
    else
        return 1;
}

//函数作用：通知基站Server可以去获取下一包发送数据
//step    阶段号：0阶段  基站找SDK直接要数据  SDK按顺序从0到最后一包
//               1阶段  基站按count号找SDK要该段数据。
//count   需要获取下一包传输的包序号  从0开始。  单位1K   最后一包SDK补全1024
void Upgrade_StartGetNextPack(uint8_t step, uint8_t count)
{
    //Platform.FLASH_Read(LOADSTART + count * 1024U, NextPack, 1024);
    update.data_ok_flag = 0;
    update_request_pkt_to_pc(10, count);
}

static uint32_t TickTimeOut = 0;

void Upgrade_TickHandler(void)
{
    static uint16_t H_Tick = 0;

    if (TickTimeOut)
    {
        if (--TickTimeOut == 0)
        {
            if ((DownFSM != DOWN_IDLE) && (DownFSM != DOWN_END))
                DownFSM = DOWN_END;
        }
    }

    switch (DownFSM)
    {
    case DOWN_IDLE:
        break;
    case DOWN_START:
        //广播1S开始指令 再转到接收
        Upgrade_SendBeacon(Down_Start, 30);
        H_Tick++;
        if (H_Tick > 40)
        {
            DownLoad.Pack.PackCount = 0;
            DownLoad.Pack.SendCount = 0x1ff;
            DownLoad.ResendMAX = 1;
            DownLoad.ResendCount = 0;

            memset(DownLoad.SN_BUF, 0, 48);
            DownLoad.SN_Count = 0;

            H_Tick = 0;
            DownLoad.Step = 0;
            memset(DownLoad.LostBitBUF, 0xff, 64);
            Upgrade_StartGetNextPack(DownLoad.Step, DownLoad.Pack.PackCount); //准备第一包数据
            Upgrade_ClrBit(DownLoad.LostBitBUF, 0);
            DownLoad.CheckNext = 0; //False;
            DownFSM = DOWN_PASSTHROUGH;
            //            GUI_ShowVoteInput("DOWN_PASSTHROUGH");
            //            SGUI_RefreshScreen();
        }
        break;
    case DOWN_PASSTHROUGH:

        log_debug("\nS:%d", DownLoad.Pack.PackCount);

        if (DownLoad.CheckNext != 1)
        {
            if (Upgrade_CheckNextPackArrive(DownLoad.Pack.Buf) == 0) //成功获取到数据
            {
                DownLoad.CheckNext = 1; //True;
                DownLoad.ResendCount = 0;
                DownLoad.Pack.CRC.u16 = Upgrade_CRC(0, DownLoad.Pack.Buf, 1024);
                DownLoad.Pack.SendCount = DownLoad.Pack.PackCount;
            }
        }
        if (DownLoad.Pack.SendCount != 0x1ff)
        {
            if (++DownLoad.ResendCount > 200)
                DownLoad.ResendCount = 200;
            Upgrade_SendPassThroughPack(DownLoad.Pack.SendCount);
            Upgrade_DelayUs(1800);
            Upgrade_SendPassThroughPack(DownLoad.Pack.SendCount);
        }

        if ((DownLoad.ResendCount >= DownLoad.ResendMAX) && (DownLoad.CheckNext == 1))
        {
            DownLoad.CheckNext = 0; //False;
            for (uint8_t i = 0; i < DownLoad.DownBlockNum; i++)
            {
                if (Upgrade_GetBit(DownLoad.LostBitBUF, i))
                {
                    Upgrade_ClrBit(DownLoad.LostBitBUF, i);
                    DownLoad.Pack.PackCount = i;
                    Upgrade_StartGetNextPack(DownLoad.Step, DownLoad.Pack.PackCount);
                    break;
                }
                if (i == (DownLoad.DownBlockNum - 1))
                    DownFSM = DOWN_PASSTHROUGHEND;
            }
        }

        break;

    case DOWN_PASSTHROUGHEND:
        H_Tick = 0;
        DownLoad.ASK_POS++;
        memset(DownLoad.LostBitBUF, 0, 32);
        DownFSM = DOWN_QUERY;
        if (DownLoad.QueryPos++ > 200)
            DownLoad.QueryPos = 1;
        log_debug("DOWN_QUERY");
        //  GUI_ShowVoteInput("DOWN_END");
        //SGUI_RefreshScreen();
        break;

    case DOWN_QUERY:
        Upgrade_BeaconQuery();

        H_Tick++;
        if (H_Tick >= 50) //5S
        {
            uint16_t LostNum = 0;
            H_Tick = 0;
            for (uint16_t i = 0; i < DownLoad.DownBlockNum; i++)
            {
                if (Upgrade_GetBit(DownLoad.LostBitBUF, i))
                {
                    LostNum++;
                }
            }
            log_debug("\nLNum:%d", LostNum);
            if (LostNum == 0)
            {
                DownFSM = DOWN_END;
                break;
            }
            else
            {
                DownLoad.Step++;
                DownLoad.ResendMAX = 8;

                for (uint8_t i = 0; i < DownLoad.DownBlockNum; i++)
                {
                    if (Upgrade_GetBit(DownLoad.LostBitBUF, i))
                    {
                        Upgrade_ClrBit(DownLoad.LostBitBUF, i);
                        DownLoad.Pack.PackCount = i;
                        Upgrade_StartGetNextPack(DownLoad.Step, DownLoad.Pack.PackCount);
                        break;
                    }
                }
                DownFSM = DOWN_PASSTHROUGH;
                break;
            }
        }

        break;
    case DOWN_END:
        //广播1S开始指令 再转到接收
        Upgrade_SendBeacon(Down_Stop, 30);
        H_Tick++;
        if (H_Tick > 40)
        {
			TickTimeOut=0;
            H_Tick = 0;
            DownFSM = DOWN_IDLE;
            updat__exit();
        }
        break;
    default:
        break;
    }
}

uint8_t Upgrade_PassThrough_CheckHead(uint8_t *buf)
{
    if ((buf[1] == 0xAA) && (buf[2] == 0xBB) && (buf[3] == 0xCC) && (buf[4] == 0xDD)) //免配对
    {
    }
    else
    {
        if (DownLoad.ATC[0] != buf[1])
            return 2;
        if (DownLoad.ATC[1] != buf[2])
            return 2;
        if (DownLoad.ATC[2] != buf[3])
            return 2;
        if (DownLoad.ATC[3] != buf[4])
            return 2;
    }

    if (0x7f != buf[5])
        return 1;
    if (0xde != buf[6])
        return 1;
    if (0x48 != buf[7])
        return 1;
    if (0xfe != buf[8])
        return 1;

    return 0;
}

void Upgrade_RfSendCallBack(const uint8_t *data, uint16_t len)
{
    static uint8_t PassThroughStep = 0;
    static U8_U16 CRC = {0};
    static uint8_t T_SN[4] = {0};
    uint8_t RxBuf[33] = {0};

    RxBuf[0] = len;
    memcpy(RxBuf + 1, data, len);

    if (Upgrade_PassThrough_CheckHead(RxBuf) == 0)
    {
        if (RxBuf[10] != 0x82)
            return;
        PassThroughStep = 1;
        memcpy(T_SN, RxBuf + 13, 4); //保存SN号
        CRC.u8[0] = RxBuf[11];
        CRC.u8[1] = RxBuf[12];
        return;
    }
    if (PassThroughStep == 1)
    {
        PassThroughStep = 0;
        uint16_t crc = Upgrade_CRC(0, RxBuf + 1, 32);
        if (crc == CRC.u16) //校验正确
        {
            log_debug("\nCRCT");
            if (DownLoad.SN_Count < 16)
            {
                memcpy((DownLoad.SN_BUF + DownLoad.SN_Count * 4), T_SN, 4);
                DownLoad.SN_Count++;
            }
            for (uint8_t i = 0; i < 32; i++)
            {
                if (RxBuf[i + 1] != 0)
                {
                    DownLoad.LostBitBUF[i] = DownLoad.LostBitBUF[i] | RxBuf[i + 1];
                }
            }
        }
        return;
    }
}

//————————————————————————————————————————————————————————————————————————
//—————————————————————————————————需修改部分——————————————————————————————
//————————————————————————————————————————————————————————————————————————
//————————————————————————————————————————————————————————————————————————
void Upgrade_Start(void)
{
    // Platform.Timer_Stop(HW_TIM_TypeUSecs0);
    // Platform.Timer_Stop(HW_TIM_TypeUSecs1);
    // Platform.Timer_Stop(HW_TIM_TypeUSecs2);

    // Platform.RF_SetRxPayloadCallback(Upgrade_RfSendCallBack); //RF接收回调
    // //Platform.RF_SetTxEndCallback(CORE_BASE_SET_EndCallback);     //RF发送完成回调

    // Platform.Timer_SetIRQHandler(HW_TIM_TypeUSecs1, Upgrade_TickHandler); //升级 主流程定时中断 100MS
    // Platform.Timer_Start(HW_TIM_TypeUSecs1, 100 * 1000);

    DownFSM = DOWN_START;    //开始升级
    DownLoad.TranSportPos++; //升级Pos序号
    TickTimeOut = 6000;      //10分钟超时时间
    
    base_core.switch_send_beacon(0);
}

//模拟固件下载
//void Upgrade_Init(void)
//{
//    //Upgrade_ParameterInit(); //参数初始化  获取总长与CRC
//    Upgrade_Start();         //开始固件升级
//}

//————————————————————————————————————————————————————————————————————————

//-------------------------------- 与pc 之间的通信 -----------------------------------------------

#if 0
/*
基站发送升级过程中的状态给PC
*/
static void update_report_info_to_pc(unsigned char kp_seq,unsigned char status)
{
		unsigned char tmp[32];
		if(kp_seq>= UPDATE_KP_CNT) return;//error 防止数组溢出
		tmp[0] =24;
		tmp[1] =0xE1;
		tmp[2] =base_core.get_id();//get_base_id();	
		tmp[3] =22;
		tmp[4] =6;	
		tmp[5] =0;//packH
		tmp[6] =0;//packL
		tmp[7] =status;	//错误或者是通知/数据已经发送完了！ 		
		if(tmp[7]==1)//报告完成状态时，不关注id/SN，便于调试理解
memset(tmp+8,0xff,6);//			mem_set(tmp+8,6,0xff);					
		else
			memcpy(tmp+8,update.idsn[kp_seq],6);//mem_cpy(update.idsn[kp_seq],tmp+8,6);	//报告错误时必须包含id/SN
				
		base_core.send_data_to_pc(tmp);//user__base_tx_to_pc_sub(tmp);
}
#endif
static void update_request_pkt_to_pc(unsigned char type, unsigned short pkt_id)
{
    unsigned char tmp[32];
    //if(kp_seq>= UPDATE_KP_CNT) return;//error 防止数组溢出
    tmp[0] = 24;
    tmp[1] = 0xE1;
    tmp[2] = base_core.get_id(); //get_base_id();
    tmp[3] = 22;
    tmp[4] = type;        //7;//6;
    tmp[5] = pkt_id >> 8; //packH
    tmp[6] = pkt_id;      //packL
                          //		tmp[7] =status;	//错误或者是通知/数据已经发送完了！
                          //		if(tmp[7]==1)//报告完成状态时，不关注id/SN，便于调试理解
                          //memset(tmp+8,0xff,6);//			mem_set(tmp+8,6,0xff);
                          //		else
                          //			memcpy(tmp+8,update.idsn[kp_seq],6);//mem_cpy(update.idsn[kp_seq],tmp+8,6);	//报告错误时必须包含id/SN
#if _RTT_VIEW_
//    SEGGER_SYSVIEW_PrintfHost("base->pc:request packetNO=%d", pkt_id);
#endif
    base_core.send_data_to_pc(tmp); //user__base_tx_to_pc_sub(tmp);
}

/*
基站升级键盘固件之 基站与pc之间的通信入口，也是升级功能的总入口！
call by rx_pc_0x61
流程： pc下载名单
	pc告知基站可以开始通知键盘进入下载
	pc开始发送升级数据
	然后基站进入广播升级数据
*/
void update_kp_enter(const unsigned char *rx_pc)
{
    switch (rx_pc[4])
    {
    case 1:
#if 0
				update.idsn_mode =rx_pc[5];
				memcpy(&update.Hver,rx_pc+8,10);//mem_cpy(rx_pc+8,&update.Hver,10);				
			
				if(rx_pc[7]==1){			//a start update
					update.type_start_stop_data=1;//update.type_cmd_data =1;			
					update.start_end_flag=1;					
					//memset(update.valid,0,UPDATE_KP_CNT); //clear valid flag
					if(update.valid_cnt < UPDATE_KP_CNT)
						memset(update.valid+update.valid_cnt,0,UPDATE_KP_CNT-update.valid_cnt); 
					update.step =_STEP_NOTICE_START;
					_debug__updata_init();					
					update.start_end_flag=1;	//升级功能总开关!!				
				}
				else if(rx_pc[7]==0){	//b,finish update 
					update.type_start_stop_data=0;//update.type_cmd_data =0;
					update.step =_STEP_NOTICE_FINISH;	
				}
				else{									//c, stop update
					update.type_start_stop_data=0;//update.type_cmd_data =0;
					update.step =_STEP_NOTICE_ABORT;//停止命令
				}
#else
        memcpy(&update.Hver, rx_pc + 8, 10+1);

        if (rx_pc[7] == 1) //开始
        {                  //start
            unsigned char mac[4];
            unsigned int file_len = (update.file_len[0] << 24) + (update.file_len[1] << 16) +
                                    (update.file_len[2] << 8) + (update.file_len[3] << 0);
            base_core.get_match_code(mac);
            Upgrade_ParameterInit(mac, (update.crc[0] << 8) + update.crc[1], file_len);
            
			if (update.start_end_flag == 0)
				Upgrade_Start(); //开始固件升级
//			core__mon_sdk_intf.switch_onoff(0);
            update.start_end_flag = 1;
			base_core.switch_send_beacon(0);//  base_core.switch_send_beacon(0);
			
			if( update.br != 0){
				Down_Start = 11;
				Down_Stop =12;					 				 
			 }
			 else{
				Down_Start = 1;
				Down_Stop =2;				 
			 }
//#if _RTT_VIEW_
//            view_print(0, "pc->base: start keypad update", rx_pc + 4);
//#endif
        }
        else if (rx_pc[7] == 2) //终止
        {
            update.start_end_flag = 0;
            DownFSM = DOWN_END;
            base_core.switch_send_beacon(1);
        }
#endif
        user__pc_cmd_ack(0x61, 22, rx_pc + 4, 26); //update_ack_pc_0x61(rx_pc);		//responce sdk
        break;
#if 0			
			case 2:{	//download id/sn list of keypad
					unsigned char i,current;
					update.kp_counter =rx_pc[5];
					update.valid_cnt =rx_pc[5];//初始化有效个数	
					if(update.kp_counter >UPDATE_KP_CNT ) break; //超出最大键盘个数 error ??如何报告此错误?	
					//每次发送8个6字节表单	
					current = (rx_pc[6]<<3);
					//if( current >= UPDATE_KP_CNT-8) break;//error 防止数组溢出
					for(i=0;i<8;i++){
						if(current+i >= UPDATE_KP_CNT) break; //解决100只键盘最后4只无法进入升级的问题
						memcpy(update.idsn[current+i],&rx_pc[7+i*6],6);
						update.valid[current+i] =1;
					}
				}	
			
				user__pc_cmd_ack(0x61,22,rx_pc+4,26);//update_ack_pc_0x61(rx_pc);
				break;
		
			case 4://down update data

				update.downID =rx_pc[6];
				update.packH =rx_pc[7];
				update.packL =rx_pc[8];
				if(update.packL >=16) break;//error 防止数组溢出
				memcpy(update.data[update.packL],rx_pc+9,18);//mem_cpy(rx_pc+9,update.data[update.packL],18);//16bytes data +2bytes crc	
			
				break;

			
			case 5://一包数据传输完了，可以开始向键盘广播数据了！
				update.type_start_stop_data=2;
				update.step =_STEP_BROADCAST_DATA_INIT;
				break;
			
			case 6:	//confirm report data from pc
				update.pc_confirm_flag=1;
				update.pc_confirm_type =rx_pc[7];
				break;
#endif

    case 7: //update data....
//        if (rx_pc[8] <= 21)
//        {
//            memcpy(update.data_ + rx_pc[8] * 48, rx_pc + 9, 48);
//        }

        //				if(rx_pc[8] ==0){
        //					memcpy(update.data_+0,rx_pc+9,512);
        //				}
        //				else if(rx_pc[8] ==1){
        //					memcpy(update.data_+512,rx_pc+9,512);
        //					update.data_ok_flag =1;
        //				}

        
//        #if _RTT_VIEW_
//                view_print(0, "pc->base: a 512 bytes", rx_pc + 4);
//        #endif
        user__pc_cmd_ack(0x61, 22, rx_pc + 4, 26);

    #if TEXT_MESSAGE 
        if(rx_pc[5]==30)
        {
			msg_get_pc_data(rx_pc);//, update.data_);//msg_get_pc_data(rx_pc);
//            if((rx_pc[7]*16 + rx_pc[8]+1)>=rx_pc[6])
//            {
//                msg_get_pc_data(1, rx_pc + 9, rx_pc[6],48);//msg_get_pc_data(update.data_,rx_pc[6]*48);
//            }
//            else
//            {
//                msg_get_pc_data(0, rx_pc + 9, rx_pc[6],48);
//            }
        }
        else
        #endif
        {
            if (rx_pc[8] <= 21)
            {
                memcpy(update.data_ + rx_pc[8] * 48, rx_pc + 9, 48);
            }
            if (rx_pc[8] == 21)
            update.data_ok_flag = 1;
        }
        break;
    default:
        break;
    } //sw
}


void Msg_TickHandler(void);
//100ms timer
void update_2_timer(void)
{
    if (++update.timer_cnt >= 5)
    {
        update.timer_cnt = 0;
        Upgrade_TickHandler();
        #if TEXT_MESSAGE 
            Msg_TickHandler();
        #endif
    }
}

//rf RX interface for keypad update
unsigned char save_keypad_ack_data(const unsigned char *rxkp)
{
//#if _RTT_VIEW_
//    view_print(0, "keypad->base: rx rf data ", rxkp);
//#endif
    if (update.start_end_flag)
    { // &&(rxkp[1]==0xC0)&& ((rxkp[4]==0x01)||(rxkp[4]==0x03)) ){
        Upgrade_RfSendCallBack(rxkp + 1, rxkp[0]);
        return 1;
    }
    else
        return 0;
}
#endif

//-------------------------------------------------------------------------
#if _RTT_VIEW_
#include "SEGGER_SYSVIEW.h"
#include "SEGGER_RTT.h"

//void view_print(unsigned char type, char *string, const unsigned char *tmp)
//{
//    unsigned short on_off = 0;
//    on_off = 1;

//    if (on_off)
//    {
//        SEGGER_SYSVIEW_Print(string);

//        SEGGER_SYSVIEW_PrintfHost("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",
//                                  tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7],
//                                  tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15]);
//    }
//}

#endif
