/*
 * dbn_ble_srv.c
 *
 *  Created on: Aug 27, 2024
 *      Author: Thinkpad
 */

#include "dbn_ble_srv.h"
#include "cmcng.h"
#include "storage.h"
#include <string.h>
#include "net_srv.h"


uint8_t g_flag_notify_temp = 0;             //临时通知notify flag, 0 disable, 1 enable

BLE_Notify_Buf  g_notify_buftemp = {0,0, ""};
BLE_Notify_Buf  g_ble_rcv_buf  = {0,0, ""};
BLE_Notify_Buf  g_tmp_report_buf = {0,0, ""};

Buf_DBN_BLE g_buf_ble_response = {0,0,0,0,0,0,0,""};

DBN_BLE_State g_dbn_ble_state_acs_enable = {0};

uint8_t tmp_ble_buf[MAX_BLE_TMP_BUF_LEN] = "";

extern uint8_t loop1_FLAG_CUT;


void clear_ble_notify_buf(BLE_Notify_Buf * buf)
{
    buf->len = 0;
    buf->flag = 0;
    memset(buf, 0, MAX_BLE_Notify_Buf_LEN);
}

void clear_buf_dbn_ble(Buf_DBN_BLE * buf)
{
    uint8_t i = 0;


    buf->flag = 0;
    buf->magic = 0;
    buf->cmd = 0;
    memset(buf->dat, 0, buf->dat_len);
    buf->dat_len = 0;
    buf->dat_offset = 0;
    buf->pkg_amount = 0;
    buf->pkg_seq = 0;
}

void clear_buf_dbn_ble_all(Buf_DBN_BLE * buf)
{
    uint8_t i = 0;
//    if(g_flag_debug)
    {
//        PRINT("\nclear_buf_dbn_ble_flag:%02X,magic:%02X,pkg_amount:%02X,seq:%02X,cmd:%02X, dat_len:%d,offset:%d\n",
//        buf->flag,buf->magic,buf->pkg_amount, buf->pkg_seq,buf->cmd, buf->dat_len,buf->dat_offset);
//        for(i = 0; i < buf->dat_len; i++)
//        {
//            PRINT(" %02X", buf->dat[i]);
//        }
//        PRINT("\n");
    }
    buf->flag = 0;
    buf->magic = 0;
    buf->cmd = 0;
    memset(buf->dat, 0, MAX_BLE_BUF_LEN);
    buf->dat_len = 0;
    buf->dat_offset = 0;
    buf->pkg_amount = 0;
    buf->pkg_seq = 0;
}


// 0: 包检测异常
//检测包是否完整，Magic Byte, Header Byte, CK Byte,   校验字节（异或校验，以及和校验）
uint8_t check_pkg(uint8_t * pkg, uint8_t len)
{
    if(len < 6)     //min length of ble pkg is 6
        return 0;
    uint8_t magic = pkg[0];
    uint8_t _len = pkg[2];   //data_len
    if(magic == 0x9F){
        // if(_len + 4 < len){
        //     return 0;
        // }
        if(pkg[1] == 0x01 && pkg[2] == 0x00 && pkg[3] == 0x01 && pkg[4] == 0xA5 && pkg[5] == 0xA7){
            g_flag_counter_ota.tick = 0;
            g_flag_counter_ota.flag = 1;
            PRINT("Come into OTA___\n");
        }
    }
    if(_len + 5 < len)
    {
        return 0;
    }
    uint8_t _dxor = 0;
    uint8_t _dsum = 0;
    uint8_t _cklen = _len + 3;  //不计算 校验字节
    uint8_t i = 0;
    for(i = 1; i < _cklen; i++)
    {
        _dxor ^= pkg[i];
        _dsum += pkg[i];
    }
    if((_dxor != pkg[_cklen]) || (_dsum != pkg[_cklen+1]))
    {
//        if(g_flag_debug)
//        {
//            PRINT("_dxor:0x%02X - 0x%02X, _dsum:0x%02X - 0x%02X\r\n", _dxor, pkg[_cklen], _dsum, pkg[_cklen + 1] );
//        }
        return 0;
    }

    return magic;
}

