

#include "system/includes.h"
#include "media/includes.h"

#include "app_config.h"
#include "app_task.h"

#include "btstack/avctp_user.h"
#include "btstack/btstack_task.h"
#include "btstack/bluetooth.h"
#include "btstack/btstack_error.h"
#include "btctrler/btctrler_task.h"
#include "classic/hci_lmp.h"

#include "bt/bt_tws.h"
#include "bt/bt_ble.h"
#include "bt/bt.h"
#include "bt/vol_sync.h"
#include "bt/bt_emitter.h"
#include "bt_common.h"
#include "aec_user.h"
#include "soundbox.h"

#include "math.h"
#include "spp_user.h"


#include "app_chargestore.h"
#include "app_charge.h"
#include "app_main.h"
#include "app_power_manage.h"
#include "user_cfg.h"

#include "asm/pwm_led.h"
#include "asm/timer.h"
#include "asm/hwi.h"
#include "cpu.h"

#include "ui/ui_api.h"
#include "ui_manage.h"
#include "ui/ui_style.h"

#include "key_event_deal.h"
#include "clock_cfg.h"
#include "gSensor/gSensor_manage.h"
/* #include "soundcard/soundcard.h" */

#include "audio_config.h"
#include "audio_dec.h"
/* #include "audio_reverb.h" */
#include "tone_player.h"
#include "dac.h"
#include "le_smartbox_adv.h"
#if TCFG_PAY_ALIOS_ENABLE && (TCFG_PAY_ALIOS_WAY_SEL == TCFG_PAY_ALIOS_WAY_ALIYUN)
#include "upay.h"
#endif

#define LOG_TAG_CONST        BT
#define LOG_TAG             "[BT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"

#if TCFG_APP_BT_EN

#define __this 	(&app_bt_hdl)

static int bt_switch_back_timer = 0;
static u8 bt_remote_name[32];
static u32 bt_phone_active_start_time = 0;

extern void bt_emitter_audio_set_mute(u8 mute);
/*************************************************************
    此文件函数主要是蓝牙模式各种状态处理

    蓝牙播歌通话各种状态处理

 	 蓝牙协议栈事件处理
**************************************************************/

u8 get_bt_init_status()
{
    return __this->init_ok;
}

u8 get_bt_back_flag()
{
    return __this->bt_back_flag;
}

void set_bt_back_flag(u8 flag)
{
    __this->bt_back_flag = flag;
}


void clr_tws_local_back_role(void)
{
    __this->tws_local_back_role = 0;
}


void bt_reverb_status_change(struct bt_event *bt)
{
}



/*----------------------------------------------------------------------------*/
/**@brief    蓝牙模式切换等待解码停止
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
static int bt_switch_back(void *p)
{
    if (!__this->call_flag) {
        return 0;
    }

    if (bt_switch_back_timer) {
        sys_timeout_del(bt_switch_back_timer);
        bt_switch_back_timer = 0;
    }

    if (bt_must_work()) {
        bt_switch_back_timer = sys_timeout_add(NULL, bt_switch_back, 500);
        return 0;
    }

    if (bt_phone_dec_is_running()) {
        bt_switch_back_timer = sys_timeout_add(NULL, bt_switch_back, 500);
        return 0;
    }
    /* __this->call_flag = 0; */
    __this->bt_back_flag = 2;
    app_task_switch_back();
    return 0;
}

u8 get_a2dp_start_flag()
{
    return __this->a2dp_start_flag;
}


