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

#if BT_FCC_TEST_EN
    #define WORK_MODE           MODE_FCC_TEST
#elif BT_BQB_RF_EN
    #define WORK_MODE           MODE_BQB_RF_BREDR
#elif LE_BQB_RF_EN
    #define WORK_MODE           MODE_BQB_RF_BLE
#elif BT_DUT_MODE_EN
    #define WORK_MODE           MODE_NORMAL_DUT
#else
    #define WORK_MODE           MODE_NORMAL
#endif

#define BT_PROFILE          (PROF_SPP*BT_SPP_EN) | (PROF_HID*BT_HID_EN)
#define BT_CODEC            0//(CODEC_SBC) | (CODEC_AAC*BT_A2DP_AAC_AUDIO_EN) | (CODEC_MSBC * BT_HFP_MSBC_EN) | (CODEC_PLC * BT_PLC_EN)


///baseband
uint8_t cfg_bt_rf_def_txpwr         = 0;        //Reduce RF transmission power of preset parameters, unit: 0.5dbm
uint8_t cfg_bt_page_txpwr           = 0;        //Reduce back-connected RF transmission power, unit: 3dbm
uint8_t cfg_bt_inq_txpwr            = 0;        //Reduce search RF transmission power, unit: 3dbm
uint8_t cfg_ble_page_txpwr          = 0;        //Reduce the RF transmission power of the formation, unit: 3dbm
uint8_t cfg_ble_page_rssi_thr       = 0;        //Set the teaming range rssi

///stack
uint8_t cfg_bt_work_mode            = WORK_MODE;
uint8_t cfg_bt_max_acl_link         = BT_2ACL_EN+1;

bool cfg_bt_dual_mode               = BT_DUAL_MODE_EN;
bool cfg_bt_scan_ctrl_mode          = BT_DISCOVER_CTRL_EN;
bool cfg_bt_simple_pair_mode        = BT_SIMPLE_PAIR_EN;
#if DUEROS_SUPPORT_EN
bool cfg_bt_ble_adv                 = false;
#endif

uint16_t cfg_bt_support_profile     = BT_PROFILE;
uint16_t cfg_bt_support_codec       = BT_CODEC;

uint8_t cfg_bt_hid_type             = BT_HID_TYPE;

uint8_t cfg_bt_connect_times        = 2;                                //Press the key to retry the connection, 5.12s * n
uint8_t cfg_bt_pwrup_connect_times  = BT_POWER_UP_RECONNECT_TIMES;      //Number of power-on reconnection retries, 5.12s * n
uint16_t cfg_bt_sup_to_connect_times = BT_TIME_OUT_RECONNECT_TIMES;     //The number of retries for timeout disconnection and reconnection, 5.12s * n, set (- 1) as always reconnection

#if BT_LINK_INFO_PAGE1_EN
uint8_t const cfg_bt_link_info_items = 8;   //Number of saved back-connection information (minimum 1, maximum 8)
#endif

///app
const char bt_local_name[] = BT_NAME_DEFAULT;
const char bt_local_addr[6] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};



//Custom Bluetooth category icon, select as needed
u32 bt_get_class_of_device(void)
{
    if(cfg_bt_work_mode == MODE_BQB_RF_BREDR) {
        return 0x0000;
    }
#if BT_HID_TYPE == 2
    return 0x0025c0;    //GamePad           - Game handle
#else
//  return 0x002540;    //Keyboard          - Keyboard icon, Android with power display, IOS without power display. All IOS can be connected to HID for taking pictures.
//  return 0x240418;    //HeadPhone         - Headphone icon, Android and IOS are both charged.
//    return 0x240404;  //WearableHeadset   - Headphone icon, Android and IOS are both charged. (used by default)
    return 0x040680;    //printer   - Printer icon
#endif
}

//PIN pairing code (up to 16 characters), default "0000"
#if !BT_SIMPLE_PAIR_EN
const char *bt_get_pin_code(void)
{
    return "0000";
}
#endif

//The callback interval is (N+3000) mS. The larger the interval, the slower the next callback, and the easier it is to be searched by other mobile phones. When the TWS function is turned off, N should be greater than or equal to 2000
//u32 bt_get_conn_fail_delay(void)
//{
//    return 200;
//}

//Whether it is necessary to always connect back to the mobile phone
//bool bt_is_always_reconn(void)
//{
//    return false;
//}

