#include "include.h"
#include "api.h"

#if  LE_MASTER_SLAVE_TEST
#include "ble_client.h"
#endif //LE_MASTER_SLAVE_TEST

typedef struct{
    u8 disp_status;
    u8 hid_menu_flag;
    u8 hid_discon_flag;
    u8 user_kl_flag;
    u8 ble_status;
    u8 bt_is_inited;
    u8 need_pairing : 1;
} func_bt_t;
func_bt_t f_bt;

void bt_new_name_init(void);
void lock_code_charge(void);
void unlock_code_charge(void);

/********************************************************/
extern void bt_tws_set_operation(uint8_t *cmd);

#ifndef LE_MASTER_SLAVE_TEST
#define LE_ALL_SLAVE_TEST   1
#endif // LE_MASTER_SLAVE_TEST

#if LE_ALL_SLAVE_TEST
WEAK u32 ble_get_scan_data(u8 *scan_buf, u32 buf_size)
{
    return 0;
}

WEAK u32 ble_get_adv_data(u8 *adv_buf, u32 buf_size)
{
    return 0;
}

static void le_adv_param_init(void)
{
    adv_param_t param;

    memset((u8 *)&param, 0, sizeof(param));

    param.adv_en = 1;
    param.adv_type = ADV_TYPE_IND;
    param.adv_len = ble_get_adv_data(param.adv_data, sizeof(param.adv_data));
    param.scan_rsp_len = ble_get_scan_data(param.scan_rsp, sizeof(param.scan_rsp));
    param.adv_int_min = param.adv_int_max = 0x030;      // Unit: 625us, set value to 0x030 means expected interval is 30ms
    ble_set_adv_params(&param);
}

void btstack_ble_init_callback(void)
{
#if LE_PAIR_EN
    le_sm_init(1, 3, 5);
#else
    le_sm_init(0, 3, 0);
#endif // LE_PAIR_EN

    ble_txpkt_init();
    gap_random_address_set_mode(GAP_RANDOM_ADDRESS_TYPE_OFF);
    le_adv_param_init();

    ble_init_att();

    att_server_init(ble_get_profile_data());
}

void ble_init_register(void)
{
    ble_init_callback_register(btstack_ble_init_callback);
}
#endif

void bsp_bt_init(void)
{
    //Update the settings of the configuration tool
    cfg_bt_rf_def_txpwr = xcfg_cb.bt_rf_pwrdec;
    cfg_bt_page_txpwr = xcfg_cb.bt_rf_page_pwrdec;
    cfg_ble_page_txpwr = xcfg_cb.ble_rf_page_pwrdec;
    cfg_ble_page_rssi_thr = xcfg_cb.ble_page_rssi_thr;

    cfg_bt_support_profile = (PROF_SPP*BT_SPP_EN*(xcfg_cb.bt_spp_en)) | (PROF_HID*BT_HID_EN*xcfg_cb.bt_hid_en);

    cfg_bt_dual_mode = BT_DUAL_MODE_EN * xcfg_cb.ble_en;
    cfg_bt_max_acl_link = BT_2ACL_EN * xcfg_cb.bt_2acl_en + 1;

#if BT_SPP_EN
    cfg_bt_spp_rx_flow_ctrl_en = BT_SPP_RX_FLOW_CTRL_EN;
#endif // BT_SPP_EN

    sys_cb.discon_reason = 0xff;

#if BT_FCC_TEST_EN
    bt_fcc_init();
#endif
    memset(&f_bt, 0, sizeof(func_bt_t));
    f_bt.disp_status = 0xfe;
    f_bt.need_pairing = 1;  //f the connection is not successful after startup, you need to broadcast the pairing

#if  (LE_MASTER_SLAVE_TEST || LE_ALL_SLAVE_TEST)

    #if  (LE_APP_EN)
        ble_init_register();
    #endif

#endif // LE_MASTER_SLAVE_TEST
    bt_setup();
    printf("System configuration completed!\n");
}

void bsp_spp_disinit(void)
{
    //Update the settings of the configuration tool
    cfg_bt_rf_def_txpwr = xcfg_cb.bt_rf_pwrdec;
    cfg_bt_page_txpwr = xcfg_cb.bt_rf_page_pwrdec;
    cfg_ble_page_txpwr = xcfg_cb.ble_rf_page_pwrdec;
    cfg_ble_page_rssi_thr = xcfg_cb.ble_page_rssi_thr;

    cfg_bt_support_profile = (PROF_SPP*BT_SPP_EN*(xcfg_cb.bt_spp_en)) | (PROF_HID*BT_HID_EN*xcfg_cb.bt_hid_en);

    cfg_bt_dual_mode = BT_DUAL_MODE_EN * xcfg_cb.ble_en;
    cfg_bt_max_acl_link = BT_2ACL_EN * xcfg_cb.bt_2acl_en + 1;

    cfg_bt_spp_rx_flow_ctrl_en = 0;

    sys_cb.discon_reason = 0xff;

    memset(&f_bt, 0, sizeof(func_bt_t));
    f_bt.disp_status = 0xfe;
    f_bt.need_pairing = 1;  //if the connection is not successful after startup, you need to broadcast the pairing

    bt_setup();             //打开蓝牙
    bt_set_scan(0x00);      //关闭蓝牙可被发现--一定要放后面
    printf("spp closed successfully!\n");
}

void bsp_bt_close(void)
{
}

void tws_user_key_process(uint32_t *opcode)
{
//*opcode

}

void tws_warning_process(uint32_t *opcode)
{
}

void bsp_bt_vol_change(void)
{
#if BT_A2DP_VOL_CTRL_EN || BT_TWS_EN
    if((xcfg_cb.bt_a2dp_vol_ctrl_en && (bt_get_status() >= BT_STA_CONNECTED)) || bt_tws_is_connected()) {
        bt_music_vol_change();     //Notify phone volume has been adjusted
    }
#endif
}

uint bsp_bt_get_hfp_vol(uint hfp_vol)
{
    return 0;
}

void bsp_bt_call_volume_msg(u16 msg)
{
//    printf("call vol: %d\n", sys_cb.hfp_vol);
}

void bt_emit_notice(uint evt, void *params)
{
//    u8 *packet = params;
    u8 opcode = 0;
    u8 scan_status = 0x03;

    switch(evt) {
    case BT_NOTICE_INIT_FINISH:
        if(cfg_bt_work_mode == MODE_BQB_RF_BREDR) {
            opcode = 1;                     //Test mode, no back-connection, open to be found and connected
        } else {
            if(bt_nor_get_link_info(NULL)) {
                scan_status = 0x02;         //There is connection information, which can be found if it is not opened
            }
        }

#if BT_DISCOVER_CTRL_EN
        scan_status = 0;
#endif

#if VUSB_TBOX_QTEST_EN
        qtest_create_env();
#endif
        bt_start_work(opcode, scan_status);
#if LE_WIN10_POPUP
        ble_adv0_set_ctrl(1);				//Open LE broadcast, which can be found by win10
#endif
        break;

    case BT_NOTICE_DISCONNECT:
#if LE_WIN10_POPUP
        ble_adv0_set_ctrl(1);				//Open LE broadcast, which can be found by win10
#endif
        delay_5ms(5);
        break;
    case BT_NOTICE_CONNECTED:
#if LE_WIN10_POPUP
        ble_adv0_set_ctrl(0);				//Turn off LE broadcast
#endif
        delay_5ms(5);
        break;

    case BT_NOTICE_HID_CONN_EVT:
        break;
    }
}