u8 bt_sco_state(void)
{
    return bt_user_priv_var.phone_call_dec_begin;
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙eir信息追加数据
   @param
   @return
   @note    注释掉add_data_2_eir函数就不追加数据
   			追加数据不可以超150byte
*/
/*----------------------------------------------------------------------------*/
u8 const eir_more_data_uuid[] = {
    0x0F, 0x03, 0x00, 0x12, 0x1F, 0x11, 0x2F,
    0x11, 0x0A, 0x11, 0x0C, 0x11, 0x32, 0x11, 0x01, 0x18
};

/* u8 add_data_2_eir(u8 *eir)
{
	u8 len = sizeof(eir_more_data_uuid);
	memcpy(eir,eir_more_data_uuid,len);

	return len;
}  */


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙电话本获取回调函数ui接管
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/

extern int __attribute__((weak))  ui_phonebook_packet_handler(u8 type, const u8 *name, const u8 *number, const u8 *date);
/*----------------------------------------------------------------------------*/
/**@brief    蓝牙电话本获取回调函数
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void phonebook_packet_handler(u8 type, const u8 *name, const u8 *number, const u8 *date)
{
    static u16 number_cnt = 0;
    if (ui_phonebook_packet_handler && ui_phonebook_packet_handler(type, name, number, date)) {
        return;
    }

    log_debug("NO.%d:", number_cnt);
    number_cnt++;
    log_debug("type:%d ", type);
    if (type == 0xff) {
        number_cnt = 0;
    }
    if (name) {
        log_debug(" NAME:%s  ", name);
    }
    if (number) {
        log_debug("number:%s  ", number);
    }
    if (date) {
        log_debug("date:%s ", date);
    }
    /* putchar('\n'); */
    /* void phonebook_save_to_flash(u8 type, const u8 *name, const u8 *number, const u8 *date); */
    /* phonebook_save_to_flash(type, name, number, date); */
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙模式led状态更新
   @param
   @return   status : 蓝牙状态
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_set_led_status(u8 status)
{
    static u8 bt_status = STATUS_BT_INIT_OK;

    u8 app = app_get_curr_task();
    if (status) {
        bt_status = status;
    }
    if (app == APP_BT_TASK) { //蓝牙模式或者state_machine
        pwm_led_mode_set(PWM_LED_ALL_OFF);
        ui_update_status(bt_status);
    }
}


/*************************************************************
                开关可发现可连接的函数接口
**************************************************************/
/*----------------------------------------------------------------------------*/
/**@brief    蓝牙可发现可连接使能
   @param    enable 1:开启   0：关闭
   @return
   @note     函数根据状态开启，开启tws后该函数不起作用
   			 1拖2的时候会限制开启
*/
/*----------------------------------------------------------------------------*/
void bt_wait_phone_connect_control(u8 enable)
{
#if TCFG_USER_TWS_ENABLE
    return;
#endif

    if (enable && app_var.goto_poweroff_flag && (__this->exiting)) {
        return;
    }

    if (enable) {
        log_debug("is_1t2_connection:%d \t total_conn_dev:%d\n", is_1t2_connection(), get_total_connect_dev());
        if (is_1t2_connection()) {
            /*达到最大连接数，可发现(0)可连接(0)*/
            user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
            user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
        } else {
            if (get_total_connect_dev() == 1) {
                /*支持连接2台，只连接一台的情况下，可发现(0)可连接(1)*/
                user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
                user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
            } else {
                /*可发现(1)可连接(1)*/
                BT_STATE_SET_PAGE_SCAN_ENABLE();
                user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
                user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
            }
        }
    } else {
        user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
        user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
    }
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙可发现可连接\回链轮询使能
   @param    p 1:开启轮询   0：不开启轮询,只开启可发现可连接
   @return
   @note     auto_connection_counter:回链设备的总时间
*/
/*----------------------------------------------------------------------------*/
int bt_wait_connect_and_phone_connect_switch(void *p)
{
    int ret = 0;
    int timeout = 0;
    s32 wait_timeout;

    if (__this->exiting) {
        return 0;
    }

    if (bt_user_priv_var.auto_connection_timer) {
        sys_timeout_del(bt_user_priv_var.auto_connection_timer);
        bt_user_priv_var.auto_connection_timer = 0;
    }
    log_debug("connect_switch: %d, %d\n", (int)p, bt_user_priv_var.auto_connection_counter);

    if (bt_user_priv_var.auto_connection_counter <= 0) {
        bt_user_priv_var.auto_connection_timer = 0;
        bt_user_priv_var.auto_connection_counter = 0;


        BT_STATE_CANCEL_PAGE_SCAN();

        user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
        //只回连一个设备
        if (0) {//(get_current_poweron_memory_search_index(NULL)) {
            bt_init_ok_search_index();
            return bt_wait_connect_and_phone_connect_switch(0);
        } else {
            //超时断开回连结束后，经低功耗晶振设回默认值
            extern const struct low_power_param power_param;
            extern void low_power_reset_osc_type(u8 type);
            low_power_reset_osc_type(power_param.osc_type);
            bt_wait_phone_connect_control(1);
            return 0;
        }
    }
    /* log_info(">>>phone_connect_switch=%d\n",bt_user_priv_var.auto_connection_counter ); */
    if ((int)p == 0) {  //// 根据地址回链
        if (bt_user_priv_var.auto_connection_counter) {
            timeout = 6000;     ////设置回链6s
            bt_wait_phone_connect_control(0);
            user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, bt_user_priv_var.auto_connection_addr);
            ret = 1;
        }
    } else {
        timeout = 2000;   ////设置开始被发现被连接2s
        user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
        bt_wait_phone_connect_control(1);
    }
    if (bt_user_priv_var.auto_connection_counter) {
        bt_user_priv_var.auto_connection_counter -= timeout ;
        /* log_info("do=%d\n", bt_user_priv_var.auto_connection_counter); */
    }
    bt_user_priv_var.auto_connection_timer = sys_timeout_add((void *)(!(int)p),
            bt_wait_connect_and_phone_connect_switch, timeout);

    return ret;
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙关闭可发现可连接
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_close_page_scan(void *p)
{
    log_info(">>>%s\n", __func__);
    bt_wait_phone_connect_control(0);
    sys_timer_del(app_var.auto_stop_page_scan_timer);
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙通话时候设置不让系统进入idle状态,不让系统进powerdown
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
static u8 check_phone_income_idle(void)
{
    if (bt_user_priv_var.phone_ring_flag) {
        return 0;
    }
    return 1;
}
REGISTER_LP_TARGET(phone_incom_lp_target) = {
    .name       = "phone_check",
    .is_idle    = check_phone_income_idle,
};


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙连接配置，提供app层用户可以输入配对鉴定key
   @param    key :配对需要输入的数字
   @return
   @note     配对需要输入6位数字的时候，按照顺序从左到右一个个输入
*/
/*----------------------------------------------------------------------------*/
void bt_send_keypress(u8 key)
{
    user_send_cmd_prepare(USER_CTRL_KEYPRESS, 1, &key);
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙连接配置，提供app层用户可以输入确定或者否定
   @param    en 0:否定   1:确定
   @return
   @note     在连接过程中类似手机弹出 确定和否定 按键，可以供用户界面设置
*/
/*----------------------------------------------------------------------------*/
void bt_send_pair(u8 en)
{
    user_send_cmd_prepare(USER_CTRL_PAIR, 1, &en);
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙获取vm连接记录信息
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_init_ok_search_index(void)
{
    if (!bt_user_priv_var.auto_connection_counter && get_current_poweron_memory_search_index(bt_user_priv_var.auto_connection_addr)) {
        /* log_info("bt_wait_connect_and_phone_connect_switch\n"); */
        clear_current_poweron_memory_search_index(1);
        bt_user_priv_var.auto_connection_counter = POWERON_AUTO_CONN_TIME * 1000; //8000ms
        BT_STATE_GET_CONNECT_MAC_ADDR();
    }
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙获取样机当前电量
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
int bt_get_battery_value()
{
    //取消默认蓝牙定时发送电量给手机，需要更新电量给手机使用USER_CTRL_HFP_CMD_UPDATE_BATTARY命令
    /*电量协议的是0-9个等级，请比例换算*/
    return get_cur_battery_level();
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙spp 协议数据 回调
   @param    packet_type:数据类型
  			 ch         :
			 packet     :数据缓存
			size        ：数据长度
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void spp_data_handler(u8 packet_type, u16 ch, u8 *packet, u16 size)
{
    switch (packet_type) {
    case 1:
        log_debug("spp connect\n");
        break;
    case 2:
        log_debug("spp disconnect\n");
        break;
    case 7:
        //log_info("spp_rx:");
        //put_buf(packet,size);
#if AEC_DEBUG_ONLINE
        aec_debug_online(packet, size);
#endif
        break;
    }
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙音乐同步,设置音量
   @param    volume : 设置音量
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_set_music_device_volume(int volume)
{
#if (SMART_BOX_EN)
    extern bool smartbox_set_device_volume(int volume);
    if (smartbox_set_device_volume(volume)) {
        return;
    }
#endif

    if (true == app_check_curr_task(APP_BT_TASK)) {
        set_music_device_volume(volume);
    }
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙通话音量同步,设置音量
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void phone_sync_vol(void *priv)
{
    log_debug("phone_sync_vol\n");
    bt_user_priv_var.phone_vol = 14;
    user_send_cmd_prepare(USER_CTRL_HFP_CALL_SET_VOLUME, 1, &bt_user_priv_var.phone_vol);
    user_send_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_UP, 0, NULL);
    bt_user_priv_var.phone_vol = 15;
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙获取在连接设备名字回调
   @param    status : 1：获取失败   0：获取成功
			 addr   : 配对设备地址
			 name   :配对设备名字
   @return
   @note     需要连接上设备后发起USER_CTRL_READ_REMOTE_NAME
   			 命令来
*/
/*----------------------------------------------------------------------------*/
void bt_read_remote_name(u8 status, u8 *addr, u8 *name)
{
    if (status) {
        log_debug("remote_name fail \n");
    } else {
        log_debug("remote_name : %s \n", name);
    }

    log_debug_hexdump(addr, 6);

    sprintf(bt_remote_name, "%s", name);

#if TCFG_USER_EMITTER_ENABLE
    emitter_search_noname(status, addr, name);
#endif
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙歌词信息获取回调
   @param
   @return
   @note
   const u8 more_avctp_cmd_support = 1;置上1
   需要在void bredr_handle_register()注册回调函数
   要动态获取播放时间的，可以发送USER_CTRL_AVCTP_OPID_GET_PLAY_TIME命令就可以了
   要半秒或者1秒获取就做个定时发这个命令
*/
/*----------------------------------------------------------------------------*/
void user_get_bt_music_info(u8 type, u32 time, u8 *info, u16 len)
{
    //profile define type: 1-title 2-artist name 3-album names 4-track number 5-total number of tracks 6-genre  7-playing time
    //JL define 0x10-total time , 0x11 current play position
    u8  min, sec;
    //printf("type %d\n", type );
    if ((info != NULL) && (len != 0)) {
        log_debug(" %s \n", info);
    }
    if (time != 0) {
        min = time / 1000 / 60;
        sec = time / 1000 - (min * 60);
        log_debug(" time %d %d\n ", min, sec);
    }
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙通话开始丢包数
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
#if ESCO_DUMP_PACKET_ADJUST
u8 get_esco_packet_dump(void)
{
    //log_info("esco_dump_packet:%d\n", esco_dump_packet);
    return __this->esco_dump_packet;
}
#endif






/*************************************************************
               蓝牙丢高级音频数据
**************************************************************/
static u32 bt_timer = 0;
/*----------------------------------------------------------------------------*/
/**@brief    蓝牙丢音频数据包
   @param
   @return
   @note     如果在播放提示音等打断高级音频解码的话，导致蓝牙底层数据满了，
  			 太久没有接收手机数据会导致手机断开链接
*/
/*----------------------------------------------------------------------------*/
static void bt_a2dp_drop_frame(void *p)
{
    int len;
    u8 *frame;
    /* putchar('@'); */
    __a2dp_drop_frame(NULL);

#if TCFG_DEC2TWS_ENABLE
    if (tone_get_status() || localtws_dec_is_open()) {
#else
    if (tone_get_status()) {
#endif
        bt_timer = sys_timeout_add(NULL, bt_a2dp_drop_frame, 100);
    } else {
        local_irq_disable();
        bt_timer = 0;
        local_irq_enable();
    }
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙启动音频数据包
   @param
   @return
   @note     如果在播放提示音等打断高级音频解码的话，导致蓝牙底层数据满了，
  			 太久没有接收手机数据会导致手机断开链接
*/
/*----------------------------------------------------------------------------*/
void bt_drop_a2dp_frame_start(void)
{
    log_debug("bt_drop_frame_start %d\n", bt_timer);
    local_irq_disable();
    if (bt_timer == 0) {
        bt_timer = sys_timeout_add(NULL, bt_a2dp_drop_frame, 100);
    }
    local_irq_enable();

}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙停止音频数据包
   @param
   @return
   @note     如果在播放提示音等打断高级音频解码的话，导致蓝牙底层数据满了，
  			 太久没有接收手机数据会导致手机断开链接
*/
/*----------------------------------------------------------------------------*/
void bt_drop_a2dp_frame_stop()
{
    log_debug("bt_drop_frame_stop %d\n", bt_timer);
    local_irq_disable();
    if (bt_timer) {
        sys_timeout_del(bt_timer);
        bt_timer = 0;
    }
    local_irq_enable();
}





/*************************************************************
  	     蓝牙模式app层检测空闲是否可以进入sniff模式
**************************************************************/
/*----------------------------------------------------------------------------*/
/**@brief    蓝牙退出sniff模式
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_check_exit_sniff()
{
    if (__this->exit_sniff_timer) {
        sys_timeout_del(__this->exit_sniff_timer);
        __this->exit_sniff_timer = 0;
    }

#if TCFG_USER_TWS_ENABLE
    if (tws_api_get_role() == TWS_ROLE_SLAVE) {
        return;
    }
#endif
    user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
}

/*----------------------------------------------------------------------------*/
/**@brief    提供给duer退出sniff的接口
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
#if TCFG_HIMALAYA_ENABLE
static volatile signed char is_continuous_net_trans = 0;
extern u8 __set_lmp_sniff_rejust_establish(u8 start);
void set_continuous_trans(signed char flag)
{    __set_lmp_sniff_rejust_establish(flag);    
    is_continuous_net_trans = flag;
}
#endif

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙检测是否空闲，空闲就发起sniff
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_check_enter_sniff()
{
    struct sniff_ctrl_config_t sniff_ctrl_config;
    u8 addr[12];
    u8 conn_cnt = 0;
    u8 i = 0;
    /* putchar('H'); */



#if (TCFG_PAY_ALIOS_ENABLE && (TCFG_PAY_ALIOS_WAY_SEL==TCFG_PAY_ALIOS_WAY_T_HEAD))
    //乘车码任务活动期间不能进sniff
#if TCFG_PAY_TRANSITCODE_ENABLE
    extern u8 transitcode_task_idle_query(void);
    if (!transitcode_task_idle_query()) {
        return;
    }
#endif
#endif
#if TCFG_HIMALAYA
    if (is_continuous_net_trans) 
    {   
            return;    
    }
#endif

#ifdef CONFIG_APP_BT_ENABLE
#if(SMART_BOX_EN)
    extern u8 file_trans_idle_query(void);
    if (!file_trans_idle_query()) {
        return;
    }
#endif
#endif

    conn_cnt = bt_api_enter_sniff_status_check(SNIFF_CNT_TIME, addr);

    ASSERT(conn_cnt <= 2);

    for (i = 0; i < conn_cnt; i++) {
        log_debug("-----USER SEND SNIFF IN %d %d\n", i, conn_cnt);
        sniff_ctrl_config.sniff_max_interval = SNIFF_MAX_INTERVALSLOT;
        sniff_ctrl_config.sniff_mix_interval = SNIFF_MIN_INTERVALSLOT;
        sniff_ctrl_config.sniff_attemp = SNIFF_ATTEMPT_SLOT;
        sniff_ctrl_config.sniff_timeout  = SNIFF_TIMEOUT_SLOT;
        memcpy(sniff_ctrl_config.sniff_addr, addr + i * 6, 6);
#if TCFG_USER_TWS_ENABLE
        if (tws_api_get_role() == TWS_ROLE_SLAVE) {
            return;
        }
#endif
        extern u8 get_role_type_by_addr(u8 * addr);
        if (get_role_type_by_addr(sniff_ctrl_config.sniff_addr)) {
            user_emitter_cmd_prepare(USER_CTRL_SNIFF_IN, sizeof(struct sniff_ctrl_config_t), (u8 *)&sniff_ctrl_config);
        } else {
            user_send_cmd_prepare(USER_CTRL_SNIFF_IN, sizeof(struct sniff_ctrl_config_t), (u8 *)&sniff_ctrl_config);
        }
    }
}

/*----------------------------------------------------------------------------*/
/**@brief    蓝牙启动 检测空闲 发起sniff
   @param   enable : 1 启动  0:关闭
   			addr:要和对应设备进入sniff 状态的地址
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void sys_auto_sniff_controle(u8 enable, u8 *addr)
{
#if (TCFG_BT_SNIFF_ENABLE == 0)
    return;
#endif

    if (addr) {
        if (bt_api_conn_mode_check(enable, addr) == 0) {
            log_debug("sniff ctr not change\n");
            return;
        }
    }

    if (enable) {
        if (get_total_connect_dev() == 0) {
            return;
        }

        if (addr) {
            log_debug("sniff cmd timer init\n");
            user_cmd_timer_init();
        }

        if (bt_user_priv_var.sniff_timer == 0) {
            log_debug("check_sniff_enable\n");
            bt_user_priv_var.sniff_timer = sys_timer_add(NULL, bt_check_enter_sniff, 1000);
        }
    } else {
        if (addr) {
            log_debug("sniff cmd timer remove\n");
            remove_user_cmd_timer();
        }

        if (bt_user_priv_var.sniff_timer) {
            log_info("check_sniff_disable\n");
            sys_timer_del(bt_user_priv_var.sniff_timer);
            bt_user_priv_var.sniff_timer = 0;

            if (__this->exit_sniff_timer == 0) {
                /* exit_sniff_timer = sys_timer_add(NULL, bt_check_exit_sniff, 5000); */
            }
        }
    }
}

void soft_poweroff_mode(u8 mode)
{
    __this->force_poweroff = mode;
}

/*************************************************************
  蓝牙模式关机处理
 **************************************************************/
/*----------------------------------------------------------------------------*/
/**@brief    软关机蓝牙模式处理
   @param
   @return
   @note     断开蓝牙链接\关闭所有状态
*/
/*----------------------------------------------------------------------------*/
void sys_enter_soft_poweroff(void *priv)
{
    int detach_phone = 1;
    struct sys_event clear_key_event = {.type =  SYS_KEY_EVENT, .arg = "key"};

    log_info("%s", __func__);

    bt_user_priv_var.emitter_or_receiver = 0;
    if (app_var.goto_poweroff_flag) {
        return;
    }

#if TCFG_BLUETOOTH_BACK_MODE
    if (__this->exit_flag == 1 && __this->init_ok == 1) {
        __this->cmd_flag = 1;
        app_task_switch_to(APP_BT_TASK);
    }
#endif

    ui_update_status(STATUS_POWEROFF);

    app_var.goto_poweroff_flag = 1;
    app_var.goto_poweroff_cnt = 0;


#if 0
    sys_key_event_disable();
    sys_event_clear(&clear_key_event);
    sys_auto_shut_down_disable();
    sys_auto_sniff_controle(0, NULL);

    BT_STATE_ENTER_SOFT_POWEROFF();


#if TCFG_CHARGESTORE_ENABLE
    if (chargestore_get_earphone_online() != 2)
#else
    if (1)
#endif
    {
#if TCFG_USER_TWS_ENABLE
        detach_phone = bt_tws_poweroff();
#endif
    }

    /* log_debug("detach_phone = %d\n", detach_phone); */

    if (detach_phone) {
        user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
    }
#endif

    if (app_var.wait_exit_timer == 0) {
        app_var.wait_exit_timer = sys_timer_add(priv, wait_exit_btstack_flag, 50);
    }
}

/*----------------------------------------------------------------------------*/
/**@brief   自动关机开关
   @param
   @return
   @note    开启后，如果一段时间内没有连接等操作就会进入关机
*/
/*----------------------------------------------------------------------------*/
void sys_auto_shut_down_enable(void)
{

#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_TRANS_DATA)
    extern u16 bt_ble_is_connected(void);
    if (bt_ble_is_connected()) {
        return;
    }
#endif


#if TCFG_AUTO_SHUT_DOWN_TIME
    log_debug("sys_auto_shut_down_enable\n");

    if (app_var.auto_shut_down_timer == 0) {

        u8 app = app_get_curr_task();
        if (app == APP_BT_TASK) {
            app_var.auto_shut_down_timer = sys_timeout_add(NULL, sys_enter_soft_poweroff, (app_var.auto_off_time * 1000));
        } else {
            /* log_debug("cur_app:%s, return", app->name); */
        }
    } else {//在切换到蓝牙任务APP_STA_START中，current_app为空
        sys_auto_shut_down_disable();
        app_var.auto_shut_down_timer = sys_timeout_add(NULL, sys_enter_soft_poweroff, (app_var.auto_off_time * 1000));
    }
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief   关闭自动关机
   @param
   @return
   @note    链接上设备后会调用关闭
*/
/*----------------------------------------------------------------------------*/
void sys_auto_shut_down_disable(void)
{
#if TCFG_AUTO_SHUT_DOWN_TIME
    log_debug("sys_auto_shut_down_disable\n");
    if (app_var.auto_shut_down_timer) {
        sys_timeout_del(app_var.auto_shut_down_timer);
        app_var.auto_shut_down_timer = 0;
    }
#endif
}


/*************************************************************
                蓝牙模式提示音播放
**************************************************************/
static const u32 num0_9[] = {
    (u32)TONE_NUM_0,
    (u32)TONE_NUM_1,
    (u32)TONE_NUM_2,
    (u32)TONE_NUM_3,
    (u32)TONE_NUM_4,
    (u32)TONE_NUM_5,
    (u32)TONE_NUM_6,
    (u32)TONE_NUM_7,
    (u32)TONE_NUM_8,
    (u32)TONE_NUM_9,
} ;



static void number_to_play_list(char *num, u32 *lst)
{
    u8 i = 0;

    if (num) {
        for (; i < strlen(num); i++) {
            lst[i] = num0_9[num[i] - '0'] ;
        }
    }
    lst[i++] = (u32)TONE_REPEAT_BEGIN(-1);
    lst[i++] = (u32)TONE_RING;
    lst[i++] = (u32)TONE_REPEAT_END();
    lst[i++] = (u32)NULL;
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙来电报号
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void phone_num_play_timer(void *priv)
{
    char *len_lst[34];

    if (get_call_status() == BT_CALL_HANGUP) {
        /* log_debug("hangup,--phone num play return\n"); */
        return;
    }
    log_info("%s\n", __FUNCTION__);

    if (bt_user_priv_var.phone_num_flag) {
        tone_play_stop();
        number_to_play_list((char *)(bt_user_priv_var.income_phone_num), len_lst);
        tone_file_list_play(len_lst, 1);
    } else {
        /*电话号码还没有获取到，定时查询*/
        bt_user_priv_var.phone_timer_id = sys_timeout_add(NULL, phone_num_play_timer, 200);
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙来电报号启动
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
static void phone_num_play_start(void)
{
    /* check if support inband ringtone */
    if (!bt_user_priv_var.inband_ringtone) {
        bt_user_priv_var.phone_num_flag = 0;
        bt_user_priv_var.phone_timer_id = sys_timeout_add(NULL, phone_num_play_timer, 500);
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙来电铃声播放
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
u8 phone_ring_play_start(void)
{
    char *len_lst[34];

    if (get_call_status() == BT_CALL_HANGUP) {
        /* log_debug("hangup,--phone ring play return\n"); */
        return 0;
    }
    log_info("%s\n", __FUNCTION__);
    /* check if support inband ringtone */
    if (!bt_user_priv_var.inband_ringtone) {
        tone_play_stop();
        number_to_play_list(NULL, len_lst);
        tone_file_list_play(len_lst, 1);
        return 1;
    }
    return 0;
}


/*----------------------------------------------------------------------------*/
/**@brief    蓝牙提示音播放统一接口
   @param    index:提示音序号
   			 preemption：是否打断/1:打断、0：不打断
		     priv :
   @return   播放是否成功
   @note
  			蓝牙模式播放提示音接口，防止提示音播放时候打开 a2dp 解码不及时，
  			导致底层 a2dp buff 阻塞，手机超时断开蓝牙.
*/
/*----------------------------------------------------------------------------*/
int bt_tone_play_index(u8 index, u8 preemption, void *priv)
{
    if (!bt_media_is_running()) { // 蓝牙不播歌的时候才清a2dp数据
        bt_drop_a2dp_frame_start();
    }
    return tone_play_with_callback_by_name(tone_table[index], preemption, NULL, priv);
}

__attribute__((weak))
int earphone_a2dp_codec_get_low_latency_mode()
{
    return 0;
}

__attribute__((weak))
void earphone_a2dp_codec_set_low_latency_mode(int enable)
{
    return;
}

int bt_get_low_latency_mode()
{
    return earphone_a2dp_codec_get_low_latency_mode();
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙tws 低电处理
   @param
   @return
   @note    电量高的做主机，电量低的做从机
*/
/*----------------------------------------------------------------------------*/
void bt_set_low_latency_mode(int enable)
{
#if TCFG_USER_TWS_ENABLE
    if (tws_api_get_role() == TWS_ROLE_MASTER) {
        if (tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) {
            if (enable) {
                bt_tws_api_push_cmd(SYNC_CMD_LOW_LATENCY_ENABLE, 300);
            } else {
                bt_tws_api_push_cmd(SYNC_CMD_LOW_LATENCY_DISABLE, 300);
            }
        } else {
            earphone_a2dp_codec_set_low_latency_mode(enable);
        }
    }
#else
    earphone_a2dp_codec_set_low_latency_mode(enable);
#endif
}



/*************************************************************
             蓝牙模式协议栈状态事件处理
**************************************************************/
/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 事件过滤
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
u8 bt_status_event_filter(struct bt_event *bt)
{
    if (app_var.goto_poweroff_flag) {
        if (bt->event != BT_STATUS_A2DP_MEDIA_STOP) {
            return false;
        }
    }

#if SOUNDCARD_ENABLE
    soundcard_bt_connect_status_event(bt->event);
#endif//SOUNDCARD_ENABLE

    UI_MSG_POST("bt_status:event=%4", bt->event);
    return true;
}

void bredr_open_scan()
{
    user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
    user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
}

void  bt_status_init_ok(struct bt_event *bt)
{
#if TCFG_NORMAL_SET_DUT_MODE
    extern void bredr_set_dut_enble(u8 en, u8 phone);
    bredr_set_dut_enble(1, 1);
#endif
    __this->init_ok = 1;

    if (__this->init_ok_time == 0) {
        __this->init_ok_time = timer_get_ms();
        __this->auto_exit_limit_time = POWERON_AUTO_CONN_TIME * 1000;
        /* tone_dec_wait_stop(3000); */
    }
#if TCFG_USER_BLE_ENABLE
    if (BT_MODE_IS(BT_BQB)) {
        ble_bqb_test_thread_init();
    } else {
#if TCFG_NORMAL_SET_DUT_MODE
        extern void ble_standard_dut_test_init(void);
        ble_standard_dut_test_init();
#else
        bt_ble_init();
#endif
    }
#endif
    /* void get_phonebook_test(u8 type); */
    /* get_phonebook_test(0); */

#if TCFG_USER_EMITTER_ENABLE
    ////发射器设置回调等
    void bt_emitter_init() ;
    bt_emitter_init();
    extern u8 emitter_search_result(char *name, u8 name_len, u8 * addr, u32 dev_class, char rssi);
    inquiry_result_handle_register(emitter_search_result);
    extern void emitter_or_receiver_switch(u8 flag);

#ifdef  BT_EMITTER_TEST
    emitter_or_receiver_switch(BT_EMITTER_EN);
#else
    emitter_or_receiver_switch(BT_EMITTER_EN);
#endif
    /* bredr_bulk_change(1); */
    return;
#endif


    bt_init_ok_search_index();
    bt_set_led_status(STATUS_BT_INIT_OK);
#if TCFG_CHARGESTORE_ENABLE || TCFG_TEST_BOX_ENABLE
    chargestore_set_bt_init_ok(1);
#endif


#if ((CONFIG_BT_MODE == BT_BQB)||(CONFIG_BT_MODE == BT_PER))
    bt_wait_phone_connect_control(1);
#else
#if TCFG_USER_TWS_ENABLE
    bt_tws_poweron();
#else
#if !TCFG_USER_BLE_CTRL_BREDR_EN
    bt_wait_connect_and_phone_connect_switch(0);
#endif
#endif
#endif
}

void bt_status_init_ok_background(struct bt_event *bt)
{
    __this->init_ok = 1;

#if TCFG_USER_BLE_ENABLE
    if (BT_MODE_IS(BT_BQB)) {
        ble_bqb_test_thread_init();
    } else {
        bt_ble_init();
    }
#endif

#if TCFG_USER_EMITTER_ENABLE
    ////发射器设置回调等
    void bt_emitter_init() ;
    bt_emitter_init();
    extern u8 emitter_search_result(char *name, u8 name_len, u8 * addr, u32 dev_class, char rssi);
    inquiry_result_handle_register(emitter_search_result);

    bt_user_priv_var.emitter_or_receiver = BT_EMITTER_EN;
    return;
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 设备连接上状态
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_connect(struct bt_event *bt)
{

    sys_auto_sniff_controle(1, NULL);
    sys_auto_shut_down_disable();

#if 0//SMART_BOX_EN
    if (bt->value == 0) {
        memcpy(__this->last_connecting_addr, bt->args, 6);
        extern void smartbox_update_bt_emitter_connect_state(u8 state, u8 * addr);
        smartbox_update_bt_emitter_connect_state(1, __this->last_connecting_addr);
    }
#endif

    static u8 mac_addr[6];
    memcpy(mac_addr, bt->args, 6);
    UI_MSG_POST("bt_connect_info:mac=%4", mac_addr);

#if TCFG_USER_EMITTER_ENABLE
#if TCFG_UI_ENABLE && TCFG_SPI_LCD_ENABLE
    if (bt->value) {
#if (TCFG_LUA_ENABLE)
        emitter_save_remote_name(mac_addr, bt_remote_name);
#else /* #if (TCFG_LUA_ENABLE) */
        extern int page_list_add(u8 * mac, u8 * name); //添加收藏
        page_list_add(mac_addr, bt_remote_name);
#endif /* #if (TCFG_LUA_ENABLE) */
    }
#endif
#endif

#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
    {
        u8 connet_type;
        if (get_auto_connect_state(bt->args)) {
            connet_type = ICON_TYPE_RECONNECT;
        } else {
            connet_type = ICON_TYPE_CONNECTED;
        }

#if TCFG_USER_TWS_ENABLE
        if (tws_api_get_role() == TWS_ROLE_MASTER) {
            bt_ble_icon_open(connet_type);
        } else {
            //maybe slave already open
            bt_ble_icon_close(0);
        }

#else
        bt_ble_icon_open(connet_type);
#endif
    }
#endif


#if (TCFG_BD_NUM == 2)
    if ((get_total_connect_dev() == 1) && bt->value) {   //当前有一台连接上了,并且连接的是sink设备
        user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
        user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
    }
    /* if (get_current_poweron_memory_search_index(NULL) == 0) { */
    /*     bt_wait_phone_connect_control(1); */
    /* } */
#endif

#if TCFG_USER_TWS_ENABLE
    if (!get_bt_tws_connect_status()) {   //如果对耳还未连接就连上手机，要切换闪灯状态
        bt_set_led_status(STATUS_BT_CONN);
    }

    if (bt_tws_phone_connected()) {
        return ;
    }
#else
    bt_set_led_status(STATUS_BT_CONN);    //单台在此处设置连接状态,对耳的连接状态需要同步，在bt_tws.c中去设置
#if (TCFG_AUTO_STOP_PAGE_SCAN_TIME && TCFG_BD_NUM == 2)
    if ((get_total_connect_dev() == 1) && bt->value) {   //当前有一台连接上了,并且连接的是sink设备
        if (app_var.auto_stop_page_scan_timer == 0) {
            app_var.auto_stop_page_scan_timer = sys_timeout_add(NULL, bt_close_page_scan, (TCFG_AUTO_STOP_PAGE_SCAN_TIME * 1000)); //2
        }
    } else {
        if (app_var.auto_stop_page_scan_timer) {
            sys_timeout_del(app_var.auto_stop_page_scan_timer);
            app_var.auto_stop_page_scan_timer = 0;
        }
    }
#endif   //endif AUTO_STOP_PAGE_SCAN_TIME
#endif
    /* log_debug("tone status:%d\n", tone_get_status()); */
    if (get_call_status() == BT_CALL_HANGUP) {
        bt_tone_play_index(IDEX_TONE_BT_CONN, 1, NULL);
    }
}

void bt_status_connect_background(struct bt_event *bt)
{
    sys_auto_sniff_controle(1, NULL);
    sys_auto_shut_down_disable();

#if SMART_BOX_EN
    memcpy(__this->last_connecting_addr, bt->args, 6);
    extern void smartbox_update_bt_emitter_connect_state(u8 state, u8 * addr);
    smartbox_update_bt_emitter_connect_state(1, __this->last_connecting_addr);
#endif

    static u8 mac_addr[6];
    memcpy(mac_addr, bt->args, 6);
    UI_MSG_POST("bt_connect_info:mac=%4", mac_addr);

#if TCFG_USER_EMITTER_ENABLE
#if TCFG_UI_ENABLE && TCFG_SPI_LCD_ENABLE
    if (bt->value) {
#if (TCFG_LUA_ENABLE)
        emitter_save_remote_name(mac_addr, bt_remote_name);
#else /* #if (TCFG_LUA_ENABLE) */
        extern int page_list_add(u8 * mac, u8 * name); //添加收藏
        page_list_add(mac_addr, bt_remote_name);
#endif /* #if (TCFG_LUA_ENABLE) */
    }
#endif
#endif

#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
    {
        u8 connet_type;
        if (get_auto_connect_state(bt->args)) {
            connet_type = ICON_TYPE_RECONNECT;
        } else {
            connet_type = ICON_TYPE_CONNECTED;
        }

#if TCFG_USER_TWS_ENABLE
        if (tws_api_get_role() == TWS_ROLE_MASTER) {
            bt_ble_icon_open(connet_type);
        } else {
            //maybe slave already open
            bt_ble_icon_close(0);
        }

#else
        bt_ble_icon_open(connet_type);
#endif
    }
#endif


#if (TCFG_BD_NUM == 2)
    if ((get_total_connect_dev() == 1) && bt->value) {   //当前有一台连接上了,并且连接的是sink设备
        user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
        user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
    }
    /* if (get_current_poweron_memory_search_index(NULL) == 0) { */
    /*     bt_wait_phone_connect_control(1); */
    /* } */
#endif

#if TCFG_USER_TWS_ENABLE
    if (!get_bt_tws_connect_status()) {   //如果对耳还未连接就连上手机，要切换闪灯状态
        bt_set_led_status(STATUS_BT_CONN);
    }

    if (bt_tws_phone_connected()) {
        return ;
    }
#else
    bt_set_led_status(STATUS_BT_CONN);    //单台在此处设置连接状态,对耳的连接状态需要同步，在bt_tws.c中去设置
#if (TCFG_AUTO_STOP_PAGE_SCAN_TIME && TCFG_BD_NUM == 2)
    if ((get_total_connect_dev() == 1) && bt->value) {   //当前有一台连接上了,并且连接的是sink设备
        if (app_var.auto_stop_page_scan_timer == 0) {
            app_var.auto_stop_page_scan_timer = sys_timeout_add(NULL, bt_close_page_scan, (TCFG_AUTO_STOP_PAGE_SCAN_TIME * 1000)); //2
        }
    } else {
        if (app_var.auto_stop_page_scan_timer) {
            sys_timeout_del(app_var.auto_stop_page_scan_timer);
            app_var.auto_stop_page_scan_timer = 0;
        }
    }
#endif   //endif AUTO_STOP_PAGE_SCAN_TIME
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 设备断开连接
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_disconnect(struct bt_event *bt)
{

    sys_auto_sniff_controle(0, NULL);
    __this->call_flag = 0;
    /* log_info("BT_STATUS_DISCONNECT\n"); */
#if (SMART_BOX_EN)
    smartbox_update_bt_emitter_connect_state(0, __this->last_connecting_addr);
#endif
    /* UI_MSG_POST("bt_status:n=%4", 0); */
#if AUDIO_OUTPUT_INCLUDE_BT
    bt_emitter_stu_set(NULL, 0);
#endif

    bt_set_led_status(STATUS_BT_DISCONN);
#if(TCFG_BD_NUM == 2)               //对耳在bt_tws同步播放提示音
    if (!app_var.goto_poweroff_flag) { /*关机不播断开提示音*/
        if (!__this->ignore_discon_tone) {
            tone_play_by_path(tone_table[IDEX_TONE_BT_DISCONN], 1);
        }
    }
#else
#if TCFG_USER_TWS_ENABLE
    if (!get_bt_tws_connect_status())
#endif
    {
        if (!app_var.goto_poweroff_flag) { /*关机不播断开提示音*/
            if (!__this->ignore_discon_tone) {
                bt_tone_play_index(IDEX_TONE_BT_DISCONN, 1, NULL);
            }
        }
    }
#endif

#if TCFG_USER_TWS_ENABLE
    STATUS *p_led = get_led_config();
    if (get_bt_tws_connect_status()) {
#if TCFG_CHARGESTORE_ENABLE
        chargestore_set_phone_disconnect();
#endif
        if (tws_api_get_role() == TWS_ROLE_MASTER) {
            bt_tws_api_push_cmd(SYNC_CMD_LED_PHONE_DISCONN_STATUS, 400);
        }
    } else {
        //断开手机时，如果对耳未连接，要把LED时钟切到RC（因为单台会进SNIFF）
        if (!app_var.goto_poweroff_flag) { /*关机时不改UI*/
            pwm_led_clk_set(PWM_LED_CLK_RC32K);
            bt_set_led_status(STATUS_BT_DISCONN);
        }
    }
    __this->tws_local_back_role = 0;
#else
    if (get_total_connect_dev() == 0) {    //已经没有设备连接
        if (!app_var.goto_poweroff_flag) { /*关机时不改UI*/
            bt_set_led_status(STATUS_BT_DISCONN);
        }
        sys_auto_shut_down_enable();
    }
#endif
    g_printf("bt->value:%d", bt->value);
#if AUDIO_OUTPUT_INCLUDE_BT
    if (bt->value) {
        bt_emitter_audio_set_mute(0);
    }
#endif /* #if AUDIO_OUTPUT_INCLUDE_BT */

    extern void bt_close_bredr_timeout_start();
    bt_close_bredr_timeout_start();
}

void bt_status_disconnect_background(struct bt_event *bt)
{
    sys_auto_sniff_controle(0, NULL);
    __this->call_flag = 0;
    /* log_info("BT_STATUS_DISCONNECT\n"); */
#if AUDIO_OUTPUT_INCLUDE_BT
    if (bt->value) {
        emitter_close(1);
        bt_emitter_audio_set_mute(0);
    }
#endif

#if TCFG_USER_TWS_ENABLE
    if (tws_api_get_role() == TWS_ROLE_MASTER) {
        bt_tws_api_push_cmd(SYNC_CMD_LED_PHONE_DISCONN_STATUS, 400);
    }
}
__this->tws_local_back_role = 0;
#endif
}

#if TCFG_SMART_VOICE_ENABLE
#if TCFG_CALL_KWS_SWITCH_ENABLE || TCFG_CALL_IFLYTEK_SWITCH_ENABLE
extern int audio_smart_voice_phone_call_start(void);
extern int audio_smart_voice_phone_call_close(void);
extern void audio_smart_voice_detect_close(void);
extern int esco_ul_stream_switch(u8 en);
extern u8 bt_phone_dec_is_running();
extern void audio_aec_reboot(u8 reduce);

/*----------------------------------------------------------------------------*/
/**@brief       蓝牙通话事件离线语音识别相关处理
   @param       event - 通话事件（INCOME, ACTIVE, HANGUP）
   @return      无
   @note
*/
/*----------------------------------------------------------------------------*/
static void jl_call_audio_smart_voice_handler(int event)
{
    if (event == BT_STATUS_PHONE_INCOME) {
        extern void a2dp_media_suspend_resume(u8 flag);
        a2dp_media_suspend_resume(1);
        a2dp_dec_close();
        audio_aec_reboot(1);
        //esco_ul_stream_switch(0);
        audio_smart_voice_phone_call_start();
    } else if (event == BT_STATUS_PHONE_ACTIVE) {
        audio_smart_voice_phone_call_close();
        audio_aec_reboot(0);
        //esco_ul_stream_switch(1);
    } else if (event == BT_STATUS_PHONE_HANGUP) {
        if (!bt_phone_dec_is_running()) {
            audio_smart_voice_phone_call_close();
        }
    }
}
#endif
#endif

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机来电
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_phone_income(struct bt_event *bt)
{
    __this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
    ui_update_status(STATUS_PHONE_INCOME);
    u8 tmp_bd_addr[6];
    memcpy(tmp_bd_addr, bt->args, 6);
    if (bt_switch_back_timer) {
        sys_timeout_del(bt_switch_back_timer);
        bt_switch_back_timer = 0;
    }
#if TCFG_SMART_VOICE_ENABLE
#if TCFG_CALL_KWS_SWITCH_ENABLE || TCFG_CALL_IFLYTEK_SWITCH_ENABLE
    jl_call_audio_smart_voice_handler(BT_STATUS_PHONE_INCOME);
#endif
#endif
    /*
     *(1)1t2有一台通话的时候，另一台如果来电不要提示
     *(2)1t2两台同时来电，现来的题示，后来的不播
     */
    if ((check_esco_state_via_addr(tmp_bd_addr) != BD_ESCO_BUSY_OTHER) && (bt_user_priv_var.phone_ring_flag == 0)) {
#if BT_INBAND_RINGTONE
        extern u8 get_device_inband_ringtone_flag(void);
        bt_user_priv_var.inband_ringtone = get_device_inband_ringtone_flag();
#else
        bt_user_priv_var.inband_ringtone = 0 ;
        lmp_private_esco_suspend_resume(3);
#endif

        bt_user_priv_var.phone_ring_flag = 1;
        bt_user_priv_var.phone_income_flag = 1;

#if TCFG_USER_TWS_ENABLE
#if BT_SYNC_PHONE_RING
        if (!bt_tws_sync_phone_num(NULL))
#else
        if (tws_api_get_role() == TWS_ROLE_MASTER)
#endif
#endif
        {
#if BT_PHONE_NUMBER
            phone_num_play_start();
#else
            phone_ring_play_start();
#endif

        }
        user_send_cmd_prepare(USER_CTRL_HFP_CALL_CURRENT, 0, NULL); //发命令获取电话号码
    } else {
        /* log_debug("SCO busy now:%d,%d\n", check_esco_state_via_addr(tmp_bd_addr), bt_user_priv_var.phone_ring_flag); */
    }
}


/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机打出电话
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_phone_out(struct bt_event *bt)
{
    if (bt_switch_back_timer) {
        sys_timeout_del(bt_switch_back_timer);
        bt_switch_back_timer = 0;
    }
    lmp_private_esco_suspend_resume(4);
    __this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
    ui_update_status(STATUS_PHONE_OUT);
    bt_user_priv_var.phone_income_flag = 0;
    user_send_cmd_prepare(USER_CTRL_HFP_CALL_CURRENT, 0, NULL); //发命令获取电话号码
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机接通电话
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_phone_active(struct bt_event *bt)
{
    bt_phone_active_start_time = timer_get_ms();
    ui_update_status(STATUS_PHONE_ACTIV);
#if TCFG_SMART_VOICE_ENABLE
#if TCFG_CALL_KWS_SWITCH_ENABLE || TCFG_CALL_IFLYTEK_SWITCH_ENABLE
    jl_call_audio_smart_voice_handler(BT_STATUS_PHONE_ACTIVE);
#endif
#endif
    if (bt_user_priv_var.phone_call_dec_begin) {
        /* log_debug("call_active,dump_packet clear\n"); */
        __this->esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
    }
    if (bt_user_priv_var.phone_ring_flag) {
        bt_user_priv_var.phone_ring_flag = 0;
        tone_play_stop();
        if (bt_user_priv_var.phone_timer_id) {
            sys_timeout_del(bt_user_priv_var.phone_timer_id);
            bt_user_priv_var.phone_timer_id = 0;
        }
    }
    lmp_private_esco_suspend_resume(4);
    bt_user_priv_var.phone_income_flag = 0;
    bt_user_priv_var.phone_num_flag = 0;
    bt_user_priv_var.phone_con_sync_num_ring = 0;
    bt_user_priv_var.phone_con_sync_ring = 0;
    bt_user_priv_var.phone_vol = 15;
    /* log_debug("phone_active:%d\n", app_var.call_volume); */
#ifdef PHONE_CALL_DEFAULT_MAX_VOL
    bt_user_priv_var.set_call_vol_flag |= BIT(1);
    if ((BIT(1) | BIT(2)) == bt_user_priv_var.set_call_vol_flag) {
        app_audio_set_volume(APP_AUDIO_STATE_CALL, 15, 1);
        sys_timeout_add(NULL, phone_sync_vol, 1200);
    }
#else
    app_audio_set_volume(APP_AUDIO_STATE_CALL, app_var.call_volume, 1);
#endif
}

u32 bt_get_phone_active_start_time_ms(void)
{
    return bt_phone_active_start_time;
}

void bt_set_phone_active_start_time_ms(void)
{
    bt_phone_active_start_time = timer_get_ms();
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机挂断电话
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_phone_hangup(struct bt_event *bt)
{
    __this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
    /* log_info("phone_handup\n"); */
#if TCFG_SMART_VOICE_ENABLE
#if TCFG_CALL_KWS_SWITCH_ENABLE || TCFG_CALL_IFLYTEK_SWITCH_ENABLE
    jl_call_audio_smart_voice_handler(BT_STATUS_PHONE_HANGUP);
#endif
#endif
    if (bt_user_priv_var.phone_ring_flag) {
        bt_user_priv_var.phone_ring_flag = 0;
        tone_play_stop();
        if (bt_user_priv_var.phone_timer_id) {
            sys_timeout_del(bt_user_priv_var.phone_timer_id);
            bt_user_priv_var.phone_timer_id = 0;
        }
    }
    bt_user_priv_var.phone_num_flag = 0;
    bt_user_priv_var.phone_con_sync_num_ring = 0;
    bt_user_priv_var.phone_con_sync_ring = 0;
    __this->call_back_flag &= ~BIT(0);
    if ((__this->call_back_flag == 0) && __this->call_flag) {
        if (bt_switch_back_timer == 0) {
            bt_switch_back_timer = sys_timeout_add(NULL, bt_switch_back, 500);
        }
    }
    if (get_call_status() == BT_CALL_HANGUP) {
        //call handup
        bt_user_priv_var.set_call_vol_flag  = 0;
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机来电号码
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_phone_number(struct bt_event *bt)
{
    u8 *phone_number = NULL;
    phone_number = (u8 *)bt->value;
    //put_buf(phone_number, strlen((const char *)phone_number));
    if (bt_user_priv_var.phone_num_flag == 1) {
        return ;
    }
    bt_user_priv_var.income_phone_len = 0;
    memset(bt_user_priv_var.income_phone_num, '\0', sizeof(bt_user_priv_var.income_phone_num));
    for (int i = 0; i < strlen((const char *)phone_number); i++) {
        if (phone_number[i] >= '0' && phone_number[i] <= '9') {
            //过滤，只有数字才能报号
            bt_user_priv_var.income_phone_num[bt_user_priv_var.income_phone_len++] = phone_number[i];
            if (bt_user_priv_var.income_phone_len >= sizeof(bt_user_priv_var.income_phone_num)) {
                return;    /*buffer 空间不够，后面不要了*/
            }
        }
    }
    if (bt_user_priv_var.income_phone_len > 0) {
        bt_user_priv_var.phone_num_flag = 1;
    } else {
        log_debug("PHONE_NUMBER len err\n");
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机来电电话本名
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
u8 phone_name_text[30];
void bt_status_phone_name(struct bt_event *bt)
{
    u8 *phone_name = NULL;
    u8 phone_name_len = 0;
    phone_name = (u8 *)bt->value;
    phone_name_len = strlen((const char *)phone_name);
    if (phone_name_len > 30) {   //限制显示30个字节,可根据需求增加
        phone_name_len = 30;
    }
    /* put_buf(phone_name, phone_name_len); */
    memset(phone_name_text, '\0', phone_name_len + 1);
    memcpy(phone_name_text, phone_name, phone_name_len);
    /* r_printf(">>%s\n", phone_name); */
    /* r_printf(">>%s\n", phone_name_text); */
    UI_MSG_POST("phone_name:status=%4", 1);
}
/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机来电铃声
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_inband_ringtone(struct bt_event *bt)
{

#if BT_INBAND_RINGTONE
    bt_user_priv_var.inband_ringtone = bt->value;
#else
    bt_user_priv_var.inband_ringtone = 0;
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机高级音频开始播放
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_a2dp_media_start(struct bt_event *bt)
{

    __this->call_flag = 0;
    __this->a2dp_start_flag = 1;
#if (TCFG_DEC2TWS_ENABLE)
    bt_drop_a2dp_frame_stop();
    if (bt_media_is_running()) {
        log_debug("is_a2dp_dec_open break\n");
        return ;
    }
    if (localtws_dec_is_open()) {
        // 先发命令再关闭解码，减少tws两边结束的时间差异
        bt_a2dp_drop_frame(NULL);
        tws_user_sync_box(TWS_BOX_NOTICE_A2DP_BACK_TO_BT_MODE, 0);
        os_time_dly(2);
        localtws_dec_close(1);
    }
#endif
    a2dp_dec_open(bt->value);
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机高级音频停止播放
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_a2dp_media_stop(struct bt_event *bt)
{
    __this->a2dp_start_flag = 0;
    bt_drop_a2dp_frame_stop();
    a2dp_dec_close();

#if (TCFG_DEC2TWS_ENABLE)
    if (is_tws_active_device()) {
        return ;
    }
#endif
#if TCFG_USER_TWS_ENABLE
    if (get_bt_tws_connect_status()) {
    }
#endif
}

/* ***************************************************************************/
/**
 * @brief   ：display_call_dly
 延时显示通话界面，用于通话中切换通话链路的界面变化
 */
/* ***************************************************************************/
void display_call_dly()
{
    if (__this->call_back_flag & BIT(1)) {
        if (get_call_status() == BT_CALL_ACTIVE) {
            UI_WINDOW_PREEMPTION_POSH(ID_WINDOW_PHONE, NULL, NULL, UI_WINDOW_PREEMPTION_TYPE_PHONE);
        }
    } else {
        if (get_call_status() == BT_CALL_ACTIVE) {
            /* if (UI_GET_WINDOW_ID() == ID_WINDOW_PHONE) {//判断手表在来电界面，退出界面 */
            UI_WINDOW_PREEMPTION_POP(ID_WINDOW_PHONE);
            /* } */
        }
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机通话链路切换
   @param
   @return
   @note   手机音频切换、微信等都会有这个状态
*/
/*----------------------------------------------------------------------------*/
void bt_status_sco_change(struct bt_event *bt)
{
    void mem_stats(void);
    mem_stats();
    /* log_info(" BT_STATUS_SCO_STATUS_CHANGE len:%d ,type:%d", (bt->value >> 16), (bt->value & 0x0000ffff)); */
    sys_timeout_add(NULL, display_call_dly, 300);
    if (bt->value != 0xff) {
#ifdef PHONE_CALL_DEFAULT_MAX_VOL
        bt_user_priv_var.set_call_vol_flag |= BIT(2);
        if ((BIT(1) | BIT(2)) == bt_user_priv_var.set_call_vol_flag) {
            /* app_audio_set_volume(APP_AUDIO_STATE_CALL, app_var.aec_dac_gain, 1); */
            app_audio_set_volume(APP_AUDIO_STATE_CALL, 15, 1);
            sys_timeout_add(NULL, phone_sync_vol, 1200);
        }
        /* log_debug("--test printfjjj --%x\n", bt_user_priv_var.set_call_vol_flag); */
#endif
        log_info("<<<<<<<<<<<esco_dec_stat\n");
        __this->call_back_flag |= BIT(1);


#if 0   //debug
        void mic_capless_feedback_toggle(u8 toggle);
        mic_capless_feedback_toggle(0);
#endif

#if PHONE_CALL_USE_LDO15
        if ((get_chip_version() & 0xff) <= 0x04) { //F版芯片以下的，通话需要使用LDO模式
            power_set_mode(PWR_LDO15);
        }
#endif

#if (TCFG_DEC2TWS_ENABLE)
        if (localtws_dec_close(1)) {
            bt_a2dp_drop_frame(NULL);
        }
#endif

#if TCFG_USER_TWS_ENABLE
#if	TCFG_USER_ESCO_SLAVE_MUTE
        if (tws_api_get_role() == TWS_ROLE_SLAVE) {
            esco_dec_open(&bt->value, 1);
        } else
#endif
#endif
        {
            esco_dec_open(&bt->value, 0);
        }
        bt_user_priv_var.phone_call_dec_begin = 1;
        if (get_call_status() == BT_CALL_ACTIVE) {
            log_debug("dec_begin,dump_packet clear\n");
            __this->esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
        }
#if TCFG_USER_TWS_ENABLE
        tws_page_scan_deal_by_esco(1);
#endif
    } else {
        log_info("<<<<<<<<<<<esco_dec_stop\n");

        __this->call_back_flag &= ~BIT(1);
        bt_user_priv_var.set_call_vol_flag &= ~BIT(2);
        bt_user_priv_var.phone_call_dec_begin = 0;
        __this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
        esco_dec_close();
#if TCFG_SMART_VOICE_ENABLE
#if TCFG_CALL_KWS_SWITCH_ENABLE || TCFG_CALL_IFLYTEK_SWITCH_ENABLE
        jl_call_audio_smart_voice_handler(BT_STATUS_PHONE_HANGUP);
#endif
#endif
#if TCFG_USER_TWS_ENABLE
        tws_page_scan_deal_by_esco(0);
#endif
#if PHONE_CALL_USE_LDO15
        if ((get_chip_version() & 0xff) <= 0x04) { //F版芯片以下的，通话需要使用LDO模式
            power_set_mode(TCFG_LOWPOWER_POWER_SEL);
        }
#endif
#if (TCFG_DEC2TWS_ENABLE)
        if (is_tws_active_device()) {
            return ;
        }
#endif
        if ((__this->call_back_flag == 0) && __this->call_flag) {
            if (bt_switch_back_timer == 0) {
                bt_switch_back_timer = sys_timeout_add(NULL, bt_switch_back, 500);
            }
        }
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机通话过程中设置音量产生状态
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_call_vol_change(struct bt_event *bt)
{

    u8 volume = bt->value;  //app_audio_get_max_volume() * bt->value / 15;
    u8 call_status = get_call_status();
    bt_user_priv_var.phone_vol = bt->value;
    if ((call_status == BT_CALL_ACTIVE) || (call_status == BT_CALL_OUTGOING) || app_var.siri_stu) {
        app_audio_set_volume(APP_AUDIO_STATE_CALL, volume, 1);
    } else if (call_status != BT_CALL_HANGUP) {
        /*只保存，不设置到dac*/
        app_var.call_volume = volume;
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status  样机和链接设备进入sniff模式后返回来的状态
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_sniff_state_update(struct bt_event *bt)
{

    if (bt->value == 0) {
#if (TCFG_USER_TWS_ENABLE == 1)
        pwm_led_clk_set(PWM_LED_CLK_BTOSC_24M);
#endif
        sys_auto_sniff_controle(1, bt->args);
    } else {
#if (TCFG_USER_TWS_ENABLE == 1)
        pwm_led_clk_set(PWM_LED_CLK_RC32K);
#endif
        sys_auto_sniff_controle(0, bt->args);
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 最后拨打电话类型
   @param
   @return
   @note    只区分打入和打出
*/
/*----------------------------------------------------------------------------*/
void bt_status_last_call_type_change(struct bt_event *bt)
{
    __this->call_back_flag |= BIT(0);
    bt_user_priv_var.last_call_type = bt->value;
}



/*----------------------------------------------------------------------------*/
/**@brief  设置与获取出声设备
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_set_music_device_style(u8 style)
{
    __this->music_dev = style;
}

u8 bt_get_music_device_style()
{
    return __this->music_dev;
}

static int bt_init_music_device_style(void)
{
#if TCFG_USER_EMITTER_ENABLE
    __this->music_dev = SET_MUSIC_IN_WATCH;
#else
    __this->music_dev = SET_MUSIC_IN_PHONE;
#endif
    return 0;
}
platform_initcall(bt_init_music_device_style);

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 高级音频链接上
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
///watch  蓝牙空闲的时候不发mic数据
void bt_status_conn_a2dp_ch(struct bt_event *bt)
{
#if TCFG_USER_EMITTER_ENABLE
    if (bt_user_priv_var.emitter_or_receiver == BT_EMITTER_EN) {
        extern int music_player_get_play_status(void);
        if (bt_get_music_device_style() != SET_MUSIC_IN_WATCH) {
            return;
        }
        if (bt->value & A2DP_SRC_CH) {
            if (music_player_get_play_status() == FILE_DEC_STATUS_PLAY) {
                emitter_open(1);
            }
        }
    }
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status 手机音频链接上
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_conn_hfp_ch(struct bt_event *bt)
{
    if ((!is_1t2_connection()) && (get_current_poweron_memory_search_index(NULL))) { //回连下一个device
        if (get_esco_coder_busy_flag()) {
            clear_current_poweron_memory_search_index(0);
        } else {
            /* user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL); */
        }
    }
}


/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status   获取手机厂商
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_phone_menufactuer(struct bt_event *bt)
{
    extern const u8 hid_conn_depend_on_dev_company;
    app_var.remote_dev_company = bt->value;
    if (hid_conn_depend_on_dev_company) {
        if (bt->value) {
            //user_send_cmd_prepare(USER_CTRL_HID_CONN, 0, NULL);
        } else {
            user_send_cmd_prepare(USER_CTRL_HID_DISCONNECT, 0, NULL);
        }
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status   语音识别
   @param
   @return
   @note    bt->value 0-siri关闭状态 ，
   				      1-siri开启状态 ，
					  2-手动打开siri成功状态.
                      3-安卓手机上选择语音识别软件状态
*/
/*----------------------------------------------------------------------------*/
void bt_status_voice_recognition(struct bt_event *bt)
{
    __this->esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
    /* put_buf(bt, sizeof(struct bt_event)); */
    app_var.siri_stu = bt->value;
    if (__this->call_flag && ((app_var.siri_stu == 0) || (app_var.siri_stu == 3))) {
        if (bt_switch_back_timer == 0) {
            bt_switch_back_timer = sys_timeout_add(NULL, bt_switch_back, 500);
        }
    }
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙status   接收远端设备发过来的avrcp命令
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_status_avrcp_income_opid(struct bt_event *bt)
{

#define AVC_VOLUME_UP			0x41
#define AVC_VOLUME_DOWN			0x42
    log_debug("BT_STATUS_AVRCP_INCOME_OPID:%d\n", bt->value);
    if (bt->value == AVC_VOLUME_UP) {

    }
    if (bt->value == AVC_VOLUME_DOWN) {

    }
}

/*************************************************************
  			蓝牙模式协议栈事件事件处理
**************************************************************/
/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event     蓝牙协议栈事件过滤
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
extern u32 classic_update_task_exist_flag_get(void);
extern void vm_update_recover(bool update_faild);
u8 bt_hci_event_filter(struct bt_event *bt)
{
    if (bt->event == HCI_EVENT_VENDOR_REMOTE_TEST) {
        if (0 == bt->value) {
            set_remote_test_flag(0);
#if SMART_BOX_EN
            extern void testbox_update_mode_set(u8 mode);
            testbox_update_mode_set(0);
#endif
            /* log_debug("clear_test_box_flag"); */
#if TCFG_TEST_BOX_ENABLE
            if (chargestore_get_testbox_status()) {
                if (get_remote_test_flag()) {
                    chargestore_clear_connect_status();
                }
                //return 0;
            }
#endif
#if TCFG_USER_BLE_ENABLE
            extern u8 ble_update_get_ready_jump_flag(void);
            if (ble_update_get_ready_jump_flag()) {
                log_info("not reset in ready jump\n");
                return 0;
            }
#endif
            if (classic_update_task_exist_flag_get()) {
                vm_update_recover(true);
            }
            log_info("cpu reset\n");
            cpu_reset();
            return 0;
        } else {

#if SMART_BOX_EN
            extern void testbox_update_mode_set(u8 mode);
            testbox_update_mode_set(bt->value);
#endif

#if TCFG_USER_BLE_ENABLE
            /* set_remote_test_flag(1); */
            //1:edr con;2:ble con;
            if (1 == bt->value) {
                extern void bt_ble_adv_enable(u8 enable);
                bt_ble_adv_enable(0);
            } else if (2 == bt->value) {
                extern u8 is_bredr_close(void);
                extern void bt_init_bredr();
                if (is_bredr_close() == 1) {
                    bt_init_bredr();
                }
            }
#endif

#if TCFG_USER_TWS_ENABLE
            bt_tws_poweroff();
#endif
        }
    }

    if (__this->bt_close_bredr) {
        return 0;
    }
    return 1;
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event   搜索结束
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_inquiry(struct bt_event *bt)
{
#if TCFG_USER_EMITTER_ENABLE
    if (bt_user_priv_var.emitter_or_receiver == BT_EMITTER_EN) {
        extern void emitter_search_stop(u8 result);
        emitter_search_stop(bt->value);
    }
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event   链接成功
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_connection(struct bt_event *bt)
{
    /* log_debug("tws_conn_state=%d\n", bt_user_priv_var.tws_conn_state); */

#if TCFG_USER_TWS_ENABLE
    bt_tws_hci_event_connect();
#ifndef CONFIG_NEW_BREDR_ENABLE
    tws_try_connect_disable();
#endif
#else
    if (bt_user_priv_var.auto_connection_timer) {
        sys_timeout_del(bt_user_priv_var.auto_connection_timer);
        bt_user_priv_var.auto_connection_timer = 0;
    }
    bt_user_priv_var.auto_connection_counter = 0;
    /* bt_wait_phone_connect_control(0); */
    user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
    //连上手机后关闭可发现可连接，不影响作为发射器连耳机
    user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
    user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event   链接断开
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_disconnect(struct bt_event *bt)
{
    u8 local_addr[6];
    if (app_var.goto_poweroff_flag || __this->exiting) {
        return;
    }

    if (get_total_connect_dev() == 0) {    //已经没有设备连接
        sys_auto_shut_down_enable();
        sys_auto_sniff_controle(0, NULL);
    }

#if TCFG_TEST_BOX_ENABLE
    if (chargestore_get_testbox_status()) {
        /* log_info("<<<<<<<<<<<<<<<<<wait bt discon,then page_scan>>>>>>>>>>>>>\n"); */
        bt_get_vm_mac_addr(local_addr);
        //log_info("local_adr\n");
        //put_buf(local_addr,6);
        lmp_hci_write_local_address(local_addr);
        user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
        return;
    }
#endif

#if (TCFG_AUTO_STOP_PAGE_SCAN_TIME && TCFG_BD_NUM == 2)
    if ((get_total_connect_dev() == 1) && (bt->value != ERROR_CODE_CONNECTION_TIMEOUT)) {   //当前有一台连接上了,并且连接的是sink设备
        if (app_var.auto_stop_page_scan_timer == 0) {
            app_var.auto_stop_page_scan_timer = sys_timeout_add(NULL, bt_close_page_scan, (TCFG_AUTO_STOP_PAGE_SCAN_TIME * 1000)); //2
        }
    } else {
        if (app_var.auto_stop_page_scan_timer) {
            sys_timeout_del(app_var.auto_stop_page_scan_timer);
            app_var.auto_stop_page_scan_timer = 0;
        }
    }
#endif   //endif AUTO_STOP_PAGE_SCAN_TIME

#if (TCFG_BD_NUM == 2)
    if ((bt->value == ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR) ||
        (bt->value == ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED)) {
        /*
         *连接接受超时
         *如果支持1t2，可以选择继续回连下一台，除非已经回连完毕
         */
        /* if (get_current_poweron_memory_search_index(NULL)) {
            user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
            return;
        } */
    }
#endif

#if TCFG_USER_TWS_ENABLE
    /* bt_tws_phone_disconnected(); */
    if (bt->value == ERROR_CODE_CONNECTION_TIMEOUT) {
        bt_tws_phone_connect_timeout();
    } else {
        bt_tws_phone_disconnected();
    }
#else
    if (bt_user_priv_var.emitter_or_receiver != BT_EMITTER_EN) {
        bt_wait_phone_connect_control(1);
    } else {
#if 0//(TCFG_SPI_LCD_ENABLE)
        //彩屏方案又ui 控制
        if (bt_search_status()) {
            return;
        }

        u8 search_index = 0;
        search_index = get_current_poweron_memory_search_index(NULL);

        if (search_index) {
            /* log_debug(">>>>>>>>> search_index =%d \n", search_index); */
            user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
            return;
        }

        user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
#else
        if (bt->value !=  ERROR_CODE_CONNECTION_TIMEOUT) {
            extern u8 *get_cur_connect_phone_mac_addr(void);
            if (!get_cur_connect_phone_mac_addr()) {
                user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
                user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
            }
        }
#endif
    }
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event   链接link key 错误
   @param
   @return
   @note   可能是取消配对
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_linkkey_missing(struct bt_event *bt)
{
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
#if (CONFIG_NO_DISPLAY_BUTTON_ICON && TCFG_CHARGESTORE_ENABLE)
    //已取消配对了
    if (bt_ble_icon_get_adv_state() == ADV_ST_RECONN) {
        //切换广播
        /* log_info("switch_INQ\n"); */
        bt_ble_icon_open(ICON_TYPE_INQUIRY);
    }
#endif
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event   回链超时
   @param
   @return
   @note    回链超时内没有连接上设备
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_page_timeout(struct bt_event *bt)
{
    log_info("-----------HCI_EVENT_PAGE_TIMEOUT conuter %d", bt_user_priv_var.auto_connection_counter);
    UI_MSG_POST("bt_page_timeout");
#if TCFG_USER_TWS_ENABLE
    bt_tws_phone_page_timeout();
#else
    /* if (!bt_user_priv_var.auto_connection_counter) { */
    if (bt_user_priv_var.auto_connection_timer) {
        sys_timeout_del(bt_user_priv_var.auto_connection_timer);
        bt_user_priv_var.auto_connection_timer = 0;
    }

    /* #if (TCFG_BD_NUM == 2)
        if (get_current_poweron_memory_search_index(NULL)) {
            user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
            return;
        }
#endif */
    /* if (bt_user_priv_var.emitter_or_receiver != BT_EMITTER_EN) { */
    bt_wait_phone_connect_control(1);
    /* } else { */
    /*     user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL); */
    /* } */
#endif
}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event   链接超时
   @param
   @return
   @note    链接超时，设备拿远导致的超时等
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_connection_timeout(struct bt_event *bt)
{
    UI_MSG_POST("bt_connection_timeout");
    if (!get_remote_test_flag() && !get_esco_busy_flag()) {
        bt_user_priv_var.auto_connection_counter = (TIMEOUT_CONN_TIME * 1000);
        memcpy(bt_user_priv_var.auto_connection_addr, bt->args, 6);
#if TCFG_USER_TWS_ENABLE
        bt_tws_phone_connect_timeout();
#else

#if ((CONFIG_BT_MODE == BT_BQB)||(CONFIG_BT_MODE == BT_PER))
        bt_wait_phone_connect_control(1);
#else
        user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
        bt_wait_connect_and_phone_connect_switch(0);
#endif
        //user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, bt->args);
#endif
    } else {
#if TCFG_USER_TWS_ENABLE
        bt_tws_phone_disconnected();
#else
        bt_wait_phone_connect_control(1);
#endif
    }

}

/*----------------------------------------------------------------------------*/
/**@brief  蓝牙event   链接已经存在
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_connection_exist(struct bt_event *bt)
{
    if (!get_remote_test_flag() && !get_esco_busy_flag()) {
        bt_user_priv_var.auto_connection_counter = (8 * 1000);
        memcpy(bt_user_priv_var.auto_connection_addr, bt->args, 6);
#if TCFG_USER_TWS_ENABLE
        bt_tws_phone_connect_timeout();
#else
        if (bt_user_priv_var.auto_connection_timer) {
            sys_timer_del(bt_user_priv_var.auto_connection_timer);
            bt_user_priv_var.auto_connection_timer = 0;
        }
        bt_wait_connect_and_phone_connect_switch(0);
#endif
    } else {
#if TCFG_USER_TWS_ENABLE
        bt_tws_phone_disconnected();
#else
        bt_wait_phone_connect_control(1);
#endif
    }
}

extern u8 file_trans_idle_query(void);
u8 is_call_now()
{
#if (SMART_BOX_EN)
    if (!file_trans_idle_query()) {
        return 1;
    }
#endif

    if (get_call_status() != BT_CALL_HANGUP) {
        return 1;
    }

    return 0;
}
#else

void sys_enter_soft_poweroff(void *priv)
{
    if (priv == NULL) {
        app_task_switch_to(APP_POWEROFF_TASK);
    } else if (priv == (void *)1) {
        log_info("cpu_reset!!!\n");
        cpu_reset();
    }
}


#endif