//Customize the connection method. Order is the serial number of the connection information
//uint8_t connect_addr[6];
//void bt_cocnnect_order(uint8_t order)
//{
//    if(bt_nor_get_link_info_addr(connect_addr, order)) {
//        bt_connect_address();
//    }
//}
//
//uint8_t bt_get_connect_addr(uint8_t *bd_addr, uint16_t *times)
//{
//    *times = 2;       //n*5.12s
//    memcpy(bd_addr, connect_addr, 6);
//    return 1;
//}

const char *bt_get_local_name(void)
{
#if 1
#if IODM_TEST_MODE
    bt_get_new_name(xcfg_cb.bt_name);
#endif // IODM_TEST_MODE
    return xcfg_cb.bt_name;
#else
    return bt_local_name;
#endif // 1
}


void bt_clr_master_addr(void)
{
//    u8 addr[6];
//    memset(addr, 0, 6);
//    cm_write8(PARAM_MASTER_ADDR_VALID, 0);
//    cm_write(addr, PARAM_MASTER_ADDR, 6);
//    cm_sync();
}

void bt_save_master_addr(u8 *addr)
{
//    if (bt_tws_is_ms_switch()||qtest_get_mode()) {
//        cm_write8(PARAM_MASTER_ADDR_VALID, 1);
//        cm_write(addr, PARAM_MASTER_ADDR, 6);
//        cm_sync();
//    }
}

bool bt_get_master_addr(u8 *addr)
{
//    if ((bt_tws_is_ms_switch()||qtest_get_mode()) && cm_read8(PARAM_MASTER_ADDR_VALID)) {
//        cm_read(addr, PARAM_MASTER_ADDR, 6);
//        return true;
//    }
    return false;
}

//Delete all pairing information
void bt_clr_all_link_info(void)
{
    bt_clr_master_addr();
    bt_nor_delete_link_info();
//    bt_tws_delete_link_info();
}

//Delete TWS pairing information
void bt_tws_clr_link_info(void)
{
    bt_clr_master_addr();
//    bt_tws_delete_link_info();
}


void bt_get_local_bd_addr(u8 *addr)
{
    if (bt_get_master_addr(addr)) {
        return;
    }
#if BT_LOCAL_ADDR
    param_random_key_read(&addr[2]);
    addr[0] = 0x41;
    addr[1] = 0x42;
#else
    #if IODM_TEST_MODE
    if(bt_get_qr_addr(addr)){
        return;
    }
    #endif // IODM_TEST_MODE
    memcpy(addr, xcfg_cb.bt_addr, 6);
#endif
}

u32 bt_get_rand_seed(void)
{
    return sys_cb.rand_seed;
}

void bt_get_link_info(void *buf, u16 addr, u16 size)
{
    //printf("bt_read: %04x,%04x, %08lx\n", addr, size, BT_CM_PAGE(addr));
    {
        if ((addr + size) <= PAGE_DATA_SIZE) {
            cm_read(buf, BT_CM_PAGE(addr), size);
#if BT_LINK_INFO_PAGE1_EN
        } else {
            cm_read(buf, BT_CM_PAGE1(addr - link_info_page_size), size);
#endif
        }
    }
    //print_r(buf, size);
}

void bt_put_link_info(void *buf, u16 addr, u16 size)
{
    //printf("bt_write: %04x,%04x, %08lx\n", addr, size, BT_CM_PAGE(addr));
    //print_r(buf, size);
    {
        if ((addr + size) <= PAGE_DATA_SIZE) {
            cm_write(buf, BT_CM_PAGE(addr), size);
#if BT_LINK_INFO_PAGE1_EN
        } else {
            cm_write(buf, BT_CM_PAGE1(addr - link_info_page_size), size);
#endif
        }
    }
}

void bt_get_ext_link_info(void *buf, u16 addr, u16 size)
{
    //printf("bt_read: %04x,%04x, %08lx\n", addr, size, BT_CM_PAGE(addr));
    cm_read(buf, EXT_CM_PAGE(addr), size);
    //print_r(buf, size);
}

void bt_put_ext_link_info(void *buf, u16 addr, u16 size)
{
    //printf("bt_write: %04x,%04x, %08lx\n", addr, size, BT_CM_PAGE(addr));
    //print_r(buf, size);
    cm_write(buf, EXT_CM_PAGE(addr), size);
}

void bt_sync_link_info(void)
{
    cm_sync();
}