static uint8_t set_dev_info_to_ready(uint8_t *dat_dst)
{
    uint8_t i = 0, j = 0;
    for(i = 0; i < 6; i++)
    {
        dat_dst[i] = gMacAddr[i];
//        PRINT(" %02X",dat_dst[i] );
    }
//    memcpy(dat_dst, MACAddr, sizeof(MACAddr));
//    i += sizeof(MACAddr);
    dat_dst[i++] = HARDWARE_VER_MAIN;
    dat_dst[i++] = HARDWARE_VER_SUB;
    dat_dst[i++] = FIRMWARE_VER_MAIN;
    dat_dst[i++] = FIRMWARE_VER_SUB;

    // Dev Model
    dat_dst[i++] = strlen(PRODUCT_MODEL);
    memcpy(&dat_dst[i], PRODUCT_MODEL, strlen(PRODUCT_MODEL));
    i += strlen(PRODUCT_MODEL);

    // Dev Number
    for(j = 0; j < 6; j++, i++)
    {
        dat_dst[i] = g_dev_number[j];
    }
    // sub_code
//    memcpy(&dat_dst[i], &(g_sub_code_enable.code_set), sizeof(g_sub_code_enable.code_set));
//    i += sizeof(g_sub_code_enable.code_set);
    dat_dst[i++] = 0;
    dat_dst[i++] = 0;


    dat_dst[i++] = 0; // g_bus_dus_amount_stored.bus1_amount;
    dat_dst[i++] = 0; //g_bus_dus_amount_stored.bus2_amount;
    return i;
}

static uint8_t set_net_info_to_ready(uint8_t * dat_dst)
{
    uint8_t i = 0;
    memcpy(&dat_dst[i], local_net_cfg.lip, 4);
    i += 4;
    memcpy(&dat_dst[i], local_net_cfg.sub, 4);
    i += 4;
    memcpy(&dat_dst[i], local_net_cfg.gw, 4);
    i += 4;
    memcpy(&dat_dst[i], net_center_info.lssc_ip, 4);
    i += 4;
    memcpy(&dat_dst[i], local_net_cfg.dns, 4);
    i += 4; 
	dat_dst[i++] = local_net_cfg.port_ssc_tcp;
	dat_dst[i++] = local_net_cfg.port_ssc_tcp >> 8;
	dat_dst[i++] = local_net_cfg.port_ssc_udp;
	dat_dst[i++] = local_net_cfg.port_ssc_udp >> 8;	
	dat_dst[i++] = local_net_cfg.port_ssc_udp_message;
	dat_dst[i++] = local_net_cfg.port_ssc_udp_message >> 8;
	
	dat_dst[i++] = local_net_cfg.port_dev_tcp;
	dat_dst[i++] = local_net_cfg.port_dev_tcp >> 8;	
	dat_dst[i++] = local_net_cfg.port_dev_udp;
	dat_dst[i++] = local_net_cfg.port_dev_udp >> 8;
	
    return i;
}

void set_response_iot_net(Buf_DBN_BLE *response_dst)
{   // config iot_net  
    uint8_t ret = 0;
    uint8_t i = 0;
    int _len = 0;
    clear_buf_dbn_ble(response_dst);
    response_dst->magic = MAGIC_BYTE_DBN_DEFAULT;
    response_dst->cmd = CMD_DBN_GET_IOT_NET;
    
    memcpy(response_dst->dat, iot_net_info.remote_addr, strlen(iot_net_info.remote_addr));
    i += strlen(iot_net_info.remote_addr);
    i++;
    _len = sprintf(&(response_dst->dat[i]), "%d", iot_net_info.mqtt_port);
    i += _len;
    i++;
    memcpy(&(response_dst->dat[i]), iot_net_info.client_id, strlen(iot_net_info.client_id));
    i += strlen(iot_net_info.client_id);
    i++;
    memcpy(&(response_dst->dat[i]), iot_net_info.username, strlen(iot_net_info.username));
    i += strlen(iot_net_info.username);
    i++;
    memcpy(&(response_dst->dat[i]), iot_net_info.password, strlen(iot_net_info.password));
    i += strlen(iot_net_info.password);    
    response_dst->dat_len = i;
    response_dst->pkg_amount = i / MAX_BLE_DAT_RESPONSE_LEN;
    if((i % MAX_BLE_DAT_RESPONSE_LEN) > 0)
    {
        response_dst->pkg_amount += 1;
    }
    response_dst->pkg_seq = 0;
    
    response_dst->flag = 1;
}

