#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_dec.h" #include "tone_player.h" #include "dac.h" #include "app_protocol_api.h" #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) extern void bt_start_a2dp_slience_detect(int ingore_packet_num) ; extern void bt_drop_a2dp_frame_start(void); /************************************************************* 此文件函数主要是蓝牙模式创建,模式退出和进去 后台、非后台的处理 **************************************************************/ /*----------------------------------------------------------------------------*/ /**@brief 蓝牙模式关机退出道idle模式 @param @return @note */ /*----------------------------------------------------------------------------*/ void wait_exit_btstack_flag(void *priv) { sys_timer_del(app_var.wait_exit_timer); app_var.wait_exit_timer = 0; if (priv == NULL) { app_task_switch_to(APP_POWEROFF_TASK); } else if (priv == (void *)1) { log_info("cpu_reset!!!\n"); cpu_reset(); } } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙模式后台回来蓝牙模式恢复 @param @return @note */ /*----------------------------------------------------------------------------*/ static void bt_resume_deal(void) { sys_key_event_enable(); sys_auto_sniff_controle(1, NULL); if (get_call_status() != BT_CALL_HANGUP) { log_debug("background return by call"); return; } bt_set_led_status(0); if (get_total_connect_dev() == 0) { sys_auto_shut_down_enable(); } } /*----------------------------------------------------------------------------*/ /**@brief 判断蓝牙通话是否在运行 @param @return @note */ /*----------------------------------------------------------------------------*/ int bt_must_work(void) { if ((app_var.siri_stu) && (app_var.siri_stu != 3)) { // siri不退出 return true; } if ((get_call_status() == BT_CALL_OUTGOING) || (get_call_status() == BT_CALL_ALERT) || (get_call_status() == BT_CALL_INCOMING) || (get_call_status() == BT_CALL_ACTIVE) ) { // 通话不退出 return true; } return false; } /*----------------------------------------------------------------------------*/ /**@brief 后台的时候判断有音频需要播放歌曲 @param @return @note */ /*----------------------------------------------------------------------------*/ static void a2dp_media_packet_play_start(void *p) { __this->back_mode_systime = 0; if ((__this->exit_flag == 0) || (__this->sbc_packet_step == 2)) { log_debug(" a2dp back \n"); #if (TCFG_DEC2TWS_ENABLE) /* tws_user_sync_box(TWS_BOX_A2DP_BACK_TO_BT_MODE_START, __this->a2dp_decoder_type); */ __this->tws_local_to_bt_mode = 1; localtws_set_wait_a2dp_start(1); #endif app_task_switch_to(APP_BT_TASK); struct sys_event event; event.type = SYS_BT_EVENT; event.arg = (void *)SYS_BT_EVENT_TYPE_CON_STATUS; event.u.bt.event = BT_STATUS_A2DP_MEDIA_START; event.u.bt.value = __this->a2dp_decoder_type; sys_event_notify(&event); } } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙模式发起播放命令 @param @return @note */ /*----------------------------------------------------------------------------*/ static int a2dp_media_packet_cmd_pp(void *p) { if ((__this->exit_flag == 1) && (__this->sbc_packet_step == 1)) { /* log_info("send pp "); */ user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL); } return 0; } u8 bt_get_exit_flag() { return __this->exit_flag; } extern int a2dp_media_clear_packet_before_seqn(u16 seqn_number); extern void *a2dp_media_fetch_packet(int *len, void *prev_packet); static u16 slience_timer; u16 clear_to_seqn; void a2dp_slience_detect(void *p) { int ingore_packet_num = (int)p; int role = tws_api_get_role(); int len; u8 *packet = a2dp_media_fetch_packet(&len, NULL); if (!packet) { return; } if (role == TWS_ROLE_MASTER) { if (packet) { u16 seqn = (packet[2] << 8) | packet[3]; if (clear_to_seqn == 0) { clear_to_seqn = seqn + ingore_packet_num; g_printf("clear_to_seqn=%d\n", clear_to_seqn); if (clear_to_seqn == 0) { clear_to_seqn = 1; } a2dp_media_clear_packet_before_seqn(clear_to_seqn); } } } if (clear_to_seqn) { bt_drop_a2dp_frame_start(); __a2dp_drop_frame(NULL); } } void bt_start_a2dp_slience_detect(int ingore_packet_num) { clear_to_seqn = 0; if (slience_timer) { sys_timer_del(slience_timer); } r_printf("bt_start_a2dp_slience_detect=%d", ingore_packet_num); a2dp_slience_detect((void *)ingore_packet_num); if (clear_to_seqn == 0) { slience_timer = sys_timer_add((void *)ingore_packet_num, a2dp_slience_detect, 40); } } void bt_stop_a2dp_slience_detect() { if (slience_timer) { sys_timer_del(slience_timer); slience_timer = 0; } } /*----------------------------------------------------------------------------*/ /**@brief tws后台回蓝牙模式 @param @return @note */ /*----------------------------------------------------------------------------*/ void tws_local_back_to_bt_mode(u8 mode, u8 value) { /* log_info("rx_tws_local_back_to_bt_mode=%d\n", mode); */ #if (TCFG_DEC2TWS_ENABLE) if (mode == TWS_BOX_NOTICE_A2DP_BACK_TO_BT_MODE) { if (__this->tws_local_back_role == 1) { localtws_set_wait_a2dp_start(1); __this->tws_local_back_role = 0; if (__this->back_mode_systime == 0) { __this->cmd_flag = 1; __this->back_mode_systime = sys_timeout_add(NULL, a2dp_media_packet_play_start, 1); } /* r_printf("tws_local_back_role ==role_new back mode_switch=%d\n", __this->back_mode_systime); */ } } else if (mode == TWS_BOX_A2DP_BACK_TO_BT_MODE_START) { __this->tws_local_back_role = 0; struct sys_event event; event.type = SYS_BT_EVENT; event.arg = (void *)SYS_BT_EVENT_TYPE_CON_STATUS; event.u.bt.event = BT_STATUS_A2DP_MEDIA_START; event.u.bt.value = value; sys_event_notify(&event); } else if (mode == TWS_BOX_EXIT_BT) { __this->a2dp_start_flag = 0; if (value == TWS_UNACTIVE_DEIVCE) { __this->tws_local_back_role = 2; if (tws_api_get_role() == TWS_ROLE_MASTER) { log_debug("\n ----- master pause ------- \n"); user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PAUSE, 0, NULL); } if (a2dp_dec_close()) { bt_start_a2dp_slience_detect(300); bt_drop_a2dp_frame_start(); __a2dp_drop_frame(NULL); } if (bt_get_exit_flag()) { __this->cmd_flag = 2; } /* __this->tws_local_back_role = 2; */ /* log_debug("__this->cmd_flag=0x%x,%d\n", __this->tws_local_back_role, __this->cmd_flag); */ app_task_switch_to(APP_BT_TASK); } else { __this->exiting = 0; } } else if (mode == TWS_BOX_ENTER_BT) { __this->tws_local_back_role = 0; if (!localtws_dec_close(1)) { tws_api_local_media_trans_clear(); } } #endif } /*----------------------------------------------------------------------------*/ /**@brief 后台模式下sbc丢包加能量检测, 返回-INVALUE表示要丢掉此包数据 @param @return @note */ /*----------------------------------------------------------------------------*/ int a2dp_media_packet_user_handler(u8 *data, u16 size) { if ((get_call_status() != BT_CALL_HANGUP) || bt_phone_dec_is_running() || (__this->call_flag)) { if (get_call_status() != BT_CALL_HANGUP) { /* puts("call!=hangup"); */ } return -EINVAL; } if (__this->tws_local_back_role == 2) { /* putchar('$'); */ return -EINVAL; } if (app_var.goto_poweroff_flag) { return -EINVAL; } #if TCFG_USER_TWS_ENABLE if (is_tws_going_poweroff()) { return -EINVAL; } #endif local_irq_disable(); if (__this->exit_flag == 0) { if ((!bt_media_is_running()) && (__this->sbc_packet_lose_cnt)) { __this->sbc_packet_lose_cnt++; if (__this->sbc_packet_lose_cnt > 10) { __this->sbc_packet_lose_cnt = 0; __this->cmd_flag = 0; __this->sbc_packet_step = 0; local_irq_enable(); __this->a2dp_decoder_type = a2dp_media_packet_codec_type(data); /* log_info("sbc lose over %d", __this->a2dp_decoder_type); */ if (__this->back_mode_systime == 0) { __this->back_mode_systime = sys_timeout_add(NULL, a2dp_media_packet_play_start, 1); } return 0; } } else { __this->sbc_packet_lose_cnt = 0; } local_irq_enable(); return 0; } u32 media_type = a2dp_media_packet_codec_type(data); u32 cur_time = timer_get_ms(); int energy = 0; if (media_type == 0/* A2DP_CODEC_SBC */) {//后台返回蓝牙 energy = sbc_energy_check(data, size); } else { if (a2dp_get_status() == BT_MUSIC_STATUS_STARTING) { energy = 2000; //其它格式不方便做能量检测。简易判断,该标志成立就直接认为是有效声音 } } /* log_info("sbc_filter: %d ", energy); */ if (__this->sbc_packet_step == 1) { // 退出 if ((cur_time > __this->no_sbc_packet_to) || ((cur_time > __this->sbc_packet_filter_to))) { // 转换为后台模式 log_debug("goto back mode \n"); __this->sbc_packet_step = 2; __this->no_sbc_packet_to = cur_time; __this->sbc_packet_filter_to = cur_time + SBC_FILTER_TIME_MS; __this->a2dp_decoder_type = a2dp_media_packet_codec_type(data); } else { // 还在退出 /* log_info("exit,, "); */ __this->no_sbc_packet_to = cur_time + NO_SBC_TIME_MS; if (energy > 1000) { __this->sbc_packet_filter_to = cur_time + SBC_ZERO_TIME_MS; __this->sbc_packet_valid_cnt ++; if (__this->sbc_packet_valid_cnt > __this->sbc_packet_valid_cnt_max) { __this->sbc_packet_valid_cnt = 0; if (__this->sbc_packet_valid_cnt_max < 80) { __this->sbc_packet_valid_cnt_max += 20; } else { log_debug("goto back mode0 \n"); __this->sbc_packet_step = 2; __this->no_sbc_packet_to = cur_time; __this->sbc_packet_filter_to = cur_time + SBC_FILTER_TIME_MS; } ///在退出的时候已经发送暂停 /* sys_timeout_add(NULL, a2dp_media_packet_cmd_pp, 1); */ } } else { __this->sbc_packet_valid_cnt = 0; } } } else if (__this->sbc_packet_step == 2) { // 后台 if (cur_time >= __this->no_sbc_packet_to) { // 新的开始 if (energy > 1000) { log_debug("new back mode \n"); #if 0 // 超时太短,容易误触发返回蓝牙模式 if (__this->tws_local_back_role) { /* puts("tws_new_back_mode\n"); */ __this->no_sbc_packet_to = cur_time + NO_SBC_TIME_MS * 2; __this->sbc_packet_filter_to = cur_time + SBC_FILTER_TIME_MS / 4; } else #endif { __this->no_sbc_packet_to = cur_time + NO_SBC_TIME_MS; __this->sbc_packet_filter_to = cur_time + SBC_FILTER_TIME_MS; } } else { /* log_info("energy limit \n"); */ } } else { /* log_info("bkm:%d, ", __this->sbc_packet_filter_to - cur_time); */ if (__this->tws_local_back_role) { __this->no_sbc_packet_to = cur_time + NO_SBC_TIME_MS * 2; } else { __this->no_sbc_packet_to = cur_time + NO_SBC_TIME_MS; } if (cur_time > __this->sbc_packet_filter_to) { //过滤时间耗完 __this->no_sbc_packet_to = cur_time; if (energy > 1000) { log_debug("start back mode \n"); __this->cmd_flag = 1; __this->tws_local_back_role = 0; local_irq_enable(); __this->a2dp_decoder_type = a2dp_media_packet_codec_type(data); if (__this->back_mode_systime == 0) { __this->back_mode_systime = sys_timeout_add(NULL, a2dp_media_packet_play_start, 1); } return -EINVAL; } } } } else { local_irq_enable(); return 0; } local_irq_enable(); return -EINVAL; } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙非后台模式退出蓝牙等待蓝牙状态可以退出 @param @return @note */ /*----------------------------------------------------------------------------*/ static void bt_no_background_exit_check(void *priv) { 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 (__this->init_ok == 0) { /* putchar('#'); */ return; } if (bt_audio_is_running()) { /* putchar('$'); */ return; } #if TCFG_USER_BLE_ENABLE bt_ble_exit(); #endif btstack_exit(); log_info("bt_exit_check ok\n"); __this->exit_flag = 1; sys_timer_del(__this->timer); __this->init_ok = 0; __this->init_start = 0; __this->timer = 0; __this->exiting = 0; set_stack_exiting(0); } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙后台模式退出蓝牙 @param @return @note */ /*----------------------------------------------------------------------------*/ static u8 bt_background_exit() { u8 suepend_rx_bulk = 1; __this->cmd_flag = 0; __this->call_flag = 0; u32 cur_time = timer_get_ms(); local_irq_disable(); __this->exit_flag = 1; __this->sbc_packet_step = 1; __this->sbc_packet_valid_cnt = 0; __this->sbc_packet_valid_cnt_max = 2; __this->no_sbc_packet_to = cur_time + NO_SBC_TIME_MS; __this->sbc_packet_filter_to = cur_time + SBC_ZERO_TIME_MS; local_irq_enable(); #if (TCFG_DEC2TWS_ENABLE) int state = tws_api_get_tws_state(); suepend_rx_bulk = 0; __this->tws_local_back_role = 0; if (state & TWS_STA_SIBLING_CONNECTED) { __this->tws_local_back_role = 1; tws_api_sync_call_by_uuid('D', SYNC_CMD_BOX_INIT_EXIT_BT, 0);// delay不宜太长,避免两边结束时间差异大 localtws_dec_close(1); } else { user_set_tws_box_mode(1); } /* r_printf("__this->tws_local_back_role=0x%x\n", __this->tws_local_back_role); */ #endif if (a2dp_dec_close()) { bt_start_a2dp_slience_detect(300); } extern int btctrler_suspend(u8 suepend_rx_bulk); btctrler_suspend(suepend_rx_bulk); extern int bredr_suspend(); bredr_suspend(); #if (TCFG_DEC2TWS_ENABLE) if (state & TWS_STA_SIBLING_CONNECTED) { __this->exiting = 1; return -EINVAL; } #endif return 0; } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙处于后台模式的时候关闭蓝牙。下次需要重新进入蓝牙初始化 @param @return @note 初版应用FM和蓝牙共用RF的情况下,进入FM需要关闭蓝牙 */ /*----------------------------------------------------------------------------*/ static u8 bt_nobackground_exit(); int bt_background_close_bt_hardward(u8 wait_flag) { #if TCFG_BLUETOOTH_BACK_MODE printf("exit flag %d, init flag %d\n", __this->exit_flag, __this->init_ok); if (!__this->init_ok) { __this->close_bt_hw_in_background = 0; return 0; } if (!__this->exit_flag) { __this->close_bt_hw_in_background = 0; return 0; } if (__this->close_bt_hw_in_background == 0) { __this->close_bt_hw_in_background = 1; bt_nobackground_exit(); } if (__this->exiting && wait_flag) { putchar('k'); os_time_dly(10); return -1; } #endif return 0; } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙后台模式关机,蓝牙关闭所有状态 @param @return @note */ /*----------------------------------------------------------------------------*/ static u8 bt_background_poweroff_exit() { __this->exiting = 1; set_stack_exiting(1); #if TCFG_USER_TWS_ENABLE bt_tws_poweroff(); #endif user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL); if (__this->exit_flag) { __this->sbc_packet_step = 0; __this->no_sbc_packet_to = 0; __this->sbc_packet_filter_to = 0; __this->sbc_packet_lose_cnt = 1; } if (__this->timer == 0) { __this->tmr_cnt = 0; __this->timer = sys_timer_add(NULL, bt_no_background_exit_check, 10); /* printf("set exit timer\n"); */ } return -EINVAL; } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙非后台模式退出模式 @param @return @note */ /*----------------------------------------------------------------------------*/ static u8 bt_nobackground_exit() { if (!__this->init_start) { return -EINVAL; } __this->exiting = 1; set_stack_exiting(1); __a2dp_drop_frame(NULL);//临时解决非后台退出杂音问题 #if AI_APP_PROTOCOL #if APP_PROTOCOL_SPEECH_EN extern void __app_protocol_speech_stop(void); __app_protocol_speech_stop(); #endif #endif #if TCFG_USER_TWS_ENABLE bt_tws_poweroff(); #endif app_protocol_exit(0); user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL); if (__this->timer == 0) { __this->tmr_cnt = 0; __this->timer = sys_timer_add(NULL, bt_no_background_exit_check, 10); printf("set exit timer\n"); } return -EINVAL; } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙通话检测 @param @return @note */ /*----------------------------------------------------------------------------*/ void esco_check_state(void *priv) { /* if (bt_sco_state()) { */ if (true == bt_phone_dec_is_running()) { sys_timeout_add(NULL, esco_check_state, 20); } else { #if (TCFG_DEC2TWS_ENABLE) extern bool get_tws_sibling_connect_state(void); if (get_tws_sibling_connect_state()) { if (tws_api_get_role() == TWS_ROLE_MASTER) { bt_tws_api_push_cmd(SYNC_CMD_POWER_OFF_TOGETHER, TWS_SYNC_TIME_DO); } } else #endif { sys_enter_soft_poweroff(NULL); } } } u8 bt_app_switch_exit_check() { if ((get_call_status() == BT_CALL_OUTGOING) || (get_call_status() == BT_CALL_ALERT) || (get_call_status() == BT_CALL_INCOMING) || (get_call_status() == BT_CALL_ACTIVE) ) { // 通话不退出 return 0; } if (__this->exit_flag) { // 正在退出就不用重新设置 // 避免快速调用两次导致发了两次pp,结束不了解码 log_debug("exit flag "); #if TCFG_BLUETOOTH_BACK_MODE if ((app_var.goto_poweroff_flag == 0) && (__this->exiting == 1)) { return 0; } else { return 1; } #else return 1; #endif } #if PHONE_CALL_FORCE_POWEROFF if (true == bt_phone_dec_is_running()) { log_debug("bt_phone_dec_is_running"); if (app_var.goto_poweroff_flag) { user_send_cmd_prepare(USER_CTRL_DISCONN_SCO, 0, NULL); sys_timeout_add(NULL, esco_check_state, 20); } app_var.goto_poweroff_flag = 0; return 0; } #else if (__this->force_poweroff) { if (true == bt_must_work()) { user_send_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL); sys_timeout_add(NULL, esco_check_state, 20); app_var.goto_poweroff_flag = 0; return 0; } if (true == bt_phone_dec_is_running()) { user_send_cmd_prepare(USER_CTRL_DISCONN_SCO, 0, NULL); sys_timeout_add(NULL, esco_check_state, 20); app_var.goto_poweroff_flag = 0; return 0; } __this->force_poweroff = 0; } if (true == bt_must_work()) { log_debug("bt_must_work"); app_var.goto_poweroff_flag = 0; return 0; } if (true == bt_phone_dec_is_running()) { log_debug("bt_phone_dec_is_running"); app_var.goto_poweroff_flag = 0; return 0; } #endif return 1; } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙退出模式 @param @return @note */ /*----------------------------------------------------------------------------*/ int bt_app_exit(void) { struct sys_event clear_key_event = {.type = SYS_KEY_EVENT, .arg = "key"}; log_info("bt_app_exit"); #if TCFG_USER_TWS_ENABLE #if AI_APP_PROTOCOL //告知APP要进行主从切换,特别是苹果app会自动重连 extern void app_protocal_update_tws_state_to_lib(int state); app_protocal_update_tws_state_to_lib(USER_NOTIFY_STATE_TWS_DISCONNECT); #endif #endif #if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_BT) bt_emitter_mic_close(); #endif __this->ignore_discon_tone = 1; bt_drop_a2dp_frame_stop(); /* __a2dp_drop_frame(NULL); */ sys_key_event_disable(); sys_event_clear(&clear_key_event); sys_auto_shut_down_disable(); tone_play_stop(); UI_HIDE_CURR_WINDOW(); #if TCFG_BLUETOOTH_BACK_MODE if (app_var.goto_poweroff_flag == 0) { return bt_background_exit(); } else { return bt_background_poweroff_exit(); } #else return bt_nobackground_exit(); #endif } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙后台进入模式初始化 @param @return @note */ /*----------------------------------------------------------------------------*/ void bt_background_init() { if (__this->back_mode_systime) { sys_timeout_del(__this->back_mode_systime); __this->back_mode_systime = 0; /* log_debug("__this->init_ok clear back_mode_systime\n"); */ } #if (TCFG_DEC2TWS_ENABLE) int state = tws_api_get_tws_state(); if (state & TWS_STA_SIBLING_CONNECTED) { if (__this->cmd_flag != 2) { if (__this->tws_local_to_bt_mode) { tws_user_sync_box(TWS_BOX_A2DP_BACK_TO_BT_MODE_START, __this->a2dp_decoder_type); } log_debug("tx_SYNC_CMD_BOX_ENTER_BT\n"); tws_api_sync_call_by_uuid('D', SYNC_CMD_BOX_ENTER_BT, 10); } } else { /* user_set_tws_box_mode(2); */ user_set_tws_box_mode(0); } __this->tws_local_to_bt_mode = 0; #endif local_irq_disable(); __this->sbc_packet_step = 0; __this->no_sbc_packet_to = 0; __this->sbc_packet_filter_to = 0; __this->sbc_packet_lose_cnt = 1; __this->tws_local_back_role = 0; local_irq_enable(); extern void bredr_resume();//background resume bredr_resume(); void btctrler_resume(); btctrler_resume(); bt_resume_deal(); __this->cmd_flag = 0; UI_SHOW_MENU(MENU_BT, 1000, 0, NULL); } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙进入模式初始化(时钟和显示部分和变量) @param @return @note */ /*----------------------------------------------------------------------------*/ void bt_task_init() { clock_idle(BT_IDLE_CLOCK); u32 sys_clk = clk_get("sys"); bt_pll_para(TCFG_CLOCK_OSC_HZ, sys_clk, 0, 0); __this->ignore_discon_tone = 0; __this->exiting = 0; __this->wait_exit = 0; __this->force_poweroff = 0 ; __this->init_start = 0;//蓝牙协议栈已经开始初始化标志位 UI_SHOW_WINDOW(ID_WINDOW_BT); UI_SHOW_MENU(MENU_BT, 1000, 0, NULL); #if TCFG_BLUETOOTH_BACK_MODE if (__this->init_ok) { __this->init_start = 1;//蓝牙协议栈已经开始初始化标志位 /* 按键消息使能 */ sys_key_event_enable();//第一次需要蓝牙初始化成功才开按键 不然会没有蓝牙后台 } #else sys_key_event_enable(); #endif } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙进入模式 @param @return @note */ /*----------------------------------------------------------------------------*/ void bt_task_start() { if (__this->exit_flag == 0) { return; } __this->exit_flag = 0; #if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_BT) if (bt_emitter_stu_get() == true) { bt_emitter_mic_open(); } #endif #if TCFG_BLUETOOTH_BACK_MODE if (__this->init_ok) { bt_background_init(); return; } #else /*注释掉app_var.goto_poweroff_flag = 0; *为了防止关机过程中运行至此处时关机标志 *被清0导致不能正常关机的情况*/ /* app_var.goto_poweroff_flag = 0; */ #endif bt_function_select_init(); bredr_handle_register(); btstack_init(); #if TCFG_USER_TWS_ENABLE tws_profile_init(); #endif BT_STATE_INIT(); __this->init_start = 1;//蓝牙协议栈已经开始初始化 sys_auto_shut_down_enable(); sys_auto_sniff_controle(1, NULL); #if TCFG_BLUETOOTH_BACK_MODE sys_key_event_enable();//蓝牙带后台情况第一次开按键需要在协议栈初始化之后 #endif } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙模式退出 @param @return @note */ /*----------------------------------------------------------------------------*/ void bt_task_close() { tone_play_stop(); if (__this->timer) { sys_timer_del(__this->timer); __this->timer = 0; } sys_auto_shut_down_disable(); __this->auto_exit_limit_time = (u32) - 1; bt_app_exit(); } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙直接开关 @param @return @note 如果想后台开机不需要进蓝牙,可以在poweron模式 直接调用这个函数初始化蓝牙 */ /*----------------------------------------------------------------------------*/ void bt_direct_init() { #if TCFG_BLUETOOTH_BACK_MODE if (__this->bt_direct_init) { return; } log_info(" bt_direct_init \n"); u32 sys_clk = clk_get("sys"); bt_pll_para(TCFG_CLOCK_OSC_HZ, sys_clk, 0, 0); __this->ignore_discon_tone = 0; __this->bt_direct_init = 1; #if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_BT) if (bt_emitter_stu_get() == true) { bt_emitter_mic_open(); } #endif bt_function_select_init(); bredr_handle_register(); btstack_init(); #if TCFG_USER_TWS_ENABLE tws_profile_init(); #endif BT_STATE_INIT(); /* 按键消息使能 */ sys_key_event_enable(); sys_auto_shut_down_enable(); sys_auto_sniff_controle(1, NULL); #endif } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙 退出蓝牙等待蓝牙状态可以退出 @param @return @note */ /*----------------------------------------------------------------------------*/ void bt_direct_close_check(void *priv) { #if TCFG_BLUETOOTH_BACK_MODE 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 (__this->init_ok == 0) { /* putchar('#'); */ return; } if (bt_audio_is_running()) { /* putchar('$'); */ return; } #if TCFG_USER_BLE_ENABLE bt_ble_exit(); #endif #if TCFG_USER_TWS_ENABLE bt_tws_poweroff(); #endif btstack_exit(); log_info(" bt_direct_close_check ok\n"); sys_timer_del(__this->timer); __this->init_ok = 0; __this->init_start = 0; __this->timer = 0; __this->bt_direct_init = 0; set_stack_exiting(0); #endif } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙后台直接关闭 @param @return @note */ /*----------------------------------------------------------------------------*/ void bt_direct_close(void) { #if TCFG_BLUETOOTH_BACK_MODE if (__this->init_ok == 0) { /* putchar('#'); */ return; } log_info(" bt_direct_close"); #if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_BT) bt_emitter_mic_close(); #endif __this->ignore_discon_tone = 1; sys_auto_shut_down_disable(); set_stack_exiting(1); __a2dp_drop_frame(NULL);//临时解决非后台退出杂音问题 user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL); if (__this->timer == 0) { __this->tmr_cnt = 0; __this->timer = sys_timer_add(NULL, bt_direct_close_check, 10); printf("set exit timer\n"); } #endif } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙 关闭bredr @param @return @note 主要把bredr 运行状态都关闭即可 */ /*----------------------------------------------------------------------------*/ void bt_close_bredr() { __this->bt_close_bredr = 1; 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; } user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL); user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL); user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL); user_send_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL); #if TCFG_USER_TWS_ENABLE tws_cancle_all_noconn(); #endif sys_auto_sniff_controle(0, NULL); btctrler_task_close_bredr(); } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙 开启bredr @param @return @note */ /*----------------------------------------------------------------------------*/ void bt_init_bredr() { __this->bt_close_bredr = 0; btctrler_task_init_bredr(); bt_wait_phone_connect_control(1); sys_auto_sniff_controle(1, NULL); } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙 开关a2dp @param @return @note */ /*----------------------------------------------------------------------------*/ void bredr_a2dp_open_and_close() { if (get_curr_channel_state() & A2DP_CH) { puts("start to disconnect a2dp "); user_send_cmd_prepare(USER_CTRL_DISCONN_A2DP, 0, NULL); } else { puts("start to connect a2dp "); user_send_cmd_prepare(USER_CTRL_CONN_A2DP, 0, NULL); } } /*----------------------------------------------------------------------------*/ /**@brief 蓝牙 开关hfp @param @return @note */ /*----------------------------------------------------------------------------*/ void bredr_hfp_open_and_close() { if (get_curr_channel_state() & HFP_CH) { user_send_cmd_prepare(USER_CTRL_HFP_DISCONNECT, 0, NULL); } else { user_send_cmd_prepare(USER_CTRL_HFP_CMD_BEGIN, 0, NULL); } } u8 bt_get_task_state() { return __this->exiting; } #endif