This commit is contained in:
huxi
2025-12-03 11:12:34 +08:00
parent c23ae4f24c
commit bc195654bf
8163 changed files with 3799544 additions and 92 deletions
+542
View File
@@ -0,0 +1,542 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_background.data.bss")
#pragma data_seg(".bt_background.data")
#pragma const_seg(".bt_background.text.const")
#pragma code_seg(".bt_background.text")
#endif
#include "system/includes.h"
#include "btstack/avctp_user.h"
#include "btstack/bluetooth.h"
#include "btctrler/btctrler_task.h"
#include "app_config.h"
#include "bt_background.h"
#include "bt_slience_detect.h"
#include "app_main.h"
#include "app_msg.h"
#include "a2dp_player.h"
#include "app_tone.h"
#include "classic/tws_api.h"
#include "dual_conn.h"
#include "btstack/a2dp_media_codec.h"
#if TCFG_APP_BT_EN
#if (TCFG_BT_BACKGROUND_ENABLE)
#define LOG_TAG "[BACKGROUND]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#define TWS_FUNC_ID_BACKGROUND_SYNC TWS_FUNC_ID('B', 'A', 'C', 'K')
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台模式初始化
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_background_init(int (*hci_handler)(struct bt_event *), int (*status_handler)(struct bt_event *))
{
g_bt_hdl.background.background_working = 0;
g_bt_hdl.background.goback_timer = 0xff;
g_bt_hdl.background.original_hci_handler = hci_handler;
g_bt_hdl.background.original_status_handler = status_handler;
INIT_LIST_HEAD(&g_bt_hdl.background.forward_msg_head);
}
static void background_add_forward_msg(int msg_from, int *msg)
{
struct forward_msg *_forward_msg = zalloc(sizeof(struct forward_msg));
if (_forward_msg) {
_forward_msg->msg_from = msg_from;
memcpy(_forward_msg->msg, msg, sizeof(struct bt_event));
list_add_tail(&_forward_msg->entry, &g_bt_hdl.background.forward_msg_head);
}
}
static void background_wait_phone_end(void *priv)
{
if ((app_var.siri_stu) && (app_var.siri_stu != 3)) {
// siri不退出
return;
}
if ((bt_get_call_status() == BT_CALL_OUTGOING)
|| (bt_get_call_status() == BT_CALL_ALERT)
|| (bt_get_call_status() == BT_CALL_INCOMING)
|| (bt_get_call_status() == BT_CALL_ACTIVE)
) {
// 通话不退出
return;
}
if (bt_get_esco_coder_busy_flag()) {
return;
}
if (g_bt_hdl.background.goback_timer != 0xff) {
sys_timer_del(g_bt_hdl.background.goback_timer);
}
g_bt_hdl.background.goback_timer = 0xff;
app_send_message(APP_MSG_GOTO_MODE, g_bt_hdl.background.goback_mode);
}
static void background_goback_with_phone(void)
{
if (g_bt_hdl.background.goback_timer == 0xff) {
g_bt_hdl.background.goback_timer = sys_timer_add(NULL, background_wait_phone_end, 1000);
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台模式退出蓝牙
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_background_suspend()
{
u8 suepend_rx_bulk = 0;
g_bt_hdl.exiting = 0;
g_bt_hdl.background.background_working = 1;
g_bt_hdl.background.backmode = BACKGROUND_GOBACK_WITH_MODE_SWITCH;
#if (TCFG_DEC2TWS_ENABLE)
suepend_rx_bulk = 0;
__this->exiting = 0;
#endif
sys_auto_shut_down_disable();
btctrler_suspend(suepend_rx_bulk);
btstack_suspend();
/*关掉解码, 打开能量检测,处理暂停之后又播歌的情况,能跳回蓝牙模式*/
u8 addr[6];
if (a2dp_player_get_btaddr(addr)) {
a2dp_player_close(addr);
bt_start_a2dp_slience_detect(addr, 50); //这里处理能跳回蓝牙模式外也处理后台丢包功能,如果手机一直没有发stop过来,这里会一直丢静音数据
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台模式返回蓝牙
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_background_resume(void)
{
g_bt_hdl.background.background_working = 0;
g_bt_hdl.background.goback_fitler = 0;
btstack_resume();
btctrler_resume();
void *devices[2];
if (btstack_get_conn_devices(devices, 2) < 1) { //无设备连接才打开自动关机
sys_auto_shut_down_enable();
}
log_info("bt_background_resume\n");
if (g_bt_hdl.background.backmode == BACKGROUND_GOBACK_WITH_PHONE) {
log_info("bt_background_goback_with_phone\n");
background_goback_with_phone();
}
/*除切模式触发的后台返回的消息需要重新处理*/
if (g_bt_hdl.background.backmode != BACKGROUND_GOBACK_WITH_MODE_SWITCH) {
struct forward_msg *p, *n;
list_for_each_entry_safe(p, n, &g_bt_hdl.background.forward_msg_head, entry) {
os_taskq_post_type("app_core", p->msg_from, \
sizeof(struct bt_event) / 4, p->msg);
__list_del_entry(&(p->entry));
free(p);
}
r_printf("list_emtry:%d\n", list_empty(&g_bt_hdl.background.forward_msg_head));
}
}
int bt_background_check_if_can_enter()
{
int esco_state;
if (app_var.siri_stu && app_var.siri_stu != 3 && bt_get_esco_coder_busy_flag()) {
// siri不退出
return -EINVAL;
}
esco_state = bt_get_call_status();
if (esco_state == BT_CALL_OUTGOING ||
esco_state == BT_CALL_ALERT ||
esco_state == BT_CALL_INCOMING ||
esco_state == BT_CALL_ACTIVE) {
// 通话不退出
return -EINVAL;
}
return 0;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台HCI事件过滤处理
@param event: 事件
@return 0:不需要切换模式 1:需要切换模式 2:通话导致需要切换 3:需要走原来的消息处理流程
@note
*/
/*----------------------------------------------------------------------------*/
static int bt_background_hci_event_filter(struct bt_event *event)
{
log_info("bt hci event: %d \n", event->event);
int ret = BACKGROUND_EVENT_NO_MACTH;
switch (event->event) {
case HCI_EVENT_IO_CAPABILITY_REQUEST:
/* clock_add_set(BT_CONN_CLK); To Do?*/
#if TCFG_BT_BACKGROUND_GOBACK && !USER_SUPPORT_DUAL_A2DP_SOURCE
ret = BACKGROUND_SWITCH_TO_BT;
#endif
break;
default:
ret = BACKGROUND_EVENT_ORIGINAL_DEAL;
break;
}
return ret;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台BTSTACK事件过滤处理
@param event: 事件
@return 0:不需要切换模式 1:需要切换模式 2:通话导致需要切换 3:需要走原来的消息处理流程
@note
*/
/*----------------------------------------------------------------------------*/
static int bt_background_btstack_event_filter(struct bt_event *event)
{
u8 ret = BACKGROUND_EVENT_NO_MACTH;
log_info("btstack event: %d \n", event->event);
switch (event->event) {
// 需要切换蓝牙的命令
case BT_STATUS_FIRST_DISCONNECT:
case BT_STATUS_SECOND_DISCONNECT:
//关机导致的断开不可以回去蓝牙,否则后台关机会有问题
if (app_var.goto_poweroff_flag) {
break;
}
if (g_bt_hdl.background.close_bt_hw_in_background) {
//需要后台关闭蓝牙硬件的就不返回蓝牙了
printf("close_bt_hw_in_background not go back\n");
break;
}
#if TCFG_BT_BACKGROUND_GOBACK
#if !USER_SUPPORT_DUAL_A2DP_SOURCE
ret = BACKGROUND_SWITCH_TO_BT;
#endif
#else
//判断断开的是sink设备,默认切换蓝牙
if (event->value) {
ret = BACKGROUND_SWITCH_TO_BT;
}
if (ret == 0) {
#if TCFG_USER_TWS_ENABLE
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
break;
}
tws_play_tone_file(get_tone_files()->bt_disconnect, 400);
#else
play_tone_file(get_tone_files()->bt_disconnect);
#endif
//bt_status_disconnect_background(&event->u.bt);
}
#endif
break;
case BT_STATUS_SECOND_CONNECTED:
case BT_STATUS_FIRST_CONNECTED:
#if TCFG_BT_BACKGROUND_GOBACK
#if !USER_SUPPORT_DUAL_A2DP_SOURCE
if (!check_page_mode_active()) { //如果是回连过程中不返回
ret = BACKGROUND_SWITCH_TO_BT;
} else {
ret = BACKGROUND_EVENT_ORIGINAL_DEAL;
}
#endif
#else
ret = BACKGROUND_EVENT_ORIGINAL_DEAL;
/* bt_status_connect_background(&event->u.bt); */
#endif
break;
case BT_STATUS_START_CONNECTED:
#if TCFG_BT_BACKGROUND_GOBACK && !USER_SUPPORT_DUAL_A2DP_SOURCE
ret = BACKGROUND_SWITCH_TO_BT;
#endif
break;
case BT_STATUS_ENCRY_COMPLETE:
break;
case BT_STATUS_SCO_STATUS_CHANGE:
ret = BACKGROUND_SWITCH_TO_BT;
break;
case BT_STATUS_LAST_CALL_TYPE_CHANGE:
/* bt_status_last_call_type_change(&event->u.bt); */
case BT_STATUS_VOICE_RECOGNITION:
case BT_STATUS_PHONE_INCOME:
case BT_STATUS_PHONE_NUMBER:
/* case BT_STATUS_PHONE_MANUFACTURER: */
case BT_STATUS_PHONE_OUT:
case BT_STATUS_PHONE_ACTIVE:
/* case BT_STATUS_PHONE_HANGUP: */
ret = BACKGROUND_PHONE_CALL_SWITCH_TO_BT;
break;
// 不需要处理的命令
/* case BT_STATUS_INIT_OK: 这里目前看了暂时不需要区分?*/
/* bt_status_init_ok_background(&event->u.bt); */
/* break; */
case BT_STATUS_A2DP_MEDIA_START:
log_info("BT_STATUS_A2DP_MEDIA_START start slience detect\n");
bt_start_a2dp_slience_detect(event->args, 50); //丢掉50包(约1s)之后才开始能量检测,过滤掉提示音,避免提示音引起抢占
ret = BACKGROUND_A2DP_SLIENCE_DETECT;
break;
case BT_STATUS_A2DP_MEDIA_STOP:
bt_stop_a2dp_slience_detect(event->args);
#if TCFG_USER_TWS_ENABLE
void tws_a2dp_player_close(u8 * bt_addr);
tws_a2dp_player_close(event->args);
#else
a2dp_play_close(event->args);
#endif
break;
case BT_STATUS_CALL_VOL_CHANGE:
break;
// 按原方式处理的命令
default:
ret = BACKGROUND_EVENT_ORIGINAL_DEAL;
break;
}
return ret;
}
/*----------------------------------------------------------------------------*/
/**@brief 判断是否处于蓝牙后台
@param void
@return TURE:处于蓝牙后台 FALSE:不处于蓝牙后台
@note
*/
/*----------------------------------------------------------------------------*/
bool bt_background_active(void)
{
return (g_bt_hdl.background.background_working) ? TRUE : FALSE;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台返回蓝牙模式
@param *msg_type:返回蓝牙模式的消息类型
*msg:返回蓝牙模式的消息内容
*mode:返回蓝牙模式的类型
@return void
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_background_goback(int msg_type, int *msg, BACKGROUND_GOBACK_MODE mode)
{
//返回蓝牙模式消息还需要走原本的消息处理函数
background_add_forward_msg(msg_type, msg);
if (g_bt_hdl.background.goback_fitler == 0) { //处理通话时可能触发多次goback导致重复切换任务
g_bt_hdl.background.goback_fitler = 1;
g_bt_hdl.background.backmode = mode;
if (g_bt_hdl.background.backmode == BACKGROUND_GOBACK_WITH_PHONE) { //由通话返回蓝牙模式需要记录当前模式,在通话结束之后返回
g_bt_hdl.background.goback_mode = app_get_current_mode()->name;
}
app_send_message(APP_MSG_GOTO_MODE, APP_MODE_BT);
#if TCFG_USER_TWS_ENABLE
if (tws_api_get_role() == TWS_ROLE_MASTER) {
tws_api_send_data_to_slave(&(g_bt_hdl.background), sizeof(g_bt_hdl.background), TWS_FUNC_ID_BACKGROUND_SYNC);
}
#endif
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台消息分发
@param *msg_from:消息类型
*msg:消息内容
@return void
@note
*/
/*----------------------------------------------------------------------------*/
static void background_msg_forward(int msg_from, int *msg)
{
const struct app_msg_handler *handler;
for_each_app_msg_handler(handler) {
if (handler->from != msg_from) {
continue;
}
handler->handler(msg);
}
}
static int background_btstack_event_handler(int *event)
{
u8 ret = bt_background_btstack_event_filter((struct bt_event *)event);
switch (ret) {
case BACKGROUND_A2DP_SLIENCE_DETECT:
/* g_bt_hdl.background.forward_msg_from = MSG_FROM_BT_STACK; */
/* memcpy(g_bt_hdl.background.forward_msg, event, sizeof(struct bt_event)); */
background_add_forward_msg(MSG_FROM_BT_STACK, event);
break;
case BACKGROUND_PHONE_CALL_SWITCH_TO_BT:
g_printf("BACKGROUND_SWITCH_TO_BT_WITH_PHONE\n");
bt_background_goback(MSG_FROM_BT_STACK, event, BACKGROUND_GOBACK_WITH_PHONE);
break;
case BACKGROUND_SWITCH_TO_BT:
if (!check_page_mode_active()) { //如果是回连过程中不返回
g_printf("BACKGROUND_SWITCH_TO_BT\n");
bt_background_goback(MSG_FROM_BT_STACK, event, BACKGROUND_GOBACK_WITH_OTHER);
}
break;
case BACKGROUND_EVENT_ORIGINAL_DEAL:
g_printf("BACKGROUND_ORIGINAL_DEAL\n");
if (g_bt_hdl.background.original_status_handler) {
g_bt_hdl.background.original_status_handler((struct bt_event *)event);
}
background_msg_forward(MSG_FROM_BT_STACK, event);
break;
}
return 0;
}
static int background_hci_event_handler(int *event)
{
u8 ret = bt_background_hci_event_filter((struct bt_event *)event);
switch (ret) {
case BACKGROUND_PHONE_CALL_SWITCH_TO_BT:
g_printf("BACKGROUND_SWITCH_TO_BT_WITH_PHONE\n");
bt_background_goback(MSG_FROM_BT_HCI, event, BACKGROUND_GOBACK_WITH_PHONE);
break;
case BACKGROUND_SWITCH_TO_BT:
g_printf("BACKGROUND_SWITCH_TO_BT\n");
bt_background_goback(MSG_FROM_BT_HCI, event, BACKGROUND_GOBACK_WITH_OTHER);
break;
case BACKGROUND_EVENT_ORIGINAL_DEAL:
g_printf("BACKGROUND_ORIGINAL_DEAL\n");
if (g_bt_hdl.background.original_hci_handler) {
g_bt_hdl.background.original_hci_handler((struct bt_event *)event);
}
background_msg_forward(MSG_FROM_BT_HCI, event);
break;
}
return 0;
}
static int background_app_msg_handler(int *msg)
{
int ret = TRUE;
switch (msg[0]) {
case APP_MSG_BT_A2DP_START:
g_printf("BACKGROUND_SWITCH_TO_BT A2DP_START\n");
struct bt_event event;
event.event = BT_STATUS_A2DP_MEDIA_START; //这里需要触发流程去打开解码
memcpy(event.args, msg + 1, 6);
void *file = a2dp_open_media_file(event.args);
if (file == NULL) {
log_error("open a2dp file error \n");
break;
}
a2dp_close_media_file(file);
background_add_forward_msg(MSG_FROM_BT_STACK, (int *)&event);
g_bt_hdl.background.backmode = BACKGROUND_GOBACK_WITH_MUSIC;
app_send_message(APP_MSG_GOTO_MODE, APP_MODE_BT);
#if TCFG_USER_TWS_ENABLE
if (tws_api_get_role() == TWS_ROLE_MASTER) {
tws_api_send_data_to_slave(&(g_bt_hdl.background), sizeof(g_bt_hdl.background), TWS_FUNC_ID_BACKGROUND_SYNC);
}
#endif
break;
default:
ret = FALSE; //APP_MSG没有match上需要走消息转发流程
break;
}
return ret;
}
/*----------------------------------------------------------------------------*/
/**@brief 后台过滤消息,如果处于后台模式且消息类型属于后台处理的,由后台来处理
@param msg: 需要处理的消息内容
@return TRUE: 消息由后台处理,无需再转发 FALSE:消息需要转发
@note
*/
/*----------------------------------------------------------------------------*/
bool bt_background_msg_forward_filter(int *msg)
{
bool ret = TRUE;
if (g_bt_hdl.background.background_working) {
switch (msg[0]) {
case MSG_FROM_BT_HCI:
background_hci_event_handler(msg + 1);
break;
case MSG_FROM_BT_STACK:
background_btstack_event_handler(msg + 1);
break;
case MSG_FROM_APP:
ret = background_app_msg_handler(msg + 1);
break;
default:
ret = FALSE;
break;
}
} else {
ret = FALSE;
}
return ret;
}
void bt_background_set_switch_mode(u8 mode)
{
g_printf("bt_background_set_switch_mode:%d\n", mode);
g_bt_hdl.background.poweron_need_switch_mode = TRUE;
g_bt_hdl.background.poweron_mode = mode;
}
bool bt_background_switch_mode_check(void)
{
return g_bt_hdl.background.poweron_need_switch_mode;
}
void bt_background_switch_mode_after_initializes(void)
{
if (g_bt_hdl.background.poweron_need_switch_mode) {
g_printf(" bt_background_switch_mode_after_initializes:%d\n", g_bt_hdl.background.poweron_need_switch_mode);
app_send_message(APP_MSG_GOTO_MODE, g_bt_hdl.background.poweron_mode);
g_bt_hdl.background.poweron_need_switch_mode = FALSE;
}
}
#if TCFG_USER_TWS_ENABLE
static void bt_background_sync(void *_data, u16 len, bool rx)
{
if (rx) {
u8 *data = (u8 *)_data;
memcpy(&(g_bt_hdl.background), data, sizeof(g_bt_hdl.background));
app_send_message(APP_MSG_GOTO_MODE, APP_MODE_BT);
}
}
REGISTER_TWS_FUNC_STUB(app_anc_sync_stub) = {
.func_id = TWS_FUNC_ID_BACKGROUND_SYNC,
.func = bt_background_sync,
};
#endif
#endif
#endif /* #if TCFG_APP_BT_EN */