void set_response_iot_topic(Buf_DBN_BLE *response_dst)
{   //config iot_topic
    uint8_t ret = 0;
    uint8_t i = 0;
    int _len = 0;
    clear_buf_dbn_ble(response_dst);
    response_dst->magic = MAGIC_BYTE_DBN_DEFAULT;
    response_dst->cmd = CMD_DBN_GET_IOT_TOPIC;
    response_dst->dat[0] = g_iot_topic.clientid_enable + 0x30;
    i++; 
    i++;
    memcpy(&(response_dst->dat[i]), g_iot_topic.topic_pub, strlen(g_iot_topic.topic_pub));
    i += strlen(g_iot_topic.topic_pub);
    i++;
    memcpy(&(response_dst->dat[i]), g_iot_topic.topic_sub, strlen(g_iot_topic.topic_sub));
    i += strlen(g_iot_topic.topic_sub);
    response_dst->dat_len = i;
    response_dst->pkg_amount = i / MAX_BLE_DAT_RESPONSE_LEN;
    if((i % MAX_BLE_DAT_RESPONSE_LEN) > 0)
    {
        response_dst->pkg_amount += 1;
    }
    response_dst->pkg_seq = 0;
    response_dst->flag = 1;
}


uint8_t set_response_buf(Buf_DBN_BLE *response_dst, uint8_t magic, uint8_t cmd, uint8_t * dat, uint8_t dat_len)
{
    uint8_t ret = 0;
    uint8_t i = 0;
    clear_buf_dbn_ble(response_dst);
    response_dst->magic = magic;
    response_dst->cmd = cmd;

    uint8_t _amount = dat_len / MAX_BLE_DAT_RESPONSE_LEN;
    if((dat_len % MAX_BLE_DAT_RESPONSE_LEN) > 0)
    {
        _amount++;
    }
    response_dst->pkg_amount = _amount;
    response_dst->pkg_seq = 0;
    response_dst->dat_len = dat_len;
    for(i = 0; i < dat_len; i++)
    {
        response_dst->dat[i] = dat[i];
    }
    response_dst->flag = 1;

    return ret;
}

uint16_t compute_ckb(uint8_t header_0, uint8_t header_1, uint8_t header_cmd, uint8_t *dat, uint8_t dat_len)
{
    uint16_t ret = 0;
    uint8_t i = 0;
    uint8_t _dxor = header_0 ^ header_1 ^ header_cmd;
    uint8_t _dsum = header_0 + header_1 + header_cmd;

    for(i = 0; i < dat_len; i++)
    {
        _dxor ^= dat[i];
        _dsum += dat[i];
    }
    ret = _dxor;
    ret = (ret << 8) + (_dsum % 0x100);

    return ret;
}


uint8_t set_response_tran_to_notify(uint8_t *dat_ori, uint8_t dat_len, BLE_Notify_Buf * notify_dst)
{
    uint8_t ret = 0;
    uint8_t i = 0;
    if(g_flag_bt_state == 0){
        return ret;
    }
    if(notify_dst->flag)
    {   //dst not idle
        return ret;
    }
    if(dat_len < 6)
    {
        return ret;
    }
    
    for(i = 0; i < dat_len; i++)
    {
        notify_dst->buf[i] = dat_ori[i];
    }
    notify_dst->len = dat_len;
    notify_dst->flag = 1;
}


//response_ori  must set_response_buf first
uint8_t set_response_to_notify(Buf_DBN_BLE *response_ori, BLE_Notify_Buf * notify_dst)
{
    uint8_t ret = 0;
    uint8_t i = 0;
    uint16_t _ckbl = 0;
    if(notify_dst->flag)
    {   //dst not idle
        return ret;
    }
    if(response_ori->flag == 0)
    {   //ori idle
        return ret;
    }
    if(response_ori->pkg_amount <= 1)
    {
        //没有分包的情况
        notify_dst->buf[0] = response_ori->magic;
        if(response_ori->magic == MAGIC_BYTE_DBN_TRANSPARENT)
        {
            notify_dst->buf[1] = response_ori->pkg_seq;
        }
        else
        {
            notify_dst->buf[1] = 0;
        }
        notify_dst->buf[2] = response_ori->dat_len + 1; // 1 is cmd_byte
        notify_dst->buf[3] = response_ori->cmd;
        _ckbl = compute_ckb(notify_dst->buf[1], notify_dst->buf[2], notify_dst->buf[3], response_ori->dat, response_ori->dat_len);
        for(i = 0; i < response_ori->dat_len; i++)
        {
            notify_dst->buf[i + 4] = response_ori->dat[i];
        }
        notify_dst->buf[i + 4] = (uint8_t)(_ckbl >> 8);
        i++;
        notify_dst->buf[i + 4] = (uint8_t)(_ckbl);
        i++;
        notify_dst->len = i + 4;
//        if(g_flag_debug)
//        {
//            PRINT("set_response_to_notify_dst__\n");
//            for(i = 0; i < notify_dst->len; i++)
//            {
//                PRINT(" %02X", notify_dst->buf[i]);
//            }
//        }
        notify_dst->flag = 1;

        clear_buf_dbn_ble(response_ori);
        return 1;
    }
    else
    {
        notify_dst->buf[0] = response_ori->magic;
        uint8_t _pkg_amount = response_ori->pkg_amount;
        uint8_t _pkg_seq = response_ori->pkg_seq;
        uint8_t _remain_len = response_ori->dat_len - response_ori->dat_offset;
        if(_remain_len > MAX_BLE_DAT_RESPONSE_LEN)
        {
            _remain_len = MAX_BLE_DAT_RESPONSE_LEN;
        }
        _pkg_seq += 1;
        notify_dst->buf[1] = (_pkg_amount << 4)|(_pkg_seq);
        notify_dst->buf[2] = _remain_len + 1;   // 1 is cmd_byte
        notify_dst->buf[3] = response_ori->cmd;

        _ckbl = compute_ckb(notify_dst->buf[1], notify_dst->buf[2], notify_dst->buf[3],
            &(response_ori->dat[response_ori->dat_offset]), _remain_len);
        for(i = 0; i < _remain_len; i++)
        {
            notify_dst->buf[i + 4] = response_ori->dat[response_ori->dat_offset + i];
        }
        notify_dst->buf[i + 4] = (uint8_t)(_ckbl >> 8);
        i++;
        notify_dst->buf[i + 4] = (uint8_t)(_ckbl);
        i++;

        response_ori->dat_offset += _remain_len;
        response_ori->pkg_seq += 1;
        notify_dst->len = i + 4;


//        if(g_flag_debug)
//        {
//            PRINT("\nset_notify_dst,amount:%d,seq:%d,offset:%d\n", response_ori->pkg_amount,response_ori->pkg_seq, response_ori->dat_offset);
//            for(i = 0; i < notify_dst->len; i++)
//            {
//                PRINT(" %02X", notify_dst->buf[i]);
//            }
//            PRINT("\n");
//        }

        notify_dst->flag = 1;
        if(response_ori->pkg_amount == response_ori->pkg_seq)
        {
            clear_buf_dbn_ble(response_ori);
        }
        return 1;

    }

}


static uint8_t unpack_packs(uint8_t *pkg, uint8_t len)
{
    static uint8_t _offset = 0;
    uint8_t _header_0 = pkg[1];
    uint8_t _header_0_high = _header_0 >> 4;
    uint8_t _header_0_low = _header_0 % 0x10;
    uint8_t _len = pkg[2];
    uint8_t _cmd = pkg[3];
    uint8_t i = 0, j = 0, k = 0;
    uint8_t _amount = 0;

    if(_header_0_high)
    {
        if(_header_0_low == 1)
        {
            g_buf_ble_response.magic = pkg[0];
            g_buf_ble_response.pkg_amount = _header_0_high;
            g_buf_ble_response.pkg_seq = _header_0_low;
            g_buf_ble_response.cmd = _cmd;
            memcpy(&g_buf_ble_response.dat, &pkg[4], _len - 1);
            _offset = _len - 1;
            g_buf_ble_response.dat_len = _len - 1;
        }
        else
        {
            if((g_buf_ble_response.pkg_amount != _header_0_high) || (g_buf_ble_response.cmd != _cmd))
            {
                //printf("\nNot_the_right_sub_pack!\n");
                clear_buf_dbn_ble_all(&g_buf_ble_response);
                return 0;
            }
            if(g_buf_ble_response.pkg_seq != (_header_0_low -1))
            {
                //printf("\nNot_the_right_sub_pack!!\n");
                clear_buf_dbn_ble_all(&g_buf_ble_response);
                return 0;
            }
            g_buf_ble_response.pkg_seq = _header_0_low;
            g_buf_ble_response.dat_len += (_len - 1);  // not include cmd_byte
            memcpy(&g_buf_ble_response.dat[_offset], &pkg[4], _len - 1);
            _offset += (_len - 1);
        }
    }
    else
    {
        clear_buf_dbn_ble(&g_buf_ble_response);
        g_buf_ble_response.magic = pkg[0];
        g_buf_ble_response.pkg_amount = 1;
        g_buf_ble_response.pkg_seq = 0;
        g_buf_ble_response.cmd = _cmd;
        g_buf_ble_response.dat_len = (_len - 1);
        memcpy(g_buf_ble_response.dat, &pkg[4], _len - 1);
    }

    if(_header_0_high == _header_0_low)
    {
        // received end.
//        if(g_flag_debug)
//        {
//            printf("\nReceive_pack_over:\n");
//            for(i = 0; i < g_buf_ble_response.dat_len; i++)
//            {
//                printf(" %02X", g_buf_ble_response.dat[i]);
//            }
//            printf("\nEnd\n");
//        }


        if(g_buf_ble_response.cmd == CMD_DBN_CHECK_PASS)
        {
           memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
           if(g_buf_ble_response.dat_len != 6)
           {
               //response pass failed
               tmp_ble_buf[0] = 0x01;
               set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
           }
           else
           {
               char _pass = check_ble_safe_pass(g_buf_ble_response.dat);
               if(_pass)
               {
                   //response ok
                   tmp_ble_buf[0] = 0x0;
                   set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
               }
               else
               {
                   //response failed
                   tmp_ble_buf[0] = 0x01;
                   set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
               }
           }

        }   //end if g_buf_ble_response.cmd == CMD_DBN_CHECK_PASS
        else if(g_buf_ble_response.cmd == CMD_DBN_MODIFY_PASS)
        {
           memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
           if(g_buf_ble_response.dat_len != 12)
           {
               //response failed
               tmp_ble_buf[0] = 0x01;
           }
           else
           {
               char _pass = check_ble_safe_pass(g_buf_ble_response.dat);
               if(_pass)
               {
                   //response ok
                   set_ble_safe_pass(&g_buf_ble_response.dat[6]);
                   tmp_ble_buf[0] = 0x00;
               }
               else
               {
                   //response failed
                   tmp_ble_buf[0] = 0x01;
               }
           }
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
        }   //end if g_buf_ble_response.cmd == CMD_DBN_MODIFY_PASS
        else if(g_buf_ble_response.cmd == CMD_DBN_SET_IOT_NET)
        {
            for(i = 0, j = 0, k = 0; i < g_buf_ble_response.dat_len; i++)
            {
                if(g_buf_ble_response.dat[i] == 0x00)
                {
                    j++;
                    if(k == 0)
                    {
                        //iot _host
                        PRINT("Rcv_Host:%s\n", tmp_ble_buf); 
                        memcpy(iot_net_info.remote_addr, tmp_ble_buf, j);
                        
                    }
                    else if(k == 1)
                    {
                        PRINT("Rcv_Port:%s\n", tmp_ble_buf);
                        uint16_t _port = 0;
                        for(j = 0; j < strlen(tmp_ble_buf); j++)
                        {
                            _port *= 10;
                            _port += tmp_ble_buf[j] - 0x30;
                        }
                        iot_net_info.mqtt_port = _port;
                    }
                    else if(k == 2)
                    {
                        PRINT("Rcv_Client:%s\n", tmp_ble_buf);
                        if((strlen(tmp_ble_buf) == 1) && (tmp_ble_buf[0] == 0x20))
                        {
                            PRINT("Client_use local_serial\n");
                        }
                        else
                        {
                            memcpy(iot_net_info.client_id, tmp_ble_buf, j);
                        }
                    }
                    else if(k == 3)
                    {
                        PRINT("Rcv_Username:%s\n", tmp_ble_buf);
                        memcpy(iot_net_info.username, tmp_ble_buf, j);
                    }
                    else if(k == 4)
                    {
                        PRINT("Rcv_Pass:%s\n", tmp_ble_buf);
                        memcpy(iot_net_info.password, tmp_ble_buf, j);
                    }
                    k++;
                    memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
                    j = 0;
                }
                else
                {
                    tmp_ble_buf[j] = g_buf_ble_response.dat[i];
                    j++;
                }
            }
            if(k == 4)
            {
                PRINT("Rcv_Pass:%s\n", tmp_ble_buf);
                
                memcpy(iot_net_info.password, tmp_ble_buf, strlen(tmp_ble_buf) + 1);
            }
            memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
            write_net_config(&local_net_cfg, &net_center_info, &iot_net_info, &g_iot_topic);
                
            // response finally
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
            //clear_buf_dbn_ble_all(&g_buf_ble_response);
        } //end if CMD_DBN_SET_IOT_NET
        else if(g_buf_ble_response.cmd == CMD_DBN_SET_IOT_TOPIC)
        {
            for(i = 0, j = 0, k = 0; i < g_buf_ble_response.dat_len; i++)
            {
                if(g_buf_ble_response.dat[i] == 0x00)
                {
                    //j++;
                    if(k == 0)
                    {
                        g_iot_topic.clientid_enable = tmp_ble_buf[0] - 0x30;
                    }
                    else if(k == 1)
                    {
//                        if(g_flag_debug)
//                        {
//                            printf("rcv_topic_pub_:%s\n", tmp_ble_buf);
//                            for(f = 0; f < j; f++)
//                            {
//                                printf(" %02X", tmp_ble_buf[f]);
//                            }
//                            printf(", j:%d\n", j);
//                        }
                        memset(g_iot_topic.topic_pub, 0, MAX_TOPIC_LENGTH);
                        memcpy(g_iot_topic.topic_pub, tmp_ble_buf, j + 1);
                    }
                    
                    k++;
                    j = 0;
                    memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
                }
                else
                {
                    tmp_ble_buf[j] = g_buf_ble_response.dat[i];
                    j++;
                }
            }
            if(k == 2)
            {
//                if(g_flag_debug)
//                {
//                    printf("rcv_topic_sub_:%s\n", tmp_ble_buf);
//                }
                memset(g_iot_topic.topic_sub, 0, MAX_TOPIC_LENGTH);
                memcpy(g_iot_topic.topic_sub, tmp_ble_buf, strlen(tmp_ble_buf) + 1);
            }
            memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
            write_net_config(&local_net_cfg, &net_center_info, &iot_net_info, &g_iot_topic);
            
            // response finally
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
        } // end if CMD_DBN_SET_IOT_TOPIC
        
    }

    return 0;
}



void manage_dbn_ble_default(uint8_t *pkg, uint8_t len)
{
    uint8_t _header_0 = pkg[1];
    uint8_t _header_0_high = 0;
    uint8_t _header_0_low = _header_0 % 0x10;
    uint8_t _len = pkg[2];
    uint8_t _cmd = pkg[3];
    uint8_t _tmp = 0;
    uint8_t i = 0, k = 0;

    memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);

    switch(_cmd)
    {
        case CMD_DBN_GET_DEV_INFO:
        {
            i = set_dev_info_to_ready(tmp_ble_buf);

            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);

            // printf("\nGet_dev_info\n");
        } break;
        case CMD_DBN_SET_LSSC_NET:
        {
            //printf("Set_Net_info_len:%d\n", len);
            if(len < 34)
            {
                return;
            }
            
            i = 4;
            memcpy(local_net_cfg.lip, &pkg[i], 4);
            i += 4;
            memcpy(local_net_cfg.sub, &pkg[i], 4);
            i += 4;
            memcpy(local_net_cfg.gw, &pkg[i], 4);
            i += 4;
            memcpy(net_center_info.lssc_ip, &pkg[i], 4);
            //i += 4;
            //printf("Reset_lip:%d\n",local_net_cfg.lip[3]);  
            i = 24;
            //printf("Reset_lport:%02X %02X\n",pkg[24], pkg[25]);  
            //memcpy(local_net_cfg.dns
            // local_net_cfg.port_ssc_tcp = *(uint16_t *)(&pkg[24]);  //TOOD: Will err, why?
            local_net_cfg.port_ssc_tcp = (pkg[25] << 8) | pkg[24];//  This is OK
            i += 2;
            // local_net_cfg.port_ssc_udp = *(uint16_t *)(&pkg[i]);
            local_net_cfg.port_ssc_udp =(pkg[27] <<8 ) | pkg[26];
            i += 2;
            // local_net_cfg.port_ssc_udp_message = *(uint16_t *)(&pkg[i]);
            local_net_cfg.port_ssc_udp_message = (pkg[29] << 8) | pkg[28];
            i += 2;
            // local_net_cfg.port_dev_tcp = *(uint16_t *)(&pkg[i]);
            local_net_cfg.port_dev_tcp = (pkg[31] << 8) | pkg[30];
            net_center_info.tcp_port = local_net_cfg.port_dev_tcp;
            i += 2;
            // local_net_cfg.port_dev_udp = *(uint16_t *)(&pkg[32]);
            local_net_cfg.port_dev_udp = (pkg[33] << 8) | pkg[32];
            //printf("Will_reset_net_param___\n");
            write_net_config(&local_net_cfg, &net_center_info, &iot_net_info, &g_iot_topic);
            //response
            tmp_ble_buf[0] = 0;
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
            
        } break;
        case CMD_DBN_GET_LSSC_NET:
        {    
            i = set_net_info_to_ready(tmp_ble_buf);
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
//            printf("Get_Net_Info\n");
        } break;  
        case CMD_DBN_GET_IOT_NET:
        {
            set_response_iot_net(&g_buf_ble_response);
        } break;
        case CMD_DBN_SET_IOT_NET:
        {
            unpack_packs(pkg, len);
        } break;
        case CMD_DBN_SET_IOT_TOPIC:
        {
            unpack_packs(pkg, len);        
        } break;
        case CMD_DBN_GET_IOT_TOPIC:
        {
            set_response_iot_topic(&g_buf_ble_response);
        } break;
        case CMD_DBN_RESET_DEV:
        {
            //Restart Dev
            NVIC_SystemReset();
        } break;
       case CMD_DBN_CHECK_PASS:
       {
           unpack_packs(pkg, len);
       } break;
        case CMD_DBN_SET_CJQ_PARAM:
        {
//            PRINT("\nSet_Cjq_param\n");
            // unpack_pkg_set_cjq_param(pkg, len);
            tmp_ble_buf[0] = 0;
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);

            // para_store_init();
        } break;
        case CMD_DBN_GET_CJQ_PARAM:
        {
            i = 0;

            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
//            PRINT("\nGet_Cjq_param\n");
        } break;
        case CMD_DBN_LOOP_SENS_LIST: {
//            PRINT("SENS_CNG: %02X\n", pkg[4]);
            memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
            
            
        } break;
        case CMD_DBN_SET_FACTORY:
        case CMD_DBN_SET_CJQ_FACTORY: {
            // 出厂初始化
            tmp_ble_buf[0] = 0;
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
            factory_dev_info();

            Delay_Ms(10);
            
            //TODO: 不整个设备复位，复位除了蓝牙的部分，即蓝牙正常，其他部分重新初始化
               
        } break;
        case CMD_DBN_RW_UART_BAUD:{ // 
            uint8_t _rw = pkg[4];
            uint32_t _baud = 0;
            i = 0;
            tmp_ble_buf[i++] = _rw;
            tmp_ble_buf[i++] = 0x01; //status

            if(_rw == 0){// read baud
                tmp_ble_buf[i++] = g_max_counter_bt_min; // Idle Ble timeout
                tmp_ble_buf[i++] = (uint8_t)g_storage_uart_baud;  //1 g_storage_uart_baud? 2 g_storage_uart_baud_2
                tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 8);
                tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 16);
                tmp_ble_buf[i++] = 0x02; 
                tmp_ble_buf[i++] = (uint8_t)g_storage_uart_baud_2;
                tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud_2 >> 8);
                tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud_2 >> 16);  
                // 4BYte Reserved

            }
            else {  // write baud
                alter_dev_baud(&pkg[5]);  // 
                g_storage_uart_num = pkg[5];
                g_storage_uart_baud = pkg[6];
                g_storage_uart_baud |= (uint16_t)(pkg[7] << 8) & 0xFF00;
                g_storage_uart_baud |= (uint32_t)(pkg[8] << 16) & 0xFF0000;
                
                tmp_ble_buf[i++] = g_storage_uart_baud;
                tmp_ble_buf[i++] = (uint8_t)g_storage_uart_baud;
                tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 8);
                tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 16);
                tmp_ble_buf[i++] = 0x00; tmp_ble_buf[i++] =  0x00; tmp_ble_buf[i++] = 0x00; tmp_ble_buf[i++] = 0x00;    // 4BYte Reserved
            }
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
        } break;
        case CMD_DBN_UPDATE_DEV_SERIAL:
        {
            alter_dev_serila(&pkg[4]);
            //response
            tmp_ble_buf[0] = 1;
            set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
        } break;
        case CMD_SENS_ACS_ENABLE: {
            // 线圈动态
            g_dbn_ble_state_acs_enable.enable = pkg[5];

            if(g_dbn_ble_state_acs_enable.enable){
                g_dbn_ble_state_acs_enable.interval = pkg[6] * 0x7F;
                g_dbn_ble_state_acs_enable.timeout_min = pkg[7];
                if(g_dbn_ble_state_acs_enable.timeout_min){
                    g_dbn_ble_state_acs_enable.counter = mstick();
                    g_dbn_ble_state_acs_enable.timeout_counter = g_dbn_ble_state_acs_enable.timeout_min * 60 * 100;     // TODO: min --> ms
                }
                g_dbn_ble_state_acs_enable.flag = 1;
            }
            else{
                g_dbn_ble_state_acs_enable.flag = 0;
            }
            PRINT("Rcv_acs_enable_flag: %d\n", g_dbn_ble_state_acs_enable.flag);
        } break;
        default:
        {
        } break;
    }

}


void manage_dbn_ble_transparent(uint8_t *pkg, uint8_t len)
{
    //
    // transparent_485(pkg, len);
    // UART1_SendString(pkg, len);
    UART2_SendString(pkg, len);
}

void poll_dbn_ble(void)
{
    uint8_t i = 0;
    uint8_t magic = 0;
    if(g_ble_rcv_buf.flag)
    {
       if(g_flag_debug && g_flag_counter_ota.flag == 0)
       {
           PRINT("profile ChangeCB CHAR1?..:%s, len:%d \n", g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
           for(i = 0; i < g_ble_rcv_buf.len; i++)
           {
               PRINT(" %02X", g_ble_rcv_buf.buf[i]);
           }
           PRINT("\n");
       }
       if(g_flag_counter_ota.flag == 0){
            magic = check_pkg(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
       }
        
        // printf("_magic: %02X\n", magic);
        if(g_flag_counter_ota.flag){
            manage_dbn_ble_transparent(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
        }
        else{
            if(magic != 0)
            {
                if(magic == MAGIC_BYTE_DBN_DEFAULT)
                {
                    manage_dbn_ble_default(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
                }
                else if (magic == MAGIC_BYTE_DBN_TRANSPARENT)
                {
                    manage_dbn_ble_transparent(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
                }
            }
        }

//        memcpy(g_notify_buftemp.buf, g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
//        g_notify_buftemp.len = g_ble_rcv_buf.len;
//        g_flag_notify_temp = 1;
        clear_ble_notify_buf(&g_ble_rcv_buf);
    }
    if(g_notify_buftemp.flag == 0)
    {
//        report_sens_acs();
        g_flag_notify_temp = set_response_to_notify(&g_buf_ble_response, &g_notify_buftemp);
    }
}



