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
+260
View File
@@ -0,0 +1,260 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".a2dp_play.data.bss")
#pragma data_seg(".a2dp_play.data")
#pragma const_seg(".a2dp_play.text.const")
#pragma code_seg(".a2dp_play.text")
#endif
#include "btstack/avctp_user.h"
#include "btstack/btstack_task.h"
#include "os/os_api.h"
#include "bt_slience_detect.h"
#include "a2dp_player.h"
#include "esco_player.h"
#include "app_tone.h"
#include "app_main.h"
#include "vol_sync.h"
#include "audio_config.h"
#include "btstack/a2dp_media_codec.h"
#include "bt.h"
#include "effect/effects_default_param.h"
#include "scene_switch.h"
#if TCFG_APP_BT_EN
#if(TCFG_USER_TWS_ENABLE == 0)
//开关a2dp后,是否保持变调状态
#define A2DP_PLAYBACK_PITCH_KEEP 0
enum {
CMD_A2DP_PLAY = 1,
CMD_A2DP_SLIENCE_DETECT,
CMD_A2DP_CLOSE,
CMD_SET_A2DP_VOL,
};
static u8 g_play_addr[6];
static u8 g_slience_addr[6];
/**@brief a2dp
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
u8 bt_get_a2dp_en_status()
{
return g_bt_hdl.a2dp_en;
}
void bt_set_a2dp_en_status(u8 on)
{
printf("%s need todo \n", __FUNCTION__);
g_bt_hdl.a2dp_en = !!on;
}
static int bt_init_a2dp_en_status(void)
{
/* #if TCFG_USER_EMITTER_ENABLE */
/* g_bt_hdl.a2dp_en = 0; */
/* #else */
g_bt_hdl.a2dp_en = 1;
/* #endif */
return 0;
}
platform_initcall(bt_init_a2dp_en_status);
void a2dp_play_close(u8 *bt_addr)
{
puts("a2dp_play_close\n");
put_buf(bt_addr, 6);
a2dp_player_close(bt_addr);
bt_stop_a2dp_slience_detect(bt_addr);
a2dp_media_close(bt_addr);
}
static void a2dp_play_in_task(u8 *data)
{
u8 btaddr[6];
u8 dev_vol;
u8 *bt_addr = data + 2;
switch (data[0]) {
case CMD_A2DP_SLIENCE_DETECT:
puts("CMD_A2DP_SLIENCT_DETECE\n");
put_buf(bt_addr, 6);
a2dp_play_close(bt_addr);
bt_start_a2dp_slience_detect(bt_addr, 50); //丢掉50包(约1s)之后才开始能量检测,过滤掉提示音,避免提示音引起抢占
memset(g_slience_addr, 0xff, 6);
break;
case CMD_A2DP_PLAY:
puts("app_msg_bt_a2dp_play\n");
put_buf(bt_addr, 6);
#if (TCFG_BT_A2DP_PLAYER_ENABLE == 0)
break;
#endif
app_audio_state_switch(APP_AUDIO_STATE_MUSIC, app_audio_volume_max_query(AppVol_BT_MUSIC), NULL);
dev_vol = data[8];
//更新一下音量再开始播放
if (dev_vol > 127) { //返回值0xff说明不支持音量同步
y_printf("device no support sync vol, use sys volume:%d\n", app_var.music_volume);
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, app_var.music_volume, 1);
app_audio_set_volume_def_state(0);
} else {
set_music_device_volume(dev_vol);
}
bt_stop_a2dp_slience_detect(bt_addr);
int err = a2dp_player_open(bt_addr);
if (err == -EBUSY) {
bt_start_a2dp_slience_detect(bt_addr, 50); //丢掉50包(约1s)之后才开始能量检测,过滤掉提示音,避免提示音引起抢占
}
memset(g_play_addr, 0xff, 6);
music_vocal_remover_update_parm();
break;
case CMD_A2DP_CLOSE:
a2dp_play_close(bt_addr);
break;
case CMD_SET_A2DP_VOL:
dev_vol = data[8];
set_music_device_volume(dev_vol);
break;
}
}
static void a2dp_play_send_cmd(u8 cmd, u8 *_data, u8 len, u8 tx_do_action)
{
u8 data[16];
data[0] = cmd;
data[1] = 2;
memcpy(data + 2, _data, len);
a2dp_play_in_task(data);
}
static void a2dp_play(u8 *bt_addr, bool tx_do_action)
{
u8 data[8];
memcpy(data, bt_addr, 6);
data[6] = bt_get_music_volume(bt_addr);
/* if (data[6] > 127) { */
/* data[6] = app_audio_bt_volume_update(bt_addr, APP_AUDIO_STATE_MUSIC); */
/* } */
a2dp_play_send_cmd(CMD_A2DP_PLAY, data, 7, tx_do_action);
}
static void a2dp_play_slience_detect(u8 *bt_addr, bool tx_do_action)
{
a2dp_play_send_cmd(CMD_A2DP_SLIENCE_DETECT, bt_addr, 6, tx_do_action);
}
static int a2dp_bt_status_event_handler(int *event)
{
int ret;
u8 data[8];
u8 btaddr[6];
struct bt_event *bt = (struct bt_event *)event;
switch (bt->event) {
case BT_STATUS_A2DP_MEDIA_START:
puts("BT_STATUS_A2DP_MEDIA_START\n");
put_buf(bt->args, 6);
if (app_var.goto_poweroff_flag) {
break;
}
void *file = a2dp_open_media_file(bt->args);
if (file == NULL) {
printf("open a2dp file error \n");
break;
}
a2dp_close_media_file(file);
if (bt_get_call_status_for_addr(bt->args) == BT_CALL_INCOMING) {
//小米11来电挂断偶现没有hungup过来,hfp链路异常,重新断开hfp再连接
puts("<<<<<<<<waring a2dp start hfp_incoming\n");
bt_cmd_prepare_for_addr(bt->args, USER_CTRL_HFP_DISCONNECT, 0, NULL);
bt_cmd_prepare_for_addr(bt->args, USER_CTRL_HFP_CMD_CONN, 0, NULL);
}
if (esco_player_runing()) {
a2dp_media_close(bt->args);
break;
}
if (a2dp_player_get_btaddr(btaddr)) {
if (memcmp(btaddr, bt->args, 6) == 0) {
a2dp_play(bt->args, 1);
} else {
a2dp_play_slience_detect(bt->args, 1);
}
} else {
a2dp_play(bt->args, 1);
}
#if (TCFG_PITCH_SPEED_NODE_ENABLE && A2DP_PLAYBACK_PITCH_KEEP)
audio_pitch_default_parm_set(app_var.pitch_mode);
a2dp_file_pitch_mode_init(app_var.pitch_mode);
#endif
break;
case BT_STATUS_A2DP_MEDIA_STOP:
puts("BT_STATUS_A2DP_MEDIA_STOP\n");
a2dp_play_send_cmd(CMD_A2DP_CLOSE, bt->args, 6, 1);
break;
case BT_STATUS_AVRCP_VOL_CHANGE:
//判断是当前地址的音量值才更新
ret = a2dp_player_get_btaddr(data);
if (ret && memcmp(data, bt->args, 6) == 0) {
data[6] = bt->value;
a2dp_play_send_cmd(CMD_SET_A2DP_VOL, data, 7, 1);
}
break;
}
return 0;
}
APP_MSG_HANDLER(a2dp_stack_msg_handler) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = a2dp_bt_status_event_handler,
};
static int a2dp_bt_hci_event_handler(int *event)
{
struct bt_event *bt = (struct bt_event *)event;
switch (bt->event) {
case HCI_EVENT_DISCONNECTION_COMPLETE:
a2dp_play_close(bt->args);
break;
}
return 0;
}
APP_MSG_HANDLER(a2dp_hci_msg_handler) = {
.owner = 0xff,
.from = MSG_FROM_BT_HCI,
.handler = a2dp_bt_hci_event_handler,
};
static int a2dp_app_msg_handler(int *msg)
{
u8 *bt_addr = (u8 *)(msg + 1);
switch (msg[0]) {
case APP_MSG_BT_A2DP_PAUSE:
puts("app_msg_bt_a2dp_pause\n");
if (a2dp_player_is_playing(bt_addr)) {
a2dp_play_slience_detect(bt_addr, 1);
}
break;
case APP_MSG_BT_A2DP_PLAY:
puts("app_msg_bt_a2dp_play\n");
a2dp_play(bt_addr, 1);
break;
}
return 0;
}
APP_MSG_HANDLER(a2dp_app_msg_handler_stub) = {
.owner = 0xff,
.from = MSG_FROM_APP,
.handler = a2dp_app_msg_handler,
};
#endif
#endif /* #if TCFG_APP_BT_EN */
File diff suppressed because it is too large Load Diff
+160
View File
@@ -0,0 +1,160 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_app_msg_handler.data.bss")
#pragma data_seg(".bt_app_msg_handler.data")
#pragma const_seg(".bt_app_msg_handler.text.const")
#pragma code_seg(".bt_app_msg_handler.text")
#endif
#include "key_driver.h"
#include "app_main.h"
#include "init.h"
#include "bt_key_func.h"
#include "low_latency.h"
#include "a2dp_player.h"
#include "linein_player.h"
#include "app_tone.h"
#include "audio_config.h"
#include "vol_sync.h"
#include "bt.h"
#include "classic/tws_api.h"
#if TCFG_APP_BT_EN
int bt_app_msg_handler(int *msg)
{
if (false == app_in_mode(APP_MODE_BT)) {
return 0;
}
u8 msg_type = msg[0];
printf("bt_app_msg type:0x%x", msg[0]);
switch (msg_type) {
case APP_MSG_CHANGE_MODE:
puts("app msg key change mode\n");
/*一些情况不希望退出蓝牙模式*/
if (bt_app_exit_check() == 0) {
puts("bt_background can not enter\n");
return 0;
}
#if TCFG_USER_TWS_ENABLE && !TCFG_BT_BACKGROUND_ENABLE
#if CONFIG_TWS_USE_COMMMON_ADDR == 0
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
tws_api_detach(TWS_DETACH_BY_POWEROFF, 5000); //这里从机用TWS_DETACH_BY_POWEROFF断开不会进行主从切换
g_bt_hdl.ignore_discon_tone = 1;
}
#endif
if (msg[1] == APP_KEY_MSG_FROM_TWS) { //非后台不响应来自tws的切换模式消息
return 0;
}
#endif
app_send_message(APP_MSG_GOTO_NEXT_MODE, 0);
break;
case APP_MSG_MUSIC_PP:
puts("app msg music pp\n");
bt_key_music_pp();
break;
case APP_MSG_MUSIC_NEXT:
puts("app msg music next\n");
bt_key_music_next();
break;
case APP_MSG_MUSIC_PREV:
puts("app msg music prev\n");
bt_key_music_prev();
break;
case APP_MSG_VOL_UP:
puts("app msg vol up\n");
bt_key_vol_up();
break;
case APP_MSG_VOL_DOWN:
puts("app msg vol down\n");
bt_key_vol_down();
break;
case APP_MSG_CALL_HANGUP:
puts("app msg call HangUp\n");
bt_key_call_hang_up();
break;
case APP_MSG_CALL_LAST_NO:
puts("app msg call last on\n");
bt_key_call_last_on();
break;
case APP_MSG_OPEN_SIRI:
puts("app msg open siri\n");
bt_key_call_siri();
break;
case APP_MSG_HID_CONTROL:
puts("app msg hid control\n");
bt_key_hid_control();
break;
case APP_MSG_LOW_LANTECY:
puts("app msg low lantecy\n");
int state = bt_get_low_latency_mode();
bt_set_low_latency_mode(!state);
break;
case APP_MSG_ADD_LINEIN_STREAM:
#if TCFG_APP_LINEIN_EN
//工具的蓝牙流程图需要添加对应的linein数据流!!
puts("app msg add linein stream\n");
if (linein_player_runing()) {
linein_player_close();
} else {
linein_player_open();
}
#endif
break;
case APP_MSG_BT_A2DP_START:
#if TCFG_BT_BACKGROUND_ENABLE
/*这里处理有些设备切到后台一直不推a2dp stop,手动切到蓝牙模式后能量检测还在跑,这时候点击设备播放按钮之后,
能量检测有数据之后结束推APP_MSG_BT_A2DP_START,这种情况需要在这里打开解码*/
u8 *bt_addr = (u8 *)&msg[1];
ASSERT(bt_addr);
u8 dev_vol = bt_get_music_volume(bt_addr);
app_audio_state_switch(APP_AUDIO_STATE_MUSIC, app_audio_volume_max_query(AppVol_BT_MUSIC), NULL);
if (dev_vol > 127) {
dev_vol = app_audio_bt_volume_update(bt_addr, APP_AUDIO_STATE_MUSIC);
}
set_music_device_volume(dev_vol);
int err = a2dp_player_open(bt_addr);
if (err == -EBUSY) {
printf("bt_app_msg_handler open a2dp_player failed\n");
}
#endif
break;
case APP_MSG_CALL_THREE_WAY_ANSWER1:
bt_key_call_three_way_answer1();
break;
case APP_MSG_CALL_THREE_WAY_ANSWER2:
bt_key_call_three_way_answer2();
break;
case APP_MSG_CALL_SWITCH:
bt_key_call_switch();
break;
case APP_MSG_PITCH_UP:
#if TCFG_PITCH_SPEED_NODE_ENABLE
printf("app msg a2dp pitch up\n");
if (a2dp_player_runing()) {
app_var.pitch_mode = a2dp_file_pitch_up(); //返回当前变调模式
}
#endif
break;
case APP_MSG_PITCH_DOWN:
#if TCFG_PITCH_SPEED_NODE_ENABLE
printf("app msg a2dp pitch down\n");
if (a2dp_player_runing()) {
app_var.pitch_mode = a2dp_file_pitch_down();
}
#endif
break;
default:
app_common_key_msg_handler(msg);
printf("unknow msg type:%d", msg_type);
break;
}
return 0;
}
#endif /* #if TCFG_APP_BT_EN */
+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 */
@@ -0,0 +1,86 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_call_kws_handler.data.bss")
#pragma data_seg(".bt_call_kws_handler.data")
#pragma const_seg(".bt_call_kws_handler.text.const")
#pragma code_seg(".bt_call_kws_handler.text")
#endif
#include "btstack/avctp_user.h"
#include "app_main.h"
#include "jl_kws/jl_kws_api.h"
#include "app_config.h"
#include "audio_cvp.h"
#include "smart_voice.h"
#include "esco_player.h"
#include "media/asr/jl_kws.h"
#if (TCFG_KWS_VOICE_RECOGNITION_ENABLE || TCFG_CALL_KWS_SWITCH_ENABLE) && !TCFG_AUDIO_ASR_DEVELOP
static void jl_call_kws_handler(int event)
{
if (event == BT_STATUS_PHONE_INCOME) {
printf("BT_STATUS_PHONE_INCOME");
#if TCFG_KWS_VOICE_RECOGNITION_ENABLE
audio_aec_reboot(1);
jl_kws_speech_recognition_open();
jl_kws_speech_recognition_start();
#endif
#if TCFG_CALL_KWS_SWITCH_ENABLE
audio_aec_reboot(1);
/* audio_phone_call_kws_start(); */
audio_smart_voice_detect_open(JL_KWS_COMMAND_KEYWORD);
#endif /* #if TCFG_CALL_KWS_SWITCH_ENABLE */
} else if (event == BT_STATUS_PHONE_ACTIVE) {
printf("BT_STATUS_PHONE_ACTIVE");
#if TCFG_KWS_VOICE_RECOGNITION_ENABLE
jl_kws_speech_recognition_close();
audio_aec_reboot(0);
#endif
#ifdef CONFIG_BOARD_AISPEECH_VAD_ASR
printf("----aispeech_state phone active");
ais_platform_asr_close();
esco_mic_reset();
#endif /*CONFIG_BOARD_AISPEECH_VAD_ASR*/
#if TCFG_CALL_KWS_SWITCH_ENABLE
audio_smart_voice_detect_close();
audio_aec_reboot(0);
#endif /* TCFG_CALL_KWS_SWITCH_ENABLE */
} else if (event == BT_STATUS_PHONE_HANGUP) {
printf("BT_STATUS_PHONE_HANGUP");
#if TCFG_KWS_VOICE_RECOGNITION_ENABLE
jl_kws_speech_recognition_close();
#endif
#if TCFG_CALL_KWS_SWITCH_ENABLE
if (!esco_player_runing()) {
audio_phone_call_kws_close();
}
#endif /* TCFG_CALL_KWS_SWITCH_ENABLE */
}
}
static int kws_btstack_msg_handler(int *msg)
{
struct bt_event *bt = (struct bt_event *)msg;
switch (bt->event) {
case BT_STATUS_PHONE_INCOME:
jl_call_kws_handler(BT_STATUS_PHONE_INCOME);
break;
case BT_STATUS_PHONE_ACTIVE:
jl_call_kws_handler(BT_STATUS_PHONE_ACTIVE);
break;
case BT_STATUS_PHONE_HANGUP:
jl_call_kws_handler(BT_STATUS_PHONE_HANGUP);
break;
default:
break;
}
return 0;
}
APP_MSG_PROB_HANDLER(call_kws_btstack_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = kws_btstack_msg_handler,
};
#endif /* #if (TCFG_KWS_VOICE_RECOGNITION_ENABLE || TCFG_CALL_KWS_SWITCH_ENABLE) && !TCFG_AUDIO_ASR_DEVELOP */
+512
View File
@@ -0,0 +1,512 @@
#include "bt.h"
#include "app_config.h"
#include "app_main.h"
#include "app_msg.h"
#include "btstack/avctp_user.h"
#include "dual_conn.h"
#include "jlui_app/ui_api.h"
#include "file_player.h"
#define LOG_TAG "[EMITTER]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if TCFG_USER_EMITTER_ENABLE
#define BT_EMITTER_TEST 0
#define SEARCH_BD_ADDR_LIMITED 0
#define SEARCH_BD_NAME_LIMITED 1
#define SEARCH_CUSTOM_LIMITED 2
#define SEARCH_NULL_LIMITED 3
#define SEARCH_LIMITED_MODE SEARCH_BD_NAME_LIMITED
struct list_head inquiry_noname_list;
struct inquiry_noname_remote {
struct list_head entry;
u8 match;
s8 rssi;
u8 addr[6];
u32 class;
};
u8 restore_remote_device_info_profile(bd_addr_t mac_addr, u8 device_num, u8 id, u8 profile);
static u8 read_name_start = 0;
static u8 search_spp_device = 0;
extern struct file_player *get_music_file_player(void); //返回第一个打开的音乐播放器指针
extern int music_file_get_player_status(struct file_player *music_player);
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射发起搜索设备
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void bt_search_device(void)
{
if (is_bredr_close() == 1) {
ASSERT(0, "bt close should user bt_emitter_start_search_device()");
}
if (!bt_check_already_initializes()) {
log_info("bt on init >>>>>>>>>>>>>>>>>>>>>>>\n");
return;
}
u8 inquiry_length = 20; // inquiry_length * 1.28s
bt_cmd_prepare(USER_CTRL_SEARCH_DEVICE, 1, &inquiry_length);
log_info("bt_search_start >>>>>>>>>>>>>>>>>>>>>>>\n");
}
void bt_search_stop(void)
{
bt_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL);
log_info("bt_search_stop >>>>>>>>>>>>>>>>>>>>>>>\n");
}
void emitter_bt_connect(u8 *mac)
{
if (is_bredr_close() == 1) {
bredr_conn_dev(mac);
} else {
dual_conn_user_bt_connect(mac);
}
}
void bt_emitter_start_search_device()
{
if (g_bt_hdl.emitter_or_receiver != BT_EMITTER_EN) {
return ;
}
if (is_bredr_close() == 1) {
bredr_search_device();
} else {
/* user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL); */
/* 关闭可发现 */
bt_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
bt_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
////发起扫描
bt_search_device();
}
}
#if (SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
u8 bd_addr_filt[][6] = {
{0x8E, 0xA7, 0xCA, 0x0A, 0x5E, 0xC8}, /*S10_H*/
{0xA7, 0xDD, 0x05, 0xDD, 0x1F, 0x00}, /*ST-001*/
{0xE9, 0x73, 0x13, 0xC0, 0x1F, 0x00}, /*HBS 730*/
{0x38, 0x7C, 0x78, 0x1C, 0xFC, 0x02}, /*Bluetooth*/
};
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过地址过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
u8 search_bd_addr_filt(u8 *addr)
{
u8 i;
log_info("bd_addr:");
log_info_hexdump(addr, 6);
for (i = 0; i < (sizeof(bd_addr_filt) / sizeof(bd_addr_filt[0])); i++) {
if (memcmp(addr, bd_addr_filt[i], 6) == 0) {
/* printf("bd_addr match:%d\n", i); */
return TRUE;
}
}
/*log_info("bd_addr not match\n"); */
return FALSE;
}
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
u8 bd_name_filt[][32] = {
"TG-294",
"JL709_VOL_ADAP",
};
u8 bd_spp_name_filt[20][30] = {
"AC69_BT_SDK",
};
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过名字过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
u8 search_bd_name_filt(char *data, u8 len, u32 dev_class, char rssi)
{
char bd_name[64] = {0};
u8 i;
char *targe_name = NULL;
if ((len > (sizeof(bd_name))) || (len == 0) || !data) {
//printf("bd_name_len error:%d\n", len);
return FALSE;
}
memset(bd_name, 0, sizeof(bd_name));
memcpy(bd_name, data, len);
log_info("name:%s,len:%d,class %x ,rssi %d\n", bd_name, len, dev_class, rssi);
if (search_spp_device) {
for (i = 0; i < (sizeof(bd_spp_name_filt) / sizeof(bd_spp_name_filt[0])); i++) {
if (memcmp(data, bd_spp_name_filt[i], len) == 0) {
puts("\n*****find dev ok******\n");
return TRUE;
}
}
} else {
for (i = 0; i < (sizeof(bd_name_filt) / sizeof(bd_name_filt[0])); i++) {
if (memcmp(data, bd_name_filt[i], len) == 0) {
puts("\n*****find dev ok******\n");
return TRUE;
}
}
}
return FALSE;
}
#endif
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索结果回调处理
@param name : 设备名字
name_len: 设备名字长度
addr: 设备地址
dev_class: 设备类型
rssi: 设备信号强度
@return 无
@note
蓝牙设备搜索结果,可以做名字/地址过滤,也可以保存搜到的所有设备
在选择一个进行连接,获取其他你想要的操作。
返回TRUE,表示搜到指定的想要的设备,搜索结束,直接连接当前设备
返回FALSE,则继续搜索,直到搜索完成或者超时
*/
/*----------------------------------------------------------------------------*/
u8 emitter_search_result(char *name, u8 name_len, u8 *addr, u32 dev_class, char rssi)
{
log_info("name:%s,len:%d,class %x ,rssi %d\n", name, name_len, dev_class, rssi);
if (name == NULL) {
struct inquiry_noname_remote *remote = malloc(sizeof(struct inquiry_noname_remote));
ASSERT(remote);
remote->match = 0;
remote->class = dev_class;
remote->rssi = rssi;
memcpy(remote->addr, addr, 6);
local_irq_disable();
list_add_tail(&remote->entry, &inquiry_noname_list);
local_irq_enable();
if (read_name_start == 0) {
read_name_start = 1;
bt_cmd_prepare(USER_CTRL_READ_REMOTE_NAME, 6, addr);
}
}
if (name) {
extern void bt_menu_list_add(char *name, u8 * mac, u8 rssi);
bt_menu_list_add(name, addr, rssi);
log_info("name:%s,len:%d,class %x ,rssi %d\n", name, name_len, dev_class, rssi);
return FALSE;
}
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
return search_bd_name_filt(name, name_len, dev_class, rssi);
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
return search_bd_addr_filt(addr);
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_CUSTOM_LIMITED)
/*以下为搜索结果自定义处理*/
char bt_name[63] = {0};
u8 len;
if (name_len == 0) {
log_info("No_eir\n");
} else {
len = (name_len > 63) ? 63 : name_len;
/* display bd_name */
memcpy(bt_name, name, len);
log_info("name:%s,len:%d,class %x ,rssi %d\n", bt_name, name_len, dev_class, rssi);
}
/* display bd_addr */
log_debug_hexdump(addr, 6);
/* You can connect the specified bd_addr by below api */
/* dual_conn_user_bt_connect(addr); */
return FALSE;
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_NULL_LIMITED)
/*没有指定限制,则搜到什么就连接什么*/
return TRUE;
#endif
return FALSE;
}
void bt_emitter_init()
{
/* bt_emitter_start = 1; */
INIT_LIST_HEAD(&inquiry_noname_list);
bt_inquiry_result_handle_register(emitter_search_result);
lmp_set_sniff_establish_by_remote(1);
bt_emitter_set_enable_flag(1);
g_bt_hdl.emitter_or_receiver = BT_EMITTER_EN;
bt_a2dp_source_init(NULL, 0, 1);
#if (TCFG_BT_SUPPORT_HFP_AG==1)
bt_hfp_ag_buf_init(NULL, 0, 1);
#endif
#if BT_EMITTER_TEST
bt_emitter_start_search_device();
#endif
}
void emitter_search_stop_handle(u8 result)
{
log_info("%s == %d", __func__, result);
struct inquiry_noname_remote *remote, *n;
u8 wait_connect_flag = 1;
if (!list_empty(&inquiry_noname_list)) {
bt_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
}
if (!result) {
list_for_each_entry_safe(remote, n, &inquiry_noname_list, entry) {
if (remote->match) {
dual_conn_user_bt_connect(remote->addr);
wait_connect_flag = 0;
}
list_del(&remote->entry);
free(remote);
}
}
read_name_start = 0;
if (wait_connect_flag) {
/* log_info("wait conenct\n"); */
/* if (bt_get_total_connect_dev() == 2) { */
/* write_scan_conn_enable(0, 0); */
/* } else if (bt_get_total_connect_dev() == 1 && bt_get_connect_status() != BT_STATUS_WAITINT_CONN) { */
/* write_scan_conn_enable(0, 1); */
/* } else { */
/* write_scan_conn_enable(1, 1); */
/* } */
}
}
void printf_malloc(void *pive)
{
int count = 10000;
/* malloc_list_status_printf_all(count); */
}
u8 bt_emitter_stu_set(u8 *addr, u8 pp)
{
log_info("total con dev:%d ", bt_get_total_connect_dev());
if (pp && (bt_get_total_connect_dev() == 0) && !(bt_emitter_get_curr_channel_state() & A2DP_SRC_CH)) {
pp = 0;
}
if (pp) {
//开音频编码
app_var.a2dp_source_open_flag = 1;
/* sys_timer_add(NULL, printf_malloc, 300); */
bt_emitter_cmd_prepare(USER_CTRL_AVCTP_OPID_SEND_VOL, 0, NULL);
} else {
//关音频编码
app_var.a2dp_source_open_flag = 0;
}
bt_emitter_send_media_toggle(NULL, pp);
return pp;
}
u8 bt_emitter_pp(u8 pp)
{
return bt_emitter_stu_set(NULL, pp);
}
void emitter_open(u8 source)
{
bt_emitter_pp(1);
}
void emitter_close(u8 source)
{
bt_emitter_pp(0);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射接收到设备按键消息
@param cmd:按键命令
@return 无
@note
发射器收到接收器发过来的控制命令处理
根据实际需求可以在收到控制命令之后做相应的处理
蓝牙库里面定义的是weak函数,直接再定义一个同名可获取信息
*/
/*----------------------------------------------------------------------------*/
void emitter_rx_avctp_opid_deal(u8 cmd, u8 id) //属于库的弱函数重写
{
log_debug("avctp_rx_cmd:%x\n", cmd);
switch (cmd) {
case AVCTP_OPID_NEXT:
log_info("AVCTP_OPID_NEXT\n");
app_send_message(APP_MSG_MUSIC_NEXT, 0);
break;
case AVCTP_OPID_PREV:
log_info("AVCTP_OPID_PREV\n");
app_send_message(APP_MSG_MUSIC_PREV, 0);
break;
case AVCTP_OPID_PAUSE:
case AVCTP_OPID_STOP:
log_info("AVCTP_OPID_PAUSE\n");
app_send_message(APP_MSG_BT_EMITTER_PAUSE, 0);
break;
case AVCTP_OPID_PLAY:
log_info("AVCTP_OPID_PP\n");
app_send_message(APP_MSG_BT_EMITTER_PLAY, 0);
break;
case AVCTP_OPID_VOLUME_UP:
log_info("AVCTP_OPID_VOLUME_UP\n");
app_send_message(APP_MSG_VOL_UP, 0);
break;
case AVCTP_OPID_VOLUME_DOWN:
log_info("AVCTP_OPID_VOLUME_DOWN\n");
app_send_message(APP_MSG_VOL_DOWN, 0);
break;
default:
break;
}
return ;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射接收设备同步音量
@param vol:接收到设备同步音量
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_rx_vol_change(u8 vol) //属于库的弱函数重写
{
log_info("vol_change:%d \n", vol);
}
////回链手机
u8 connect_last_source_device_from_vm()
{
u8 mac_addr[6];
u8 flag = 0;
flag = restore_remote_device_info_profile((u8 *)&mac_addr, 1, get_remote_dev_info_index(), REMOTE_SOURCE);
if (flag) {
//connect last conn
printf("last source device addr from vm:");
put_buf(mac_addr, 6);
dual_conn_user_bt_connect(mac_addr);
}
return flag;
}
static int bt_emitter_btstack_event_handler(int *msg)
{
struct bt_event *bt = (struct bt_event *)msg;
switch (bt->event) {
case BT_STATUS_INIT_OK:
log_info(" BT_STATUS_INIT_OK \n");
bt_emitter_init();
break;
case BT_STATUS_CONN_A2DP_CH:
log_info("++++++++ BT_STATUS_CONN_A2DP_CH +++++++++ 0x%x \n", bt->value);
if (bt->value & A2DP_SRC_CH) {
#if BT_EMITTER_TEST
bt_emitter_pp(1);
#endif
}
break;
}
return 0;
}
APP_MSG_HANDLER(emitter_stack_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = bt_emitter_btstack_event_handler,
};
static int bt_emitter_hci_event_handler(struct bt_event *bt)
{
//对应原来的蓝牙连接上断开处理函数 ,bt->value=reason
log_info("-----------bt_hci_event_handler reason %x %x", bt->event, bt->value);
switch (bt->event) {
case HCI_EVENT_INQUIRY_COMPLETE:
log_info(" HCI_EVENT_INQUIRY_COMPLETE \n");
emitter_search_stop_handle(bt->value);
UI_MSG_POST("bt_emitter_status:hci_event=%4", bt->event);
break;
case HCI_EVENT_CONNECTION_COMPLETE:
UI_MSG_POST("bt_emitter_status:hci_value=%4", bt->value);
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
#if !TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
UI_MSG_POST("bt_emitter_status:hci_event=%4", bt->event);
#else
UI_MSG_POST("bt_emitter_status:hci_event=%4:hci_value=%4", bt->event, bt->value);
#endif
break;
}
return 0;
}
static int bt_emitter_hci_msg_handler(int *msg)
{
struct bt_event *event = (struct bt_event *)msg;
bt_emitter_hci_event_handler(event);
return 0;
}
APP_MSG_HANDLER(emitter_hci_msg_handler) = {
.owner = 0xff,
.from = MSG_FROM_BT_HCI,
.handler = bt_emitter_hci_msg_handler,
};
static int bt_emitter_app_msg_handler(int *msg)
{
struct file_player *file_player = NULL;
switch (msg[0]) {
case APP_MSG_BT_EMITTER_PLAY:
#if TCFG_APP_MUSIC_EN
file_player = get_music_file_player();
if (music_file_get_player_status(file_player) != FILE_PLAYER_START) {
app_send_message(APP_MSG_MUSIC_PP, 0);
}
#endif
bt_emitter_pp(1);
break;
case APP_MSG_BT_EMITTER_PAUSE:
#if TCFG_APP_MUSIC_EN
file_player = get_music_file_player();
if (music_file_get_player_status(file_player) == FILE_PLAYER_START) {
app_send_message(APP_MSG_MUSIC_PP, 0);
}
#endif
bt_emitter_pp(0);
break;
default:
break;
}
return 0;
}
APP_MSG_HANDLER(bt_emitter_app_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_APP,
.handler = bt_emitter_app_msg_handler,
};
#endif
+570
View File
@@ -0,0 +1,570 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_event_func.data.bss")
#pragma data_seg(".bt_event_func.data")
#pragma const_seg(".bt_event_func.text.const")
#pragma code_seg(".bt_event_func.text")
#endif
#include "classic/hci_lmp.h"
#include "btstack/btstack_task.h"
#include "btstack/avctp_user.h"
#include "app_main.h"
#include "app_testbox.h"
#include "tone_player.h"
#include "clock_manager/clock_manager.h"
#include "audio_config.h"
#include "audio_cvp.h"
#if TCFG_AUDIO_ANC_ENABLE
#include "audio_anc.h"
#endif/*TCFG_AUDIO_ANC_ENABLE*/
#include "battery_manager.h"
#include "bt_common.h"
#if TCFG_USER_TWS_ENABLE
#include "bt_tws.h"
#endif
#include "bt_event_func.h"
#include "ui_api.h"
#if TCFG_APP_BT_EN
/*************************************************************
此文件函数主要是蓝牙模式各种状态处理
蓝牙播歌通话各种状态处理
蓝牙协议栈事件处理
**************************************************************/
u8 get_bt_init_status()
{
return g_bt_hdl.init_ok;
}
/*************************************************************************************************/
/*!
* \brief 蓝牙连接配置,提供app层用户可以输入配对鉴定key
*
* \param key :配对需要输入的数字
*
* \return
*
* \note 配对需要输入6位数字的时候,按照顺序从左到右一个个输入
*/
/*************************************************************************************************/
void bt_send_keypress(u8 key)
{
printf("bt_send_keypress:%d", key);
bt_cmd_prepare(USER_CTRL_KEYPRESS, 1, &key);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙连接配置,提供app层用户可以输入确定或者否定
*
* \param en 0:否定 1:确定
*
* \return
*
* \note 在连接过程中类似手机弹出 确定和否定 按键,可以供用户界面设置
*/
/*************************************************************************************************/
void bt_send_pair(u8 en)
{
bt_cmd_prepare(USER_CTRL_PAIR, 1, &en);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙获取vm连接记录信息
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_init_ok_search_index(void)
{
if (bt_get_current_poweron_memory_search_index(g_bt_hdl.auto_connection_addr)) {
printf("bt_wait_connect_and_phone_connect_switch\n");
bt_clear_current_poweron_memory_search_index(1);
app_send_message(APP_MSG_BT_GET_CONNECT_ADDR, 0);
}
}
/*************************************************************************************************/
/*!
* \brief 蓝牙初始化完成
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_status_init_ok(void)
{
g_bt_hdl.init_ok = 1;
#if TCFG_NORMAL_SET_DUT_MODE
printf("edr set dut mode\n");
bredr_set_dut_enble(1, 1);
#if TCFG_USER_BLE_ENABLE
printf("ble set dut mode\n");
extern void ble_standard_dut_test_init(void);
ble_standard_dut_test_init();
return;
#endif
#endif
#if (TCFG_USER_BLE_ENABLE || TCFG_BT_BLE_ADV_ENABLE)
if (BT_MODE_IS(BT_BQB)) {
ble_bqb_test_thread_init();
} else {
bt_ble_init();
}
#endif
#if (BT_AI_SEL_PROTOCOL & (RCSP_MODE_EN | GFPS_EN | MMA_EN | FMNA_EN | REALME_EN | SWIFT_PAIR_EN | DMA_EN | ONLINE_DEBUG_EN | CUSTOM_DEMO_EN))
void multi_protocol_bt_init(void);
multi_protocol_bt_init();
#endif
bt_init_ok_search_index();
#if ((CONFIG_BT_MODE == BT_BQB)||(CONFIG_BT_MODE == BT_PER))
return;
#endif
#if TCFG_TWS_INIT_AFTER_POWERON_TONE_PLAY_END
if (tone_player_runing()) {
return;
}
#endif
#if TCFG_USER_TWS_ENABLE
bt_tws_poweron();
#endif
}
/*----------------------------------------------------------------------------*/
/**@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) {
printf("remote_name fail \n");
} else {
printf("remote_name : %s \n", name);
}
put_buf(addr, 6);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙歌曲信息获取回调
@param
@return
@note
const u8 more_avctp_cmd_support = 1;置上1
需要在void bredr_handle_register()注册回调函数
要动态获取播放时间的,可以发送USER_CTRL_AVCTP_OPID_GET_PLAY_TIME命令就可以了
要半秒或者1秒获取就做个定时发这个命令
*/
/*----------------------------------------------------------------------------*/
static bt_lrc_cb_t lrc_cb = NULL;
static int pow(int x, int y)
{
u8 i;
int ret = 1;
for (i = 0; i < y; i++) {
ret *= x;
}
return ret;
}
void bt_register_lyric_callback(bt_lrc_cb_t cb)
{
lrc_cb = cb;
}
static void ms_to_time(u8 *info, u16 len)
{
//毫秒转换成分:秒
u32 time = 0;
u16 cnt;
for (cnt = 0; cnt < len; cnt ++) {
time += (info[len - 1 - cnt] - '0') * pow(10, cnt);
}
printf("music_time: %02d : %02d", time / 1000 / 60, (time % 60000) / 1000);
}
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) && (type != 7)) {
printf(" %s \n", info);
}
if (type == 7) {
ms_to_time(info, len);
}
if (time != 0) {
min = time / 1000 / 60;
sec = time / 1000 - (min * 60);
printf(" time %02d : %02d\n ", min, sec);
}
if (lrc_cb) {
lrc_cb(type, time, info, len);
}
}
static void bt_music_player_time_deal(void *priv)
{
if (BT_STATUS_PLAYING_MUSIC == bt_get_connect_status()) {
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_GET_PLAY_TIME, 0, NULL);
}
}
//播歌时配置为1
void bt_music_player_time_timer_deal(u8 en)
{
#if TCFG_BT_MUSIC_INFO_ENABLE
if (en) {
if (g_bt_hdl.get_music_player_timer == 0) {
g_bt_hdl.get_music_player_timer = sys_timer_add(NULL, bt_music_player_time_deal, 800);
}
} else {
if (g_bt_hdl.get_music_player_timer) {
sys_timer_del(g_bt_hdl.get_music_player_timer);
g_bt_hdl.get_music_player_timer = 0;
}
}
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙spp 协议数据 回调
@param packet_type:数据类型
ch :区分spp链路的连接号
packet :数据缓存
size :数据长度
@return
@note
*/
/*----------------------------------------------------------------------------*/
void spp_data_handler(u8 packet_type, u16 ch, u8 *packet, u16 size)
{
switch (packet_type) {
case 1:
printf("---spp connect:%x\n", ch);
break;
case 2:
printf("---spp disconnect:%x\n", ch);
break;
case 7:
//puts("spp_rx:");
//put_buf(packet,size);
#if AEC_DEBUG_ONLINE
aec_debug_online(packet, size);
#endif
#if TCFG_USER_RSSI_TEST_EN
int spp_get_rssi_handler(u8 * packet, u16 size);
spp_get_rssi_handler(packet, size);
#endif
break;
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙获取样机当前电量
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
int bt_get_battery_value()
{
//取消默认蓝牙定时发送电量给手机,需要更新电量给手机使用USER_CTRL_HFP_CMD_UPDATE_BATTARY命令
/*电量协议的是0-9个等级,请比例换算*/
return get_cur_battery_level();
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙快速测试
@param
@return
@note 样机和蓝牙测试盒链接开启快速测试,开启mic扩音功能,
按键就播放按键音来检测硬件是否焊接正常
*/
/*----------------------------------------------------------------------------*/
void bt_fast_test_api(void)
{
/*
* 进入快速测试模式,用户根据此标志判断测试,
* 如测试按键-开按键音 、测试mic-开扩音 、
* 根据fast_test_mode根据改变led闪烁方式、关闭可发现可连接
*/
puts("------------bt_fast_test_api---------\n");
if (g_bt_hdl.fast_test_mode == 0) {
g_bt_hdl.fast_test_mode = 1;
audio_fast_mode_test();
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙模式样机被测试仪链接上的回调函数,把其他状态关闭
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_dut_api(u8 param)
{
printf("bt in dut \n");
sys_auto_shut_down_disable();
#if TCFG_USER_TWS_ENABLE
tws_cancle_all_noconn() ;
#endif
if (g_bt_hdl.auto_connection_timer) {
sys_timeout_del(g_bt_hdl.auto_connection_timer);
g_bt_hdl.auto_connection_timer = 0;
}
#if TCFG_BT_BLE_ADV_ENABLE
#if (CONFIG_BT_MODE == BT_NORMAL)
bt_ble_adv_enable(0);
#endif
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙模式进入定频状态
@param
@return
@note 量产的时候可以通过按键等来触发进入定频状态,这时候蓝牙会在一个通道里
发送信号,可以通过设置下面变量来设置定频的频点
const int config_bredr_fcc_fix_fre = 0;
*/
/*----------------------------------------------------------------------------*/
void bt_fix_fre_api(u8 fre)
{
bt_dut_api(0);
bit_clr_ie(IRQ_BREDR_IDX);
bit_clr_ie(IRQ_BT_CLKN_IDX);
bredr_fcc_init(BT_FRE, fre);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙模式进入定频测试接收发射
@param mode 0 测试发射 1:测试接收
mac_addr:测试设置的地址
fre:定频的频点 0=2402 1=2403
packet_type:数据包类型
#define DH1_1 0
#define DH3_1 1
#define DH5_1 2
#define DH1_2 3
#define DH3_2 4
#define DH5_2 5
payload:数据包内容 0x0000 0x0055 0x00aa 0x00ff
0xffff:prbs9
payload_len:数据包长度,不可以超过包类型最大长度,0:底层按照最大包发送
pwr 发送功率
@return
@note 量产的时候通过串口,发送设置的参数,设置发送接收的参数
关闭定频接收发射测试
void link_fix_txrx_disable();
更新接收结果
void bt_updata_fix_rx_result()
struct link_fix_rx_result {
u32 rx_err_b; //接收到err bit
u32 rx_sum_b; //接收到正确bit
u32 rx_perr_p; //接收到crc 错误 包数
u32 rx_herr_p; //接收到crc 以外其他错误包数
u32 rx_invail_p; //接收到crc错误bit太多的包数,丢弃不统计到err bit中
};*/
/*----------------------------------------------------------------------------*/
void bt_fix_txrx_api(u8 mode, u8 *mac_addr, u8 fre, u8 packet_type, u16 payload)
{
bt_dut_api(0);
local_irq_disable();
link_fix_txrx_disable();
if (mode) {
link_fix_rx_enable(mac_addr, fre, packet_type, 0xffff, 0, 9);
} else {
link_fix_tx_enable(mac_addr, fre, packet_type, 0xffff, 0, 9);
}
local_irq_enable();
}
void bt_updata_fix_rx_result()
{
struct link_fix_rx_result fix_rx_result;
link_fix_rx_update_result(&fix_rx_result);
printf("err_b:%d sum_b:%d perr:%d herr_b:%d invaile:%d \n",
fix_rx_result.rx_err_b,
fix_rx_result.rx_sum_b,
fix_rx_result.rx_perr_p,
fix_rx_result.rx_herr_p,
fix_rx_result.rx_invail_p
);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙event 退出dut模式
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_bredr_exit_dut_mode()
{
bredr_set_dut_enble(0, 1);
clock_free("DUT");
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙event 搜索结束
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_inquiry(struct bt_event *bt)
{
#if TCFG_USER_EMITTER_ENABLE
/* if (g_bt_hdl.emitter_or_receiver == BT_EMITTER_EN) { */
//以后扩展,暂时注释
//emitter_search_stop();
/* } */
#endif
}
void bt_discovery_and_connectable_using_loca_mac_addr(u8 inquiry_scan_en, u8 page_scan_en)
{
u8 local_addr[6];
bt_get_vm_mac_addr(local_addr);
lmp_hci_write_local_address(local_addr);
if (page_scan_en) {
bt_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
}
if (inquiry_scan_en) {
bt_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙event链接断开,实际流程处理位于dual_conn.c中,此处预留做状态更新
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_disconnect(struct bt_event *bt)
{
if (app_var.goto_poweroff_flag) {
return;
}
printf("<<<<<<<<<<<<<<total_dev: %d>>>>>>>>>>>>>\n", bt_get_total_connect_dev());
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_ex_enter_dut_flag()) {
bt_discovery_and_connectable_using_loca_mac_addr(1, 1);
return;
}
if (testbox_get_status()) {
bt_discovery_and_connectable_using_loca_mac_addr(0, 1);
return;
}
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙event 链接超时
@param
@return
@note 回链超时内没有连接上设备
*/
/*----------------------------------------------------------------------------*/
void bt_hci_event_connection_timeout(struct bt_event *bt)
{
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_ex_enter_dut_flag()) {
bt_discovery_and_connectable_using_loca_mac_addr(1, 1);
return;
}
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙event 获取sco状态
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
u8 bt_sco_state(void)
{
return g_bt_hdl.phone_call_dec_begin;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙weak函数重新定义,蓝牙获取到的电话本信息反馈给用户层
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_phonebook_packet_handler(u8 type, const u8 *name, const u8 *number, const u8 *date)
{
static u16 number_cnt = 0;
printf("NO.%d:", number_cnt);
number_cnt++;
printf("type:%d ", type);
if (type == 0xff) {
number_cnt = 0;
}
if (name) {
printf(" NAME:%s ", name);
}
if (number) {
printf("number:%s ", number);
}
if (date) {
printf("date:%s ", date);
}
}
#endif /* #if TCFG_APP_BT_EN */
+426
View File
@@ -0,0 +1,426 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_key_func.data.bss")
#pragma data_seg(".bt_key_func.data")
#pragma const_seg(".bt_key_func.text.const")
#pragma code_seg(".bt_key_func.text")
#endif
#include "btstack/avctp_user.h"
#include "key_driver.h"
#include "audio_manager.h"
#include "vol_sync.h"
#include "app_main.h"
#include "audio_config.h"
#include "bt_key_func.h"
#include "ui/ui_api.h"
#include "ui_manage.h"
#include "bt_event_func.h"
#include "app_tone.h"
#include "app_common.h"
#if TCFG_APP_BT_EN
/*************************************************************************************************/
/*!
* \brief 音量加
*
* \param [in]
*
* \return
*
* \note 加音量
*/
/*************************************************************************************************/
void volume_up(void)
{
u8 test_box_vol_up = 0x41;
s8 cur_vol = 0;
u8 call_status = bt_get_call_status();
if ((tone_player_runing() || ring_player_runing())) {
if (bt_get_call_status() == BT_CALL_INCOMING) {
volume_up_down_direct(1);
}
return;
}
/*打电话出去彩铃要可以调音量大小*/
if ((call_status == BT_CALL_ACTIVE) || (call_status == BT_CALL_OUTGOING)) {
cur_vol = app_audio_get_volume(APP_AUDIO_STATE_CALL);
} else {
cur_vol = app_audio_get_volume(APP_AUDIO_STATE_MUSIC);
}
if (bt_get_remote_test_flag()) {
bt_cmd_prepare(USER_CTRL_TEST_KEY, 1, &test_box_vol_up); //音量加
}
if (cur_vol >= app_audio_get_max_volume()) {
audio_event_to_user(AUDIO_EVENT_VOL_MAX); //触发vol max事件
#if TCFG_MAX_VOL_PROMPT
play_tone_file(get_tone_files()->max_vol);
#endif
if (bt_get_call_status() != BT_CALL_HANGUP) {
/*本地音量最大,如果手机音量还没最大,继续加,以防显示不同步*/
if (g_bt_hdl.phone_vol < 15) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_UP, 0, NULL);
}
return;
}
#if TCFG_BT_VOL_SYNC_ENABLE
if (bt_get_call_status() == BT_CALL_HANGUP) {
opid_play_vol_sync_fun(&app_var.music_volume, 1);
bt_cmd_prepare(USER_CTRL_CMD_SYNC_VOL_INC, 0, NULL);
}
#endif/* TCFG_BT_VOL_SYNC_ENABLE */
return;
}
#if TCFG_BT_VOL_SYNC_ENABLE
if (bt_get_call_status() == BT_CALL_HANGUP) {
opid_play_vol_sync_fun(&app_var.music_volume, 1);
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, app_var.music_volume, 1);
}
#else
if (app_audio_get_state() == APP_AUDIO_STATE_IDLE) {
app_audio_state_switch(APP_AUDIO_STATE_MUSIC, app_audio_volume_max_query(AppVol_BT_MUSIC), NULL);
}
app_audio_volume_up(1);
#endif/*TCFG_BT_VOL_SYNC_ENABLE*/
printf("vol+: %d", app_audio_get_volume(APP_AUDIO_CURRENT_STATE));
if (bt_get_call_status() != BT_CALL_HANGUP) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_UP, 0, NULL);
} else {
#if TCFG_BT_VOL_SYNC_ENABLE
bt_cmd_prepare(USER_CTRL_CMD_SYNC_VOL_INC, 0, NULL);
#endif
}
}
/*************************************************************************************************/
/*!
* \brief 音量减
*
* \param [in]
*
* \return
*
* \note 减音量
*/
/*************************************************************************************************/
void volume_down(void)
{
u8 test_box_vol_down = 0x42;
if ((tone_player_runing() || ring_player_runing())) {
if (bt_get_call_status() == BT_CALL_INCOMING) {
volume_up_down_direct(-1);
}
return;
}
if (bt_get_remote_test_flag()) {
bt_cmd_prepare(USER_CTRL_TEST_KEY, 1, &test_box_vol_down); //音量减
}
if (app_audio_get_volume(APP_AUDIO_CURRENT_STATE) <= 0) {
audio_event_to_user(AUDIO_EVENT_VOL_MIN); //触发vol mix事件
if (bt_get_call_status() != BT_CALL_HANGUP) {
/*
*本地音量最小,如果手机音量还没最小,继续减
*注意:有些手机通话最小音量是1(GREE G0245D)
*/
if (g_bt_hdl.phone_vol > 1) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_DOWN, 0, NULL);
}
return;
}
#if TCFG_BT_VOL_SYNC_ENABLE
if (bt_get_call_status() == BT_CALL_HANGUP) {
opid_play_vol_sync_fun(&app_var.music_volume, 0);
bt_cmd_prepare(USER_CTRL_CMD_SYNC_VOL_DEC, 0, NULL);
}
#endif
return;
}
#if TCFG_BT_VOL_SYNC_ENABLE
if (bt_get_call_status() == BT_CALL_HANGUP) {
opid_play_vol_sync_fun(&app_var.music_volume, 0);
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, app_var.music_volume, 1);
}
#else
if (app_audio_get_state() == APP_AUDIO_STATE_IDLE) {
app_audio_state_switch(APP_AUDIO_STATE_MUSIC, app_audio_volume_max_query(AppVol_BT_MUSIC), NULL);
}
app_audio_volume_down(1);
#endif/*TCFG_BT_VOL_SYNC_ENABLE*/
printf("vol-: %d", app_audio_get_volume(APP_AUDIO_CURRENT_STATE));
if (bt_get_call_status() != BT_CALL_HANGUP) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_DOWN, 0, NULL);
} else {
#if TCFG_BT_VOL_SYNC_ENABLE
/* opid_play_vol_sync_fun(&app_var.music_volume, 0); */
if (app_audio_get_volume(APP_AUDIO_CURRENT_STATE) == 0) {
app_audio_volume_down(0);
}
bt_cmd_prepare(USER_CTRL_CMD_SYNC_VOL_DEC, 0, NULL);
#endif
}
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 pp 按键处理
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_music_pp(void)
{
if ((bt_get_call_status() == BT_CALL_OUTGOING) ||
(bt_get_call_status() == BT_CALL_ALERT)) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
} else if (bt_get_call_status() == BT_CALL_INCOMING) {
#if TCFG_BT_CALL_PHONE_BY_WATCH
set_bt_esco_by_watch(1);
#endif
bt_cmd_prepare(USER_CTRL_HFP_CALL_ANSWER, 0, NULL);
} else if (bt_get_call_status() == BT_CALL_ACTIVE) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
} else {
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL);
}
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 prev 按键处理
*
* \param [in]
*
* \return
*
* \note 播放音乐上一曲
*/
/*************************************************************************************************/
void bt_key_music_prev(void)
{
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PREV, 0, NULL);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 next 按键处理
*
* \param [in]
*
* \return
*
* \note 播放音乐下一曲
*/
/*************************************************************************************************/
void bt_key_music_next(void)
{
if (bt_get_call_status() == BT_CALL_INCOMING) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
return;
}
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_NEXT, 0, NULL);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 vol up 按键处理
*
* \param [in]
*
* \return
*
* \note 加音量
*/
/*************************************************************************************************/
void bt_key_vol_up(void)
{
u8 vol;
u8 call_status;
if (bt_get_call_status() == BT_CALL_ACTIVE && bt_sco_state() == 0) {
return;
}
volume_up();
call_status = bt_get_call_status();
if ((call_status == BT_CALL_ACTIVE) || (call_status == BT_CALL_OUTGOING)) {
vol = app_audio_get_volume(APP_AUDIO_STATE_CALL);
} else {
vol = app_audio_get_volume(APP_AUDIO_STATE_MUSIC);
}
printf("music_vol:vol=%d, state:%d", vol, app_audio_get_state());
app_send_message(APP_MSG_VOL_CHANGED, vol);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 vol down 按键处理
*
* \param [in]
*
* \return
*
* \note 减音量
*/
/*************************************************************************************************/
void bt_key_vol_down(void)
{
u8 vol;
u8 call_status;
if (bt_get_call_status() == BT_CALL_ACTIVE && bt_sco_state() == 0) {
return;
}
volume_down();
call_status = bt_get_call_status();
if ((call_status == BT_CALL_ACTIVE) || (call_status == BT_CALL_OUTGOING)) {
vol = app_audio_get_volume(APP_AUDIO_STATE_CALL);
} else {
vol = app_audio_get_volume(APP_AUDIO_STATE_MUSIC);
}
printf("music_vol:vol=%d, state:%d", vol, app_audio_get_state());
app_send_message(APP_MSG_VOL_CHANGED, vol);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 回拨最后一个号码 来电拒听
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_call_last_on(void)
{
if (bt_get_call_status() == BT_CALL_INCOMING) {
bt_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
return;
}
if ((bt_get_call_status() == BT_CALL_ACTIVE) ||
(bt_get_call_status() == BT_CALL_OUTGOING) ||
(bt_get_call_status() == BT_CALL_ALERT) ||
(bt_get_call_status() == BT_CALL_INCOMING)) {
return;//通话过程不允许回拨
}
if (g_bt_hdl.last_call_type == BT_STATUS_PHONE_INCOME) {
bt_cmd_prepare(USER_CTRL_HFP_DIAL_NUMBER, g_bt_hdl.income_phone_len,
g_bt_hdl.income_phone_num);
} else {
bt_cmd_prepare(USER_CTRL_HFP_CALL_LAST_NO, 0, NULL);
}
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 通话挂断
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_call_hang_up(void)
{
bt_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 siri开启
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_call_siri(void)
{
bt_cmd_prepare(USER_CTRL_HFP_GET_SIRI_OPEN, 0, NULL);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 hid 发起拍照命令
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_hid_control(void)
{
/* log_info("bt_get_curr_channel_state:%x\n", bt_get_curr_channel_state()); */
if (bt_get_curr_channel_state() & HID_CH) {
printf("KEY_HID_CONTROL\n");
bt_cmd_prepare(USER_CTRL_HID_IOS, 0, NULL);
}
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 三方通话 挂断当前去听另一个(未接听或者在保留状态都可以)
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_call_three_way_answer1(void)
{
bt_cmd_prepare(USER_CTRL_HFP_THREE_WAY_ANSWER1, 0, NULL);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 三方通话 保留当前去接听, 或者用于两个通话的切换
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_call_three_way_answer2(void)
{
bt_cmd_prepare(USER_CTRL_HFP_THREE_WAY_ANSWER2, 0, NULL);
}
/*************************************************************************************************/
/*!
* \brief 蓝牙模式 通话声卡切换
*
* \param [in]
*
* \return
*
* \note
*/
/*************************************************************************************************/
void bt_key_call_switch(void)
{
if (bt_get_call_status() == BT_CALL_ACTIVE) {
bt_cmd_prepare(USER_CTRL_SCO_LINK, 0, NULL);
}
}
#endif /* #if TCFG_APP_BT_EN */
+287
View File
@@ -0,0 +1,287 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_key_msg_table.data.bss")
#pragma data_seg(".bt_key_msg_table.data")
#pragma const_seg(".bt_key_msg_table.text.const")
#pragma code_seg(".bt_key_msg_table.text")
#endif
#include "key_driver.h"
#include "app_main.h"
#include "init.h"
#if TCFG_APP_BT_EN
#if TCFG_ADKEY_ENABLE
//短按 //长按 //hold i
//长按抬起 //双击 //三击
#if (CONFIG_UI_STYLE != STYLE_JL_SOUNDBOX)
const int key_bt_ad_num0_msg_table[KEY_ACTION_MAX] = {
APP_MSG_CHANGE_MODE, APP_MSG_KEY_POWER_OFF, APP_MSG_KEY_POWER_OFF_HOLD,
APP_MSG_KEY_POWER_OFF_RELEASE, APP_MSG_MIC_EFFECT_ON_OFF, APP_MSG_VOCAL_REMOVE,
};
const int key_bt_ad_num1_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_PP, APP_MSG_CALL_HANGUP, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_CALL_LAST_NO, APP_MSG_TWS_START_REMOVE_PAIR,
};
const int key_bt_ad_num2_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_NEXT, APP_MSG_VOL_UP, APP_MSG_VOL_UP,
APP_MSG_NULL, APP_MSG_OPEN_SIRI, APP_MSG_CALL_SWITCH,
};
const int key_bt_ad_num3_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_PREV, APP_MSG_VOL_DOWN, APP_MSG_VOL_DOWN,
APP_MSG_NULL, APP_MSG_CALL_THREE_WAY_ANSWER1, APP_MSG_NULL,
};
const int key_bt_ad_num4_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_CALL_THREE_WAY_ANSWER2, APP_MSG_NULL,
};
const int key_bt_ad_num5_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_SWITCH_SOUND_EFFECT, APP_MSG_NULL,
};
const int key_bt_ad_num6_msg_table[KEY_ACTION_MAX] = {
APP_MSG_SWITCH_MIC_EFFECT, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_MIC_EFFECT_ON_OFF, APP_MSG_NULL,
};
const int key_bt_ad_num7_msg_table[KEY_ACTION_MAX] = {
APP_MSG_VOCAL_REMOVE, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num8_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MIC_VOL_UP, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num9_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MIC_VOL_DOWN, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
#else /*LCD按键*/
const int key_bt_ad_num0_msg_table[KEY_ACTION_MAX] = {
APP_MSG_CHANGE_MODE, APP_MSG_KEY_POWER_OFF, APP_MSG_KEY_POWER_OFF_HOLD,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num1_msg_table[KEY_ACTION_MAX] = {
APP_MSG_LCD_OK, APP_MSG_LCD_MENU, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num2_msg_table[KEY_ACTION_MAX] = {
APP_MSG_LCD_DOWN, APP_MSG_LCD_VOL_DEC, APP_MSG_LCD_VOL_DEC,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num3_msg_table[KEY_ACTION_MAX] = {
APP_MSG_LCD_UP, APP_MSG_LCD_VOL_INC, APP_MSG_LCD_VOL_INC,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num4_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_LCD_MODE, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num5_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num6_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num7_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num8_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ad_num9_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
#endif
#endif
#if TCFG_IRKEY_ENABLE
//短按 //长按 //hold
//长按抬起 //双击 //三击
const int key_bt_ir_num0_msg_table[KEY_ACTION_MAX] = {
APP_MSG_KEY_POWER_OFF_INSTANTLY, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num1_msg_table[KEY_ACTION_MAX] = {
APP_MSG_CHANGE_MODE, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num2_msg_table[KEY_ACTION_MAX] = {
APP_MSG_SYS_MUTE, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num3_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_PP, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_OPEN_SIRI, APP_MSG_NULL,
};
const int key_bt_ir_num4_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_PREV, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num5_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_NEXT, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num6_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_CHANGE_EQ, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num7_msg_table[KEY_ACTION_MAX] = {
APP_MSG_VOL_DOWN, APP_MSG_VOL_DOWN, APP_MSG_VOL_DOWN,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num8_msg_table[KEY_ACTION_MAX] = {
APP_MSG_VOL_UP, APP_MSG_VOL_UP, APP_MSG_VOL_UP,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num9_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num10_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num11_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num12_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num13_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num14_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num15_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num16_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num17_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num18_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num19_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_ir_num20_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
#endif
#if TCFG_IOKEY_ENABLE
//短按 //长按 //hold
//长按抬起 //双击 //三击
const int key_bt_io_num0_msg_table[KEY_ACTION_MAX] = {
APP_MSG_JL_UI_HOME, APP_MSG_JL_UI_POWEROFF, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_io_num1_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_PP, APP_MSG_CALL_HANGUP, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_CALL_LAST_NO, APP_MSG_LOW_LANTECY,
};
const int key_bt_io_num2_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_NEXT, APP_MSG_VOL_UP, APP_MSG_VOL_UP,
APP_MSG_NULL, APP_MSG_OPEN_SIRI, APP_MSG_NULL,
};
const int key_bt_io_num3_msg_table[KEY_ACTION_MAX] = {
APP_MSG_MUSIC_PREV, APP_MSG_VOL_DOWN, APP_MSG_VOL_DOWN,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_io_num4_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_io_num5_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_io_num6_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_io_num7_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_io_num8_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
const int key_bt_io_num9_msg_table[KEY_ACTION_MAX] = {
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
APP_MSG_NULL, APP_MSG_NULL, APP_MSG_NULL,
};
#endif
const struct key_remap_table bt_mode_key_table[] = {
#if TCFG_ADKEY_ENABLE
{ .key_value = KEY_AD_NUM0, .remap_table = key_bt_ad_num0_msg_table },
{ .key_value = KEY_AD_NUM1, .remap_table = key_bt_ad_num1_msg_table },
{ .key_value = KEY_AD_NUM2, .remap_table = key_bt_ad_num2_msg_table },
{ .key_value = KEY_AD_NUM3, .remap_table = key_bt_ad_num3_msg_table },
{ .key_value = KEY_AD_NUM4, .remap_table = key_bt_ad_num4_msg_table },
{ .key_value = KEY_AD_NUM5, .remap_table = key_bt_ad_num5_msg_table },
{ .key_value = KEY_AD_NUM6, .remap_table = key_bt_ad_num6_msg_table },
{ .key_value = KEY_AD_NUM7, .remap_table = key_bt_ad_num7_msg_table },
{ .key_value = KEY_AD_NUM8, .remap_table = key_bt_ad_num8_msg_table },
{ .key_value = KEY_AD_NUM9, .remap_table = key_bt_ad_num9_msg_table },
#endif
#if TCFG_IRKEY_ENABLE
{ .key_value = KEY_IR_NUM0, .remap_table = key_bt_ir_num0_msg_table },
{ .key_value = KEY_IR_NUM1, .remap_table = key_bt_ir_num1_msg_table },
{ .key_value = KEY_IR_NUM2, .remap_table = key_bt_ir_num2_msg_table },
{ .key_value = KEY_IR_NUM3, .remap_table = key_bt_ir_num3_msg_table },
{ .key_value = KEY_IR_NUM4, .remap_table = key_bt_ir_num4_msg_table },
{ .key_value = KEY_IR_NUM5, .remap_table = key_bt_ir_num5_msg_table },
{ .key_value = KEY_IR_NUM6, .remap_table = key_bt_ir_num6_msg_table },
{ .key_value = KEY_IR_NUM7, .remap_table = key_bt_ir_num7_msg_table },
{ .key_value = KEY_IR_NUM8, .remap_table = key_bt_ir_num8_msg_table },
{ .key_value = KEY_IR_NUM9, .remap_table = key_bt_ir_num9_msg_table },
{ .key_value = KEY_IR_NUM10, .remap_table = key_bt_ir_num10_msg_table },
{ .key_value = KEY_IR_NUM11, .remap_table = key_bt_ir_num11_msg_table },
{ .key_value = KEY_IR_NUM12, .remap_table = key_bt_ir_num12_msg_table },
{ .key_value = KEY_IR_NUM13, .remap_table = key_bt_ir_num13_msg_table },
{ .key_value = KEY_IR_NUM14, .remap_table = key_bt_ir_num14_msg_table },
{ .key_value = KEY_IR_NUM15, .remap_table = key_bt_ir_num15_msg_table },
{ .key_value = KEY_IR_NUM16, .remap_table = key_bt_ir_num16_msg_table },
{ .key_value = KEY_IR_NUM17, .remap_table = key_bt_ir_num17_msg_table },
{ .key_value = KEY_IR_NUM18, .remap_table = key_bt_ir_num18_msg_table },
{ .key_value = KEY_IR_NUM19, .remap_table = key_bt_ir_num19_msg_table },
{ .key_value = KEY_IR_NUM20, .remap_table = key_bt_ir_num20_msg_table },
#endif
#if TCFG_IOKEY_ENABLE
{ .key_value = KEY_IO_WATCH_UPPER_LEFT, .remap_table = key_bt_io_num0_msg_table },
{ .key_value = KEY_IO_NUM1, .remap_table = key_bt_io_num1_msg_table },
{ .key_value = KEY_IO_NUM2, .remap_table = key_bt_io_num2_msg_table },
{ .key_value = KEY_IO_NUM3, .remap_table = key_bt_io_num3_msg_table },
{ .key_value = KEY_IO_NUM4, .remap_table = key_bt_io_num4_msg_table },
{ .key_value = KEY_IO_NUM5, .remap_table = key_bt_io_num5_msg_table },
{ .key_value = KEY_IO_NUM6, .remap_table = key_bt_io_num6_msg_table },
{ .key_value = KEY_IO_NUM7, .remap_table = key_bt_io_num7_msg_table },
{ .key_value = KEY_IO_NUM8, .remap_table = key_bt_io_num8_msg_table },
{ .key_value = KEY_IO_NUM9, .remap_table = key_bt_io_num9_msg_table },
#endif
{ .key_value = 0xff }
};
#endif /* #if TCFG_APP_BT_EN */
+300
View File
@@ -0,0 +1,300 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".bt_slience_detect.data.bss")
#pragma data_seg(".bt_slience_detect.data")
#pragma const_seg(".bt_slience_detect.text.const")
#pragma code_seg(".bt_slience_detect.text")
#endif
#include "system/includes.h"
#include "classic/tws_api.h"
#include "btstack/avctp_user.h"
#include "btstack/a2dp_media_codec.h"
#include "bt_slience_detect.h"
#include "bt_audio_energy_detection.h"
#include "app_config.h"
#include "app_main.h"
#if TCFG_APP_BT_EN
struct detect_handler {
u8 codec_type;
u8 unmute_packet_cnt;
u8 energy_check_stop;
u8 ingore_packet_num;
u8 bt_addr[6];
u16 ingore_to_seqn;
u16 slience_timer;
void *file;
};
static struct detect_handler *g_detect_hdl[2] = {NULL, NULL};
static struct detect_handler *get_detect_handler(u8 *bt_addr)
{
for (int i = 0; i < 2; i++) {
if (g_detect_hdl[i] && memcmp(g_detect_hdl[i]->bt_addr, bt_addr, 6) == 0) {
return g_detect_hdl[i];
}
}
return NULL;
}
static struct detect_handler *create_detect_handler()
{
for (int i = 0; i < 2; i++) {
if (!g_detect_hdl[i]) {
g_detect_hdl[i] = zalloc(sizeof(struct detect_handler));
return g_detect_hdl[i];
}
}
return NULL;
}
static void close_energy_detect(u8 codec_type)
{
for (int i = 0; i < 2; i++) {
if (g_detect_hdl[i] && g_detect_hdl[i]->codec_type == codec_type) { //判断要关闭的类型是否还在使用
return;
}
}
bt_audio_energy_detect_close(codec_type);//关闭对应类型的能量检测
}
static void a2dp_slience_detect(void *_detect)
{
int len;
struct a2dp_media_frame frame;
int seqn = -1;
struct detect_handler *detect = (struct detect_handler *)_detect;
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
return;
}
for (int i = 0; i < 2; i++) {
if (detect == g_detect_hdl[i]) {
goto __check;
}
}
return;
__check:
if (!detect->file) {
return;
}
while (1) {
len = a2dp_media_try_get_packet(detect->file, &frame);
if (len <= 0) {
break;
}
u8 *packet = frame.packet;
seqn = (packet[2] << 8) | packet[3];
/*
* 不检测,一直丢包
*/
#if 0//TCFG_A2DP_PREEMPTED_ENABLE == 0
seqn += 10;
if ((seqn & 0xffff) == 0) {
seqn = 1;
}
a2dp_media_free_packet(detect->file, packet);
break;
#endif
extern u8 bt_get_a2dp_en_status();
if (!bt_get_a2dp_en_status()) {
a2dp_media_free_packet(detect->file, packet);
detect->ingore_to_seqn = 0;
detect->unmute_packet_cnt = 0;
detect->energy_check_stop = 0;
break;
}
if (detect->ingore_to_seqn == 0) {
detect->ingore_to_seqn = seqn + detect->ingore_packet_num;
if (detect->ingore_to_seqn == 0) {
detect->ingore_to_seqn = 1;
}
a2dp_media_free_packet(detect->file, packet);
seqn = detect->ingore_to_seqn;
break;
}
//能量检测
int energy = 0;
int unmute_packet_num = 0;
if (detect->codec_type == A2DP_CODEC_SBC) { //20ms
energy = bt_audio_energy_detect_run(detect->codec_type, packet, len);
unmute_packet_num = TCFG_BT_BACKGROUND_DETECT_TIME / 20;
} else if (detect->codec_type == A2DP_CODEC_MPEG24) { //25ms
energy = bt_audio_energy_detect_run(detect->codec_type, packet, len);
unmute_packet_num = TCFG_BT_BACKGROUND_DETECT_TIME / 25;
} else if (detect->codec_type == A2DP_CODEC_LDAC) {
energy = bt_audio_energy_detect_run(detect->codec_type, packet, len);
unmute_packet_num = TCFG_BT_BACKGROUND_DETECT_TIME / 25;
}
printf("-energy: %d, %d, %d\n", seqn, energy, detect->unmute_packet_cnt);
if (energy >= 10) {
if (++detect->unmute_packet_cnt < unmute_packet_num) {
a2dp_media_free_packet(detect->file, packet);
continue;
}
} else {
if (energy >= 0) {
detect->unmute_packet_cnt >>= 1;
}
a2dp_media_free_packet(detect->file, packet);
continue;
}
a2dp_media_free_packet(detect->file, packet);
sys_timer_del(detect->slience_timer);
detect->slience_timer = 0;
seqn += 10;
if ((seqn & 0xffff) == 0) {
seqn = 1;
}
a2dp_media_clear_packet_before_seqn(detect->file, seqn);
printf("slience_detect_over: clear_to_seqn: %d\n", seqn);
a2dp_close_media_file(detect->file);
detect->file = NULL;
u8 codec_type = detect->codec_type;
if (detect->codec_type == A2DP_CODEC_MPEG24) {
detect->codec_type = 0xff;
}
close_energy_detect(codec_type);
int msg[4];
msg[0] = APP_MSG_BT_A2DP_START;
memcpy(msg + 1, detect->bt_addr, 6);
app_send_message_from(MSG_FROM_APP, 12, msg);
return;
}
if (seqn > 0) {
a2dp_media_clear_packet_before_seqn(detect->file, seqn);
}
}
void bt_start_a2dp_slience_detect(u8 *bt_addr, int ingore_packet_num)
{
void *file = a2dp_open_media_file(bt_addr);
if (!file) {
puts("open_a2dp_file_faild\n");
return;
}
struct detect_handler *detect = get_detect_handler(bt_addr);
if (!detect) {
detect = create_detect_handler();
if (!detect) {
a2dp_close_media_file(file);
return;
}
}
if (detect->slience_timer) {
sys_timer_del(detect->slience_timer);
}
detect->file = file;
detect->codec_type = a2dp_media_get_codec_type(detect->file);
detect->ingore_packet_num = ingore_packet_num;
detect->ingore_to_seqn = 0;
detect->unmute_packet_cnt = 0;
detect->energy_check_stop = 0;
memcpy(detect->bt_addr, bt_addr, 6);
detect->slience_timer = sys_timer_add(detect, a2dp_slience_detect, 80);
g_printf("bt_start_a2dp_slience_detect:");
put_buf(bt_addr, 6);
}
void bt_stop_a2dp_slience_detect(u8 *bt_addr)
{
struct detect_handler *detect;
u8 codec_type = 0;
for (int i = 0; i < 2; i++) {
detect = g_detect_hdl[i];
if (!detect) {
continue;
}
if (bt_addr && memcmp(detect->bt_addr, bt_addr, 6)) {
continue;
}
codec_type = g_detect_hdl[i]->codec_type;
g_detect_hdl[i] = NULL;
if (detect->slience_timer) {
sys_timer_del(detect->slience_timer);
detect->slience_timer = 0;
g_printf("bt_stop_a2dp_slience_detect");
}
if (detect->file) {
a2dp_close_media_file(detect->file);
detect->file = NULL;
}
free(detect);
detect = NULL;
}
close_energy_detect(codec_type);
}
void bt_reset_a2dp_slience_detect()
{
struct detect_handler *detect;
for (int i = 0; i < 2; i++) {
detect = g_detect_hdl[i];
if (!detect || detect->slience_timer == 0) {
return;
}
detect->ingore_to_seqn = 0;
detect->unmute_packet_cnt = 0;
detect->energy_check_stop = 0;
}
}
int bt_slience_detect_get_result(u8 *bt_addr)
{
struct detect_handler *detect = get_detect_handler(bt_addr);
if (!detect) {
return BT_SLIENCE_NO_DETECTING;
}
if (detect->unmute_packet_cnt) {
return BT_SLIENCE_HAVE_ENERGY;
}
return BT_SLIENCE_NO_ENERGY;
}
int bt_slience_get_detect_addr(u8 *bt_addr)
{
struct detect_handler *detect;
for (int i = 0; i < 2; i++) {
detect = g_detect_hdl[i];
if (!detect) {
continue;
}
memcpy(bt_addr, detect->bt_addr, 6);
return 1;
}
return 0;
}
#endif /* #if TCFG_APP_BT_EN */
+633
View File
@@ -0,0 +1,633 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".dual_conn.data.bss")
#pragma data_seg(".dual_conn.data")
#pragma const_seg(".dual_conn.text.const")
#pragma code_seg(".dual_conn.text")
#endif
#include "btstack/avctp_user.h"
#include "app_main.h"
#include "bt.h"
#include "app_config.h"
#include "user_cfg.h"
#include "bt_background.h"
#include "bt_event_func.h"
#include "btstack/third_party/rcsp/btstack_rcsp_user.h"
#if TCFG_APP_BT_EN
#if(TCFG_USER_TWS_ENABLE == 0)
#define MAX_PAGE_DEVICE_NUM 2
#define TIMEOUT_CONN_DEVICE_OPEN_PAGE 1 //第二台设备超时断开回连一直开启page
static void page_next_device(void *p);
extern u8 get_role_type_by_addr(u8 *addr);
extern u8 check_conn_by_addr(u8 *addr);
struct page_device_info {
struct list_head entry;
u32 timeout;
u16 timer;
u8 mac_addr[6];
};
struct dual_conn_handle {
u16 timer;
u16 page_scan_timer;
u16 close_inquiry_scan_timer;
u8 device_num_recorded;
u8 remote_addr[3][6];
u8 remote_type[3];
u8 page_head_inited;
u8 page_scan_auto_disable;
u8 inquiry_scan_disable;
struct list_head page_head;
};
static struct dual_conn_handle g_dual_conn;
static u8 page_mode_active = 0;
static void dual_conn_page_device();
static bool page_list_empty()
{
return list_empty(&g_dual_conn.page_head);
}
static void auto_close_page_scan(void *p)
{
puts("auto_close_page_scan\n");
g_dual_conn.page_scan_timer = 0;
g_dual_conn.page_scan_auto_disable = 1;
lmp_hci_write_scan_enable((0 << 1) | 0);
}
static void write_scan_conn_enable(bool scan_enable, bool conn_enable)
{
if (g_dual_conn.page_scan_auto_disable) {
if (!scan_enable && conn_enable) {
return;
}
}
lmp_hci_write_scan_enable((conn_enable << 1) | scan_enable);
if ((scan_enable || conn_enable) && page_list_empty()) {
int connect_device = bt_get_total_connect_dev();
app_send_message(APP_MSG_BT_IN_PAIRING_MODE, connect_device);
}
#if TCFG_DUAL_CONN_PAGE_SCAN_TIME
if (conn_enable && !scan_enable) {
if (g_dual_conn.page_scan_timer) {
sys_timer_modify(g_dual_conn.page_scan_timer,
TCFG_DUAL_CONN_PAGE_SCAN_TIME * 1000);
} else {
g_dual_conn.page_scan_timer = sys_timeout_add(NULL, auto_close_page_scan,
TCFG_DUAL_CONN_PAGE_SCAN_TIME * 1000);
}
} else {
if (g_dual_conn.page_scan_timer) {
sys_timeout_del(g_dual_conn.page_scan_timer);
g_dual_conn.page_scan_timer = 0;
}
}
#endif
}
static void close_inquiry_scan(void *p)
{
g_dual_conn.inquiry_scan_disable = 1;
if (g_dual_conn.device_num_recorded == 1 && bt_get_total_connect_dev() == 1) {
write_scan_conn_enable(0, 0);
}
g_dual_conn.close_inquiry_scan_timer = 0;
}
static int dual_conn_try_open_inquiry_scan()
{
#if TCFG_DUAL_CONN_INQUIRY_SCAN_TIME
if (g_dual_conn.inquiry_scan_disable) {
return 0;
}
write_scan_conn_enable(1, 1);
#endif
return 1;
}
static int add_device_2_page_list(u8 *mac_addr, u32 timeout)
{
struct page_device_info *info;
printf("add_device_2_page_list: %d\n", timeout);
put_buf(mac_addr, 6);
if (!g_dual_conn.page_head_inited) {
return 0;
}
list_for_each_entry(info, &g_dual_conn.page_head, entry) {
if (memcmp(info->mac_addr, mac_addr, 6) == 0) {
if (info->timer) {
sys_timeout_del(info->timer);
info->timer = 0;
}
info->timeout = jiffies + msecs_to_jiffies(timeout);
__list_del_entry(&info->entry);
list_add_tail(&info->entry, &g_dual_conn.page_head);
return 1;
}
}
info = malloc(sizeof(*info));
ASSERT(info);
info->timer = 0;
info->timeout = jiffies + msecs_to_jiffies(timeout);
memcpy(info->mac_addr, mac_addr, 6);
list_add_tail(&info->entry, &g_dual_conn.page_head);
return 0;
}
static void del_device_from_page_list(u8 *mac_addr)
{
struct page_device_info *info;
if (!g_dual_conn.page_head_inited) {
return;
}
list_for_each_entry(info, &g_dual_conn.page_head, entry) {
if (memcmp(info->mac_addr, mac_addr, 6) == 0) {
puts("del_device\n");
put_buf(mac_addr, 6);
__list_del_entry(&info->entry);
if (info->timer) {
sys_timeout_del(info->timer);
}
free(info);
return;
}
}
}
static void clr_device_in_page_list()
{
struct page_device_info *info, *n;
if (!g_dual_conn.page_head_inited) {
return;
}
list_for_each_entry_safe(info, n, &g_dual_conn.page_head, entry) {
__list_del_entry(&info->entry);
if (info->timer) {
sys_timeout_del(info->timer);
}
free(info);
}
}
static u8 *get_device_addr_in_page_list()
{
struct page_device_info *info, *n;
list_for_each_entry_safe(info, n, &g_dual_conn.page_head, entry) {
return info->mac_addr;
}
return NULL;
}
static void dual_conn_state_handler()
{
int connect_device = bt_get_total_connect_dev();
int have_page_device = page_list_empty() ? false : true;
printf("page_state: %d, %d\n", connect_device, have_page_device);
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
if (connect_device == 0) {
#if TCFG_EDR_SCAN_CONN_CTRL
u8 rcsp_get_ble_disconnect_by_app_flag(void);
void rcsp_set_ble_disconnect_by_app_flag(u8 flag);
u8 ble_disconnect = rcsp_get_ble_disconnect_by_app_flag();
u8 bredr_state = is_bredr_close();
printf("%s ble_disconnect:%d is_bredr_close:%d", __func__, ble_disconnect, is_bredr_close());
if (is_bredr_close() == 0) {
if (ble_disconnect == 1) {
/*一键连接时候, 由app发指令断连*/
write_scan_conn_enable(0, 1);
} else {
write_scan_conn_enable(0, 0);
}
}
rcsp_set_ble_disconnect_by_app_flag(0);
#else
write_scan_conn_enable(1, 1);
#endif
} else if (connect_device == 1) {
#if TCFG_BT_DUAL_CONN_ENABLE
if (g_dual_conn.device_num_recorded > 1) {
write_scan_conn_enable(0, 1);
}
#endif
#if TCFG_USER_EMITTER_ENABLE
if (bt_emitter_get_curr_channel_state()) {
write_scan_conn_enable(0, 1);
}
#endif
}
}
static void dual_conn_page_device_timeout(void *p)
{
struct page_device_info *info;
if (!g_dual_conn.page_head_inited) {
return;
}
/* 参数有效性检查 */
list_for_each_entry(info, &g_dual_conn.page_head, entry) {
if (info == p) {
printf("page_device_timeout: %lu, %d\n", jiffies, info->timeout);
info->timer = 0;
list_del(&info->entry);
if (time_after(jiffies, info->timeout)) {
del_device_from_page_list(info->mac_addr);
free(info);
} else {
list_add_tail(&info->entry, &g_dual_conn.page_head);
}
bt_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
if (!page_list_empty()) {
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
g_dual_conn.timer = sys_timeout_add(NULL, page_next_device, 2000);
#if TCFG_EDR_SCAN_CONN_CTRL
bt_discovery_and_connectable_using_loca_mac_addr(0, 1);
#else
//增加2s可发现可连接
bt_discovery_and_connectable_using_loca_mac_addr(1, 1);
#endif
return;
}
page_mode_active = 0;
dual_conn_state_handler();
break;
}
}
}
static void dual_conn_page_device()
{
struct page_device_info *info, *n;
if (!g_dual_conn.page_head_inited) {
return;
}
list_for_each_entry_safe(info, n, &g_dual_conn.page_head, entry) {
if (info->timer) {
return;
}
printf("start_page_device: %lu, %d\n", jiffies, info->timeout);
put_buf(info->mac_addr, 6);
info->timer = sys_timeout_add(info, dual_conn_page_device_timeout,
TCFG_BT_PAGE_TIMEOUT * 1000);
bt_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, info->mac_addr);
page_mode_active = 1;
return;
}
dual_conn_state_handler();
}
static void dual_conn_page_devices_init()
{
u8 mac_addr[6];
INIT_LIST_HEAD(&g_dual_conn.page_head);
g_dual_conn.page_head_inited = 1;
g_dual_conn.page_scan_auto_disable = 0;
int num = btstack_get_num_of_remote_device_recorded();
for (int i = num - 1; i >= 0 && i + 2 >= num ; i--) {
btstack_get_remote_addr(mac_addr, i);
add_device_2_page_list(mac_addr, TCFG_BT_POWERON_PAGE_TIME * 1000);
}
g_dual_conn.device_num_recorded = num;
if (num == 1) {
memcpy(g_dual_conn.remote_addr[2], mac_addr, 6);
}
#if TCFG_DUAL_CONN_INQUIRY_SCAN_TIME
g_dual_conn.inquiry_scan_disable = 0;
g_dual_conn.close_inquiry_scan_timer = sys_timeout_add(NULL, close_inquiry_scan, TCFG_DUAL_CONN_INQUIRY_SCAN_TIME * 1000);
#else
g_dual_conn.inquiry_scan_disable = 1;
#endif
#if (TCFG_LP_NFC_TAG_ENABLE && TCFG_LP_NFC_TAG_TYPE == JL_BT_TAG)
static u8 nfc_wakeup_disable_page = 1;
if ((is_reset_source(MSYS_P2M_RST)) && (is_wakeup_source(PWR_WK_REASON_LPNFC)) && nfc_wakeup_disable_page) {
nfc_wakeup_disable_page = 0;
write_scan_conn_enable(1, 1);
} else { //非nfc唤醒
dual_conn_page_device();
}
#else
dual_conn_page_device();
#endif
}
static void page_next_device(void *p)
{
g_dual_conn.timer = 0;
dual_conn_page_device();
}
void dual_conn_user_bt_connect(u8 *addr)
{
add_device_2_page_list(addr, 0);
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
dual_conn_page_device();
}
static void dual_conn_bt_connect_timeout(struct bt_event *bt)
{
add_device_2_page_list(bt->args, TCFG_BT_TIMEOUT_PAGE_TIME * 1000);
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
dual_conn_page_device();
}
static int dual_conn_btstack_event_handler(int *_event)
{
struct bt_event *event = (struct bt_event *)_event;
switch (event->event) {
case BT_STATUS_INIT_OK:
puts("dual_conn BT_STATUS_INIT_OK");
dual_conn_page_devices_init();
#if (TCFG_BT_BACKGROUND_ENABLE)
bt_background_switch_mode_after_initializes();
#endif
return 0;
case BT_STATUS_FIRST_CONNECTED:
puts("dual_conn BT_STATUS_FIRST_CONNECTED");
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
del_device_from_page_list(event->args);
memcpy(g_dual_conn.remote_addr[0], event->args, 6);
if (!check_conn_by_addr(g_dual_conn.remote_addr[0])) {
printf("no conn!");
break;
}
g_dual_conn.remote_type[0] = get_role_type_by_addr(g_dual_conn.remote_addr[0]);
if (!page_list_empty()) {
g_dual_conn.timer = sys_timeout_add(NULL, page_next_device, 500);
return 0;
}
page_mode_active = 0;
if (g_dual_conn.device_num_recorded == 0) {
g_dual_conn.device_num_recorded++;
memcpy(g_dual_conn.remote_addr[2], event->args, 6);
break;
}
if (g_dual_conn.device_num_recorded == 1) {
if (memcmp(event->args, g_dual_conn.remote_addr[2], 6) == 0) {
break;
}
g_dual_conn.device_num_recorded++;
}
#if TCFG_BT_DUAL_CONN_ENABLE
write_scan_conn_enable(0, 1);
#else
#if !TCFG_USER_BLE_CTRL_BREDR_EN && TCFG_USER_EMITTER_ENABLE
if (get_role_type_by_addr(g_dual_conn.remote_addr[0]) == ROLE_EMITTER) {
write_scan_conn_enable(1, 1);
} else {
write_scan_conn_enable(0, 1);
}
#else
write_scan_conn_enable(0, 0);
#endif
#endif
break;
case BT_STATUS_SECOND_CONNECTED:
puts("dual_conn BT_STATUS_SECOND_CONNECTED");
if (g_dual_conn.device_num_recorded == 1) {
g_dual_conn.device_num_recorded++;
}
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
clr_device_in_page_list();
memcpy(g_dual_conn.remote_addr[1], event->args, 6);
if (!check_conn_by_addr(g_dual_conn.remote_addr[1])) {
printf("no conn!");
break;
}
g_dual_conn.remote_type[1] = get_role_type_by_addr(g_dual_conn.remote_addr[1]);
break;
}
return 0;
}
APP_MSG_HANDLER(dual_conn_stack_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = dual_conn_btstack_event_handler,
};
static int dual_conn_hci_event_handler(int *_event)
{
struct bt_event *event = (struct bt_event *)_event;
if (app_var.goto_poweroff_flag) {
return 0;
}
int is_remote_test = bt_get_remote_test_flag();
switch (event->event) {
case HCI_EVENT_VENDOR_NO_RECONN_ADDR:
break;
case HCI_EVENT_DISCONNECTION_COMPLETE :
if (event->value == ERROR_CODE_CONNECTION_TIMEOUT) {
printf("dual_conn ERROR_CODE_CONNECTION_TIMEOUT");
put_buf(event->args, 7);
if (is_remote_test == 0) {
dual_conn_bt_connect_timeout(event);
}
}
break;
case HCI_EVENT_CONNECTION_COMPLETE:
switch (event->value) {
case ERROR_CODE_SUCCESS :
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
del_device_from_page_list(event->args);
return 0;
case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR:
case ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED:
case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES:
if (!list_empty(&g_dual_conn.page_head)) {
struct page_device_info *info;
info = list_first_entry(&g_dual_conn.page_head,
struct page_device_info, entry);
list_del(&info->entry);
list_add_tail(&info->entry, &g_dual_conn.page_head);
}
break;
case ERROR_CODE_PIN_OR_KEY_MISSING:
case ERROR_CODE_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED :
case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION:
case ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST :
case ERROR_CODE_AUTHENTICATION_FAILURE :
break;
case ERROR_CODE_PAGE_TIMEOUT:
break;
case ERROR_CODE_CONNECTION_TIMEOUT:
printf("dual_conn ERROR_CODE_CONNECTION_TIMEOUT 2");
put_buf(event->args, 7);
dual_conn_bt_connect_timeout(event);
break;
case ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS :
if (is_remote_test == 0) {
add_device_2_page_list(event->args, TCFG_BT_TIMEOUT_PAGE_TIME * 1000);
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
dual_conn_page_device();
}
break;
default:
return 0;
}
break;
default:
return 0;
}
g_dual_conn.page_scan_auto_disable = 0;
for (int i = 0; i < 2; i++) {
if (memcmp(event->args, g_dual_conn.remote_addr[i], 6) == 0) {
memset(g_dual_conn.remote_addr[i], 0xff, 6);
g_dual_conn.remote_type[i] = 0;
}
}
dual_conn_state_handler();
return 0;
}
APP_MSG_HANDLER(dual_conn_hci_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_HCI,
.handler = dual_conn_hci_event_handler,
};
static void page_device_msg_handler()
{
u8 mac_addr[6];
struct page_device_info *info;
int device_num = bt_get_total_connect_dev();
if (!g_dual_conn.page_head_inited) {
return;
}
list_for_each_entry(info, &g_dual_conn.page_head, entry) {
device_num++;
}
if (device_num >= 2) {
return;
}
int num = btstack_get_num_of_remote_device_recorded();
for (int i = num - 1; i >= 0; i--) {
btstack_get_remote_addr(mac_addr, i);
if (memcmp(mac_addr, g_dual_conn.remote_addr[0], 6) == 0) {
continue;
}
if (memcmp(mac_addr, g_dual_conn.remote_addr[1], 6) == 0) {
continue;
}
int ret = add_device_2_page_list(mac_addr, TCFG_BT_POWERON_PAGE_TIME * 1000);
if (ret == 0) {
if (++device_num >= 2) {
break;
}
}
}
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
write_scan_conn_enable(0, 0);
dual_conn_page_device();
}
static int dual_conn_app_event_handler(int *msg)
{
switch (msg[0]) {
case APP_MSG_BT_PAGE_DEVICE:
page_device_msg_handler();
break;
}
return 0;
}
APP_MSG_HANDLER(dual_conn_app_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_APP,
.handler = dual_conn_app_event_handler,
};
void dual_conn_close()
{
if (g_dual_conn.timer) {
sys_timeout_del(g_dual_conn.timer);
g_dual_conn.timer = 0;
}
#if TCFG_DUAL_CONN_INQUIRY_SCAN_TIME
if (g_dual_conn.close_inquiry_scan_timer) {
sys_timeout_del(g_dual_conn.close_inquiry_scan_timer);
g_dual_conn.close_inquiry_scan_timer = 0;
}
#endif
clr_device_in_page_list();
write_scan_conn_enable(0, 0);
bt_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
}
bool check_page_mode_active(void)
{
return (page_mode_active) ? TRUE : FALSE;
}
#endif
#endif /* #if TCFG_APP_BT_EN */
@@ -0,0 +1,731 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".kws_voice_event_deal.data.bss")
#pragma data_seg(".kws_voice_event_deal.data")
#pragma const_seg(".kws_voice_event_deal.text.const")
#pragma code_seg(".kws_voice_event_deal.text")
#endif
#include "event.h"
#include "app_config.h"
#include "btstack/avctp_user.h"
#include "asr/kws_event.h"
#include "key_driver.h"
#include "app_msg.h"
#include "bt_key_func.h"
#include "ui/ui_api.h"
#include "jlui_app/ui_sys_param.h"
#include "app_mode_manager/app_mode_manager.h"
#include "app_task.h"
#include "esco_player.h"
#include "app_common.h"
#include "music/music_player.h"
#include "media/file_decoder.h"
#include "data_storage.h"
#include "audio_config.h"
#if TCFG_USER_TWS_ENABLE
#include "bt_tws.h"
#endif
#if TCFG_AUDIO_ANC_ENABLE
#include "audio_anc.h"
#endif/*TCFG_AUDIO_ANC_ENABLE*/
#define LOG_TAG "[KWS_VOICE_EVENT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if ((defined TCFG_KWS_VOICE_EVENT_HANDLE_ENABLE) && (TCFG_KWS_VOICE_EVENT_HANDLE_ENABLE))
#define KWS_CHECK_EVENT BIT(0)
#define KWS_CHECK_ID BIT(1)
#define KWS_CHECK_MODE BIT(2)
#define KWS_CHECK_BT BIT(3)
#define KWS_CHECK_PHONE_BT BIT(4)
#define KWS_CHECK_UI BIT(5)
#define KWS_EVENT_ERR_CHECK_EVENT (-1)
#define KWS_EVENT_ERR_CHECK_ID (-2)
#define KWS_EVENT_ERR_CHECK_MODE (-3)
#define KWS_EVENT_ERR_CHECK_BT (-4)
#define KWS_EVENT_ERR_CHECK_UI (-5)
#define KWS_EVENT_ERR_UI_SHOW (-6)
extern u8 is_bredr_close();
extern void bt_init_bredr();
extern void bredr_conn_last_dev();
extern void bt_close_bredr();
extern void set_call_log_type(u8 type);
extern int music_pp(void);
extern int music_prev(void);
extern int music_next(void);
extern void volume_up();
extern void volume_down();
extern void volume_set(u8 vol);
extern int watch_set_style(int style);
extern int watch_get_items_num();
extern char *watch_get_item(int style);
extern int watch_version_juge(char *watch_item);
extern int watch_get_style();
extern void kws_hold_time_enable(void);
extern int bt_must_work(void);
extern void music_set_start_auto_play(u8 on);
extern u8 create_control_by_menu_set(u8 en);
extern void ui_auto_shut_down_re_run(void);
extern void setting_write_UIInfo_to_vm(void *info);
extern void save_ui_info_to_vm();
static int kws_event_common_deal(u16 event, u32 id);
static int kws_event_app_list_deal(u16 event, u32 id);
static int kws_event_music_deal(u16 event, u32 id);
static int kws_event_call_deal(u16 event, u32 id);
static int kws_event_volume_deal(u16 event, u32 id);
static int kws_event_brightness_deal(u16 event, u32 id);
static int kws_event_bt_setting_deal(u16 event, u32 id);
static int kws_event_start_photos_deal(u16 event, u32 id);
static int kws_event_switch_dial_deal(u16 event, u32 id);
static int kws_event_switch_style_deal(u16 event, u32 id);
static int kws_event_ui_show_ID(u32 id, u8 checkid);
extern int UIInfo_w_vm_timer;
struct jl_kws_event_hdl {
u32 last_event;
u32 last_event_jiffies;
u32 last_ui_id;
};
static struct jl_kws_event_hdl kws_hdl = {
.last_event = 0,
.last_event_jiffies = 0,
.last_ui_id = 0,
};
#define __this (&kws_hdl)
struct jl_kws_event_ui_key {
u16 event; // 事件
u32 ui_id; // UI界面
int (*deal)(u16 event, u32 ui_id); // 执行处理
};
#if (defined(CONFIG_UI_STYLE_JL_PUBLIC_MODLS_ENABLE) || defined(CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE))
static const struct jl_kws_event_ui_key kws_event_tab[] = {
/*音乐关键词*/
{KWS_EVENT_PLAY_MUSIC, ID_WINDOW_MUSIC_PLAYER, kws_event_music_deal},
{KWS_EVENT_STOP_MUSIC, 0, kws_event_music_deal},
{KWS_EVENT_PAUSE_MUSIC, 0, kws_event_music_deal},
{KWS_EVENT_PREV_SONG, 0, kws_event_music_deal},
{KWS_EVENT_NEXT_SONG, 0, kws_event_music_deal},
/*通话关键词*/
{KWS_EVENT_CALL_ACTIVE, 0, kws_event_call_deal},
{KWS_EVENT_CALL_HANGUP, 0, kws_event_call_deal},
/*音量关键词*/
{KWS_EVENT_VOLUME_UP, 0, kws_event_volume_deal},
{KWS_EVENT_VOLUME_DOWN, 0, kws_event_volume_deal},
{KWS_EVENT_VOLUME_MUTE, 0, kws_event_volume_deal},
{KWS_EVENT_VOLUME_UNMUTE, 0, kws_event_volume_deal},
{KWS_EVENT_VOLUME_MAX, 0, kws_event_volume_deal},
/*亮度调整关键词*/
{KWS_EVENT_BRIGHTNESS_ALWAYS, 0, kws_event_brightness_deal},
{KWS_EVENT_BRIGHTNESS_UP, 0, kws_event_brightness_deal},
{KWS_EVENT_BRIGHTNESS_DOWN, 0, kws_event_brightness_deal},
{KWS_EVENT_BRIGHTNESS_AUTO, 0, kws_event_brightness_deal},
/*健康测量关键词*/
{KWS_EVENT_DETECTION_HEART, ID_WINDOW_HEART, kws_event_common_deal},
{KWS_EVENT_DETECTION_OXYGEN, ID_WINDOW_OXYGEN, kws_event_common_deal},
/*蓝牙应用关键词*/
{KWS_EVENT_OPEN_EDR, 0, kws_event_bt_setting_deal},
{KWS_EVENT_FIND_PHONE, ID_WINDOW_FINDPHONE, kws_event_common_deal},
{KWS_EVENT_START_PHOTOS, ID_WINDOW_PHOTOGRAGH, kws_event_common_deal},
/*表盘应用关键词*/
{KWS_EVENT_SWITCH_DIAL, ID_WINDOW_DIAL, kws_event_switch_dial_deal},
{KWS_EVENT_SWITCH_STYLE, 0, kws_event_switch_style_deal},
/*记录查看关键词*/
{KWS_EVENT_SEE_SPORT_RECORD, ID_WINDOW_SPORT_RESULT, kws_event_common_deal},
{KWS_EVENT_SEE_ACTION_RECORD, ID_WINDOW_MOMENTUM, kws_event_common_deal},
{KWS_EVENT_SEE_SLEEP_RECORD, ID_WINDOW_SLEEP, kws_event_common_deal},
{KWS_EVENT_SEE_CALL_REDORD, ID_WINDOW_PHONE, kws_event_common_deal},
{KWS_EVENT_SEE_TRAIN_RECORD, ID_WINDOW_SPORTING, kws_event_common_deal},
{KWS_EVENT_SEE_HEAT, ID_WINDOW_HEAT, kws_event_common_deal},
/*打开功能页面关键词*/
{KWS_EVENT_OPEN_SPORT, ID_WINDOW_OUTDOOR_SPORTS, kws_event_common_deal},
{KWS_EVENT_OPEN_TRAIN, ID_WINDOW_SPORT_TARGET, kws_event_common_deal},
{KWS_EVENT_OPEN_CALCULAGRAPH, ID_WINDOW_TIMER, kws_event_common_deal},
{KWS_EVENT_OPEN_CALL_DIAL, ID_WINDOW_PHONE_KEYPAD, kws_event_common_deal},
{KWS_EVENT_OPEN_PHONEBOOK, ID_WINDOW_PHONE, kws_event_common_deal},
{KWS_EVENT_OPEN_ALARM, ID_WINDOW_ALARM, kws_event_common_deal},
{KWS_EVENT_OPEN_STOPWATCH, ID_WINDOW_STOPWATCH, kws_event_common_deal},
{KWS_EVENT_OPEN_WEATHER, ID_WINDOW_WEATHER, kws_event_common_deal},
{KWS_EVENT_OPEN_MESS, ID_WINDOW_NOTICE, kws_event_common_deal},
{KWS_EVENT_OPEN_SET, ID_WINDOW_SETTING, kws_event_common_deal},
{KWS_EVENT_OPEN_APP_LIST, 0, kws_event_app_list_deal},
{KWS_EVENT_OPEN_BREATH_TRAIN, ID_WINDOW_BREATH_TRAIN, kws_event_common_deal},
{KWS_EVENT_OPEN_BARO, 0, kws_event_common_deal},
{KWS_EVENT_OPEN_COMPASS, ID_WINDOW_COMPASS, kws_event_common_deal},
{KWS_EVENT_OPEN_CARD_BAG, 0, kws_event_common_deal},
{KWS_EVENT_OPEN_ALIPAY, ID_WINDOW_ALIPAY, kws_event_common_deal},
{KWS_EVENT_OPEN_FLASHLIGHT, ID_WINDOW_FLASHLIGHT, kws_event_common_deal},
{KWS_EVENT_OPEN_CALENDAR, ID_WINDOW_CALENDAR, kws_event_common_deal},
{KWS_EVENT_OPEN_CALCULATOR, ID_WINDOW_CALCULATOR, kws_event_common_deal},
{0, 0, 0},
};
#else
static const struct jl_kws_event_ui_key kws_event_tab[] = {
};
#endif
static int kws_get_event_index(u16 event)
{
int index = -1;
for (int i = 0; i < ARRAY_SIZE(kws_event_tab); i++) {
if (kws_event_tab[i].event == event) {
index = i;
break;
}
}
return index;
}
static int kws_admittance_check_mode(void)
{
u8 cur_task = app_get_current_mode_name();
switch (cur_task) {
case APP_MODE_POWERON:
case APP_MODE_UPDATE:
case APP_MODE_SMARTBOX:
// 这些模式不支持跳转
log_e("cur task:%d no support swtich \n", cur_task);
return false;
/* break; */
default:
break;
}
return true;
}
static int kws_admittance_check_phone_bt(void)
{
if (bt_must_work()) {
log_e("phone bt busy \n");
return false;
}
return true;
}
static int kws_admittance_check_bt(void)
{
if (esco_player_runing()) {
log_e("bt busy \n");
return false;
}
return true;
}
static int kws_admittance_check_ui(void)
{
if (UI_WINDOW_PREEMPTION_CHECK()) {
log_e("ui busy \n");
return false;
}
return true;
}
static int kws_admittance_check(u16 event, u32 id, u32 check_type)
{
int index = 0;
if (check_type & KWS_CHECK_EVENT) {
index = kws_get_event_index(event);
if (index < 0) {
log_e("event index err \n");
return KWS_EVENT_ERR_CHECK_EVENT;
}
}
if ((check_type & KWS_CHECK_ID) && (id == 0)) {
return KWS_EVENT_ERR_CHECK_ID;
}
if ((check_type & KWS_CHECK_MODE) && (!kws_admittance_check_mode())) {
return KWS_EVENT_ERR_CHECK_MODE;
}
if ((check_type & KWS_CHECK_BT) && (!kws_admittance_check_bt())) {
return KWS_EVENT_ERR_CHECK_BT;
}
if ((check_type & KWS_CHECK_PHONE_BT) && (!kws_admittance_check_phone_bt())) {
return KWS_EVENT_ERR_CHECK_BT;
}
if (((check_type & KWS_CHECK_UI) && !kws_admittance_check_ui())) {
return KWS_EVENT_ERR_CHECK_UI;
}
return index;
}
static void kws_event_ui_show_push(int (*callback)(int))
{
int argv[3];
argv[0] = (int)callback;
argv[1] = 1;
argv[2] = (int)0;
os_taskq_post_type("ui", Q_CALLBACK, ARRAY_SIZE(argv), argv);
}
#if (defined(CONFIG_UI_STYLE_JL_PUBLIC_MODLS_ENABLE) || defined(CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE))
static int kws_event_ui_show_ID(u32 id, u8 checkid)
{
if (__this->last_ui_id) {
UI_WINDOW_BACK_DEL(__this->last_ui_id);
}
__this->last_ui_id = id;
if (get_screen_saver_status()) {
/* ui_screen_recover(0); */
ui_auto_shut_down_enable();
/* UI_HIDE_CURR_WINDOW(); */
if (id == ID_WINDOW_NOTICE) {
create_control_by_menu_set(1);
}
UI_SHOW_WINDOW(id);
} else {
ui_auto_shut_down_re_run();
if ((UI_GET_WINDOW_ID() != id) || (!checkid)) {
UI_HIDE_CURR_WINDOW();
if (id == ID_WINDOW_NOTICE) {
create_control_by_menu_set(1);
}
UI_SHOW_WINDOW(id);
}
}
return 0;
}
#else
static int kws_event_ui_show_ID(u32 id, u8 checkid)
{
return 0;
}
#endif
static int kws_event_common_deal(u16 event, u32 id)
{
int ret = kws_admittance_check(event, id, KWS_CHECK_ID | KWS_CHECK_MODE | KWS_CHECK_BT | KWS_CHECK_UI);
if (ret) {
return ret;
}
kws_event_ui_show_ID(id, 1);
return 0;
}
static int kws_event_app_list_deal(u16 event, u32 id)
{
int ret = kws_admittance_check(event, id, KWS_CHECK_MODE | KWS_CHECK_BT | KWS_CHECK_UI);
if (ret) {
return ret;
}
if (false == ui_check_list_tyep(UI_GET_WINDOW_ID())) {
ret = ui_show_menu_page();
if (ret == false) {
return KWS_EVENT_ERR_UI_SHOW;
}
ui_auto_shut_down_re_run();
}
return 0;
}
static int kws_event_music_deal(u16 event, u32 id)
{
int ret = kws_admittance_check(event, id, KWS_CHECK_MODE | KWS_CHECK_BT | KWS_CHECK_PHONE_BT);
if (ret) {
return ret;
}
u8 cur_task = app_get_curr_task();
if (0) {
#if TCFG_APP_MUSIC_EN
} else if (cur_task == APP_MUSIC_TASK) {
switch (event) {
case KWS_EVENT_PLAY_MUSIC:
if (music_player_get_play_status() != FILE_DEC_STATUS_PLAY) {
app_send_message(APP_MSG_MUSIC_PP, 0);
}
break;
case KWS_EVENT_STOP_MUSIC:
case KWS_EVENT_PAUSE_MUSIC:
if (music_player_get_play_status() == FILE_DEC_STATUS_PLAY) {
app_send_message(APP_MSG_MUSIC_PP, 0);
}
break;
case KWS_EVENT_PREV_SONG:
app_send_message(APP_MSG_MUSIC_PREV, 0);
break;
case KWS_EVENT_NEXT_SONG:
app_send_message(APP_MSG_MUSIC_NEXT, 0);
break;
default :
break;
}
#endif /* #if TCFG_APP_MUSIC_EN */
} else if (cur_task == APP_BT_TASK) {
u8 a2dp_state = bt_a2dp_get_status();
switch (event) {
case KWS_EVENT_PLAY_MUSIC:
if (a2dp_state != BT_MUSIC_STATUS_STARTING) {
#if TCFG_APP_MUSIC_EN
if (bt_get_connect_status() == BT_STATUS_WAITINT_CONN) {
log_info("switch music mode\n");
music_set_start_auto_play(1);
app_task_switch_to(APP_MODE_MUSIC, 0);
break;
}
#endif /* #if TCFG_APP_MUSIC_EN */
log_info("send PLAY cmd\n");
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL);
}
break;
case KWS_EVENT_STOP_MUSIC:
if (a2dp_state == BT_MUSIC_STATUS_STARTING) {
log_info("send STOP cmd\n");
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_STOP, 0, NULL);
}
break;
case KWS_EVENT_PAUSE_MUSIC:
if (a2dp_state == BT_MUSIC_STATUS_STARTING) {
log_info("send PAUSE cmd\n");
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PAUSE, 0, NULL);
}
break;
case KWS_EVENT_PREV_SONG:
log_info("Send PREV cmd");
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PREV, 0, NULL);
break;
case KWS_EVENT_NEXT_SONG:
log_info("Send NEXT cmd");
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_NEXT, 0, NULL);
break;
default :
break;
}
} else {
if (event == KWS_EVENT_PLAY_MUSIC) {
#if TCFG_APP_MUSIC_EN
if (app_get_current_mode_name() == APP_MODE_BT) {
log_info("switch music mode\n");
music_set_start_auto_play(1);
app_task_switch_to(APP_MODE_MUSIC, 0);
}
#endif /* #if TCFG_APP_MUSIC_EN */
if (app_get_current_mode_name() == APP_MODE_MUSIC) {
log_info("switch bt mode, send PLAY cmd\n");
app_task_switch_to(APP_MODE_BT, 0);
bt_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL);
}
}
}
if ((event == KWS_EVENT_PLAY_MUSIC) && id) {
ret = kws_admittance_check(event, id, KWS_CHECK_UI);
if (ret == 0) {
kws_event_ui_show_ID(id, 1);
}
}
return 0;
}
static int kws_event_call_deal(u16 event, u32 id)
{
int ret = kws_admittance_check(event, id, KWS_CHECK_MODE);
if (ret) {
return ret;
}
switch (event) {
case KWS_EVENT_CALL_ACTIVE:
if (bt_get_call_status() == BT_CALL_INCOMING) {
log_info("Send ANSWER cmd");
call_ctrl_answer();
}
break;
case KWS_EVENT_CALL_HANGUP:
log_info("Send HANG UP cmd");
if ((bt_get_call_status() >= BT_CALL_INCOMING) && (bt_get_call_status() <= BT_CALL_ALERT)) {
small_file_call_log_set_type(CALL_INCOME_REJECT);
call_ctrl_hangup();
}
break;
default :
break;
}
return 0;
}
static int kws_event_volume_deal(u16 event, u32 id)
{
/* int ret = kws_admittance_check(event, id, KWS_CHECK_MODE | KWS_CHECK_BT); */
/* if (ret) { */
/* return ret; */
/* } */
switch (event) {
case KWS_EVENT_VOLUME_UP:
log_info("volume up\n");
volume_up();
break;
case KWS_EVENT_VOLUME_DOWN:
log_info("volume down\n");
volume_down();
break;
case KWS_EVENT_VOLUME_MUTE:
log_info("volume mute\n");
if (!ui_get_voice_mute()) {
ui_set_voice_mute(1);
}
break;
case KWS_EVENT_VOLUME_UNMUTE:
log_info("volume unmute\n");
if (ui_get_voice_mute()) {
ui_set_voice_mute(0);
}
break;
case KWS_EVENT_VOLUME_MAX:
log_info("volume max\n");
app_audio_set_volume(APP_AUDIO_STATE_WTONE, app_audio_volume_max_query(SysVol_TONE), 1);
#if (defined(CONFIG_UI_STYLE_JL_PUBLIC_MODLS_ENABLE) || defined(CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE))
set_ui_sys_param(LastSysVol, 100);
save_ui_info_to_vm();
#endif
break;
default :
break;
}
return 0;
}
static int kws_event_brightness_deal(u16 event, u32 id)
{
int level;
/* int ret = kws_admittance_check(event, id, KWS_CHECK_MODE | KWS_CHECK_BT); */
/* if (ret) { */
/* return ret; */
/* } */
switch (event) {
case KWS_EVENT_BRIGHTNESS_ALWAYS:
screen_light_alway_switch(1);
break;
case KWS_EVENT_BRIGHTNESS_UP:
level = get_light_level();
if (level < 10) {
level ++;
}
set_ui_sys_param(LightLevel, level);
ui_ajust_light(level);
break;
case KWS_EVENT_BRIGHTNESS_DOWN:
level = get_light_level();
if (level) {
level--;
}
set_ui_sys_param(LightLevel, level);
ui_ajust_light(level);
break;
case KWS_EVENT_BRIGHTNESS_AUTO:
level = 10;
set_ui_sys_param(LightLevel, level);
ui_ajust_light(level);
break;
default :
return 0;
/* break; */
}
write_UIInfo_to_vm(NULL);
return 0;
}
static int kws_event_bt_setting_ui_reshow(int priv)
{
/* ui_pic_show_image_by_id(PIC_EDR_SWITCH, 1); */
return 0;
}
static int kws_event_bt_setting_deal(u16 event, u32 id)
{
/* int ret = kws_event_common_deal(event, id); */
/* if (ret) { */
/* return ret; */
/* } */
if (is_bredr_close()) {
#if 1
bredr_conn_last_dev();
#else
bt_init_bredr();
#endif//自动回连
/* ui_pic_show_image_by_id(PIC_EDR_SWITCH, 1); */
kws_event_ui_show_push(kws_event_bt_setting_ui_reshow);
}
return 0;
}
static int kws_event_switch_dial_deal(u16 event, u32 id)
{
int ret = kws_admittance_check(event, id, KWS_CHECK_MODE);
if (ret) {
return ret;
}
int items = watch_get_items_num();
int sel_item = watch_get_style();
sel_item ++;
if (sel_item >= items) {
sel_item = 0;
}
ret = watch_version_juge(watch_get_item(sel_item));
if (ret != 0) {
log_error("watch_version_juge err %d, %d\n", sel_item, ret);
return KWS_EVENT_ERR_UI_SHOW;
}
ret = watch_set_style(sel_item);
if (ret != true) {
log_error("watch_set_style err %d\n", sel_item);
return KWS_EVENT_ERR_UI_SHOW;
}
ret = kws_admittance_check(event, id, KWS_CHECK_BT | KWS_CHECK_UI);
if (ret == 0) {
kws_event_ui_show_ID(id, 0);
}
return 0;
}
static int kws_event_switch_style_deal(u16 event, u32 id)
{
int ret = kws_admittance_check(event, id, KWS_CHECK_MODE);
if (ret) {
return ret;
}
u8 menu_style = get_ui_sys_param(MenuStyle);
menu_style ++;
if (menu_style > (ui_show_menu_total_num() - 1)) {
menu_style = 0;
}
set_ui_sys_param(MenuStyle, menu_style);
write_UIInfo_to_vm(NULL);
ret = kws_admittance_check(event, id, KWS_CHECK_BT | KWS_CHECK_UI);
if (ret == 0) {
ret = ui_show_menu_page();
if (ret == false) {
return KWS_EVENT_ERR_UI_SHOW;
}
ui_auto_shut_down_re_run();
}
return 0;
}
/* ---------------------------------------------------------------------------- */
/**
* @brief: 关键词唤醒语音事件处理流程
*
* @param event: 系统事件
*
* @return : true: 处理该事件; false: 不处理该事件, 由
*/
/* ---------------------------------------------------------------------------- */
int jl_kws_voice_event_handle(int event)
{
u32 cur_jiffies = jiffies;
u32 voice_event = event;
log_info("%s: event: %d", __func__, voice_event);
if (voice_event == __this->last_event) {
if (jiffies_to_msecs(cur_jiffies - __this->last_event_jiffies) < 1000) {
log_info("voice event %d same, ignore", voice_event);
__this->last_event_jiffies = cur_jiffies;
return true;
}
}
__this->last_event_jiffies = cur_jiffies;
__this->last_event = voice_event;
switch (voice_event) {
case KWS_EVENT_HEY_KEYWORD:
case KWS_EVENT_XIAOJIE:
//主唤醒词:
log_info("send SIRI cmd");
bt_cmd_prepare(USER_CTRL_HFP_GET_SIRI_OPEN, 0, NULL);
break;
case KWS_EVENT_XIAODU:
//主唤醒词:
log_info("send SIRI cmd");
bt_cmd_prepare(USER_CTRL_HFP_GET_SIRI_OPEN, 0, NULL);
break;
#if TCFG_AUDIO_ANC_ENABLE
case KWS_EVENT_ANC_ON:
anc_mode_switch(ANC_ON, 1);
break;
case KWS_EVENT_TRANSARENT_ON:
anc_mode_switch(ANC_TRANSPARENCY, 1);
break;
case KWS_EVENT_ANC_OFF:
anc_mode_switch(ANC_OFF, 1);
break;
#endif
case KWS_EVENT_NULL:
log_info("KWS_EVENT_NULL");
break;
default: {
int index = kws_get_event_index(voice_event);
if (index < 0) {
log_error("event index err \n");
break;
}
if (kws_event_tab[index].deal) {
int ret = kws_event_tab[index].deal(voice_event, kws_event_tab[index].ui_id);
log_info("event deal index:%d, ret:%d \n", index, ret);
}
}
break;
}
return true;
}
static int kws_voice_event_msg_handler(int *msg)
{
int type = msg[0];
switch (type) {
case APP_MSG_SMART_VOICE_EVENT:
int event = msg[1];
jl_kws_voice_event_handle(event);
break;
default:
break;
}
return 0;
}
APP_MSG_HANDLER(kws_voice_event_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_APP,
.handler = kws_voice_event_msg_handler,
};
#endif
+91
View File
@@ -0,0 +1,91 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".low_latency.data.bss")
#pragma data_seg(".low_latency.data")
#pragma const_seg(".low_latency.text.const")
#pragma code_seg(".low_latency.text")
#endif
#include "system/includes.h"
#include "btstack/a2dp_media_codec.h"
#include "a2dp_player.h"
#include "app_tone.h"
#include "low_latency.h"
#include "app_config.h"
#if TCFG_APP_BT_EN
#if(TCFG_USER_TWS_ENABLE == 0)
enum {
API_ENTER_LOW_LATENCY,
API_EXIT_LOW_LATENCY,
API_RESTART_A2DP_DEC,
};
static u8 low_latency_mode = 0;
static u16 low_latency_timer = 0;
static u8 g_btaddr[6];
static void *g_a2dp_file = NULL;
static void get_a2dp_packet_timer(void *p)
{
struct a2dp_media_frame frame;
if (!g_a2dp_file) {
return;
}
int len = a2dp_media_try_get_packet(g_a2dp_file, &frame);
if (len == 0) {
return;
}
u16 seqn = (frame.packet[2] << 8) | frame.packet[3];
int type = a2dp_media_get_codec_type(g_a2dp_file);
if (type == A2DP_CODEC_SBC) {
seqn += 200 / 15;
} else {
seqn += 200 / 20;
}
a2dp_media_clear_packet_before_seqn(g_a2dp_file, seqn);
if (!tone_player_runing()) {
sys_timer_del(low_latency_timer);
low_latency_timer = 0;
a2dp_player_open(g_btaddr);
}
}
static void set_low_latency_mode(int enable)
{
if (low_latency_timer) {
return;
}
printf("set_low_latency: enable = %d\n", enable);
a2dp_player_low_latency_enable(enable);
if (a2dp_player_runing()) {
a2dp_player_get_btaddr(g_btaddr);
a2dp_player_close(g_btaddr);
g_a2dp_file = a2dp_open_media_file(g_btaddr);
low_latency_timer = sys_timer_add(NULL, get_a2dp_packet_timer, 100);
}
if (enable) {
play_tone_file(get_tone_files()->low_latency_in);
} else {
play_tone_file(get_tone_files()->low_latency_out);
}
low_latency_mode = enable;
}
void bt_set_low_latency_mode(int enable)
{
set_low_latency_mode(enable);
}
int bt_get_low_latency_mode()
{
return low_latency_mode;
}
#endif
#endif /* #if TCFG_APP_BT_EN */
File diff suppressed because it is too large Load Diff
+183
View File
@@ -0,0 +1,183 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".poweroff.data.bss")
#pragma data_seg(".poweroff.data")
#pragma const_seg(".poweroff.text.const")
#pragma code_seg(".poweroff.text")
#endif
#include "classic/hci_lmp.h"
#include "btstack/avctp_user.h"
#include "app_config.h"
#include "app_tone.h"
#include "app_main.h"
#include "bt.h"
#include "a2dp_player.h"
#include "esco_player.h"
#include "idle.h"
#include "app_charge.h"
#include "bt_slience_detect.h"
#include "poweroff.h"
#include "bt_background.h"
#if(TCFG_USER_TWS_ENABLE == 0)
#define LOG_TAG "[POWEROFF]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
static u16 g_poweroff_timer = 0;
static u16 g_bt_detach_timer = 0;
static void sys_auto_shut_down_deal(void *priv);
void sys_auto_shut_down_disable(void)
{
#if TCFG_AUTO_SHUT_DOWN_TIME
log_info("sys_auto_shut_down_disable\n");
if (g_poweroff_timer) {
sys_timeout_del(g_poweroff_timer);
g_poweroff_timer = 0;
}
#endif
}
void sys_auto_shut_down_enable(void)
{
#if TCFG_AUTO_SHUT_DOWN_TIME
#if TCFG_BT_BACKGROUND_ENABLE
if (bt_background_active()) {
log_info("sys_auto_shut_down_enable cannot in background\n");
return;
}
#endif
log_info("sys_auto_shut_down_enable\n");
if (g_poweroff_timer == 0) {
g_poweroff_timer = sys_timeout_add(NULL, sys_auto_shut_down_deal,
app_var.auto_off_time * 1000);
}
#endif
}
static void sys_auto_shut_down_deal(void *priv)
{
sys_enter_soft_poweroff(POWEROFF_NORMAL);
}
static int poweroff_app_event_handler(int *msg)
{
switch (msg[0]) {
case APP_MSG_BT_IN_PAIRING_MODE:
if (msg[1] == 0) {
sys_auto_shut_down_enable();
}
break;
}
return 0;
}
APP_MSG_HANDLER(poweroff_app_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_APP,
.handler = poweroff_app_event_handler,
};
static int poweroff_btstack_event_handler(int *_event)
{
struct bt_event *bt = (struct bt_event *)_event;
switch (bt->event) {
case BT_STATUS_SECOND_CONNECTED:
case BT_STATUS_FIRST_CONNECTED:
sys_auto_shut_down_disable();
break;
}
return 0;
}
APP_MSG_HANDLER(poweroff_btstack_msg_stub) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = poweroff_btstack_event_handler,
};
static void wait_exit_btstack_flag(void *_reason)
{
int reason = (int)_reason;
#if TCFG_USER_BT_CLASSIC_ENABLE
if (a2dp_player_runing() || esco_player_runing()) {
if (++app_var.goto_poweroff_cnt > 200) {
log_info("cpu_reset!!!\n");
cpu_reset();
}
printf("wait_poweroff_cnt: %d\n", app_var.goto_poweroff_cnt);
return ;
}
lmp_hci_reset();
os_time_dly(2);
#endif
sys_timer_del(g_bt_detach_timer);
switch (reason) {
case POWEROFF_NORMAL:
log_info("task_switch to idle...\n");
app_send_message2(APP_MSG_GOTO_MODE, APP_MODE_IDLE, IDLE_MODE_PLAY_POWEROFF);
break;
case POWEROFF_RESET:
log_info("cpu_reset!!!\n");
cpu_reset();
break;
case POWEROFF_POWER_KEEP:
#if TCFG_CHARGE_ENABLE
app_charge_power_off_keep_mode();
#endif
break;
}
}
void sys_enter_soft_poweroff(enum poweroff_reason reason)
{
log_info("sys_enter_soft_poweroff: %d flag:%d \n", reason, app_var.goto_poweroff_flag);
if (app_var.goto_poweroff_flag) {
return;
}
app_var.goto_poweroff_flag = 1;
app_var.goto_poweroff_cnt = 0;
sys_auto_shut_down_disable();
#if TCFG_APP_BT_EN
void bt_sniff_disable();
bt_sniff_disable();
#endif
#if TCFG_USER_BT_CLASSIC_ENABLE
bt_stop_a2dp_slience_detect(NULL);
#endif
app_send_message(APP_MSG_POWER_OFF, 0);
#if TCFG_USER_BT_CLASSIC_ENABLE
bt_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
#endif
#if (SYS_DEFAULT_VOL == 0)
syscfg_write(CFG_SYS_VOL, &app_var.music_volume, 2);
#endif
g_bt_detach_timer = sys_timer_add((void *)reason, wait_exit_btstack_flag, 50);
}
#endif
+247
View File
@@ -0,0 +1,247 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sniff.data.bss")
#pragma data_seg(".sniff.data")
#pragma const_seg(".sniff.text.const")
#pragma code_seg(".sniff.text")
#endif
#include "btstack/avctp_user.h"
#include "app_config.h"
#include "app_main.h"
#include "bt.h"
#include "bt_tws.h"
#if TCFG_AUDIO_ANC_ENABLE
#include "audio_anc.h"
#endif
#if (RCSP_ADV_EN)
#include "ble_rcsp_adv.h"
#endif
#define LOG_TAG "[SNIFF]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if TCFG_APP_BT_EN
/*
*以下情况,关闭sniff
*(1)通过spp在线调试eq
*(2)通过spp导出数据
*/
#if APP_ONLINE_DEBUG
#if ((TCFG_AUDIO_DATA_EXPORT_DEFINE == AUDIO_DATA_EXPORT_VIA_SPP) || \
TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE || USE_DMA_UART_TEST )
/*!!! 不要使用MY_SNIFF_EN宏去控制sniff开关,这样会导致协议栈状态错误!!!*/
static u8 sniff_enable = 0;
#else
static u8 sniff_enable = 1;
#endif
#else
static u8 sniff_enable = 1;
#endif
#define SNIFF_CNT_TIME TCFG_SNIFF_CHECK_TIME //空闲6S之后进入sniff模式
#define SNIFF_MAX_INTERVALSLOT 800
#define SNIFF_MIN_INTERVALSLOT 100
#define SNIFF_ATTEMPT_SLOT 4
#define SNIFF_TIMEOUT_SLOT 1
u8 sniff_ready_status = 0; //0:sniff_ready 1:sniff_not_ready
bool bt_is_sniff_close(void)
{
return (g_bt_hdl.sniff_timer == 0);
}
void bt_check_exit_sniff()
{
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
return;
}
bt_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
}
void bt_sniff_ready_clean(void)
{
sniff_ready_status = 1;
}
void bt_check_enter_sniff()
{
u8 addr[12];
#if TCFG_BT_SNIFF_ENABLE
#if TCFG_USER_EMITTER_ENABLE
if (app_var.a2dp_source_open_flag) { // 如果蓝牙发射a2dp_tx模块开启则不进入SNIFF
return;
}
#endif
#if TCFG_AUDIO_ANC_ENABLE
if (anc_train_open_query() || anc_online_busy_get()) { //如果ANC训练则不进入SNIFF
return;
}
#endif
#if (RCSP_ADV_EN)
if (get_ble_adv_modify() || get_ble_adv_notify()) {
return;
}
#endif
if (sniff_ready_status) {
sniff_ready_status = 0;
return;
}
#if TCFG_BT_DUAL_CONN_ENABLE
if (bt_get_esco_coder_busy_flag()) {
return;
}
#endif
if (app_get_current_mode_name() == APP_MODE_UPDATE ||
app_get_current_mode_name() == APP_MODE_RCSP) {
return; // 传输的时候不进sniff
}
struct sniff_ctrl_config_t config;
int conn_cnt = bt_api_enter_sniff_status_check(SNIFF_CNT_TIME, addr);
ASSERT(conn_cnt <= 2);
for (int i = 0; i < conn_cnt; i++) {
log_info("-----USER SEND SNIFF IN %d %d\n", i, conn_cnt);
config.sniff_max_interval = SNIFF_MAX_INTERVALSLOT;
config.sniff_mix_interval = SNIFF_MIN_INTERVALSLOT;
config.sniff_attemp = SNIFF_ATTEMPT_SLOT;
config.sniff_timeout = SNIFF_TIMEOUT_SLOT;
memcpy(config.sniff_addr, addr + i * 6, 6);
bt_cmd_prepare(USER_CTRL_SNIFF_IN, sizeof(config), (u8 *)&config);
}
#endif
}
void sys_auto_sniff_controle(u8 enable, u8 *addr)
{
if (addr) {
if (bt_api_conn_mode_check(enable, addr) == 0) {
log_info("sniff ctr not change\n");
return;
}
}
if (enable) {
if (!sniff_enable) {
//sniff_enable为0时不启动定时器去检测进入sniff
return;
}
if (tws_api_get_role_async() == TWS_ROLE_SLAVE) {
return;
}
if (g_bt_hdl.sniff_timer == 0) {
log_info("check_sniff_enable\n");
g_bt_hdl.sniff_timer = sys_timer_add(NULL, bt_check_enter_sniff, 1000);
}
} else {
if (g_bt_hdl.sniff_timer) {
log_info("check_sniff_disable\n");
sys_timeout_del(g_bt_hdl.sniff_timer);
g_bt_hdl.sniff_timer = 0;
}
}
}
void bt_sniff_enable()
{
sniff_enable = 1;
sys_auto_sniff_controle(1, NULL);
}
void bt_sniff_disable()
{
sys_auto_sniff_controle(0, NULL);
bt_check_exit_sniff();
sniff_enable = 0;
}
void bt_sniff_feature_init()
{
#if TCFG_BT_SNIFF_ENABLE == 0
u8 feature = lmp_hci_read_local_supported_features(0);
feature &= ~BIT(7); //BIT_SNIFF_MODE;
lmp_hci_write_local_supported_features(feature, 0);
#endif
}
static int sniff_btstack_event_handler(int *_event)
{
struct bt_event *bt = (struct bt_event *)_event;
switch (bt->event) {
case BT_STATUS_SECOND_CONNECTED:
case BT_STATUS_FIRST_CONNECTED:
sys_auto_sniff_controle(1, bt->args);
break;
case BT_STATUS_SNIFF_STATE_UPDATE:
log_info(" BT_STATUS_SNIFF_STATE_UPDATE %d\n", bt->value); //0退出SNIFF
if (bt->value == 0) {
sys_auto_sniff_controle(1, bt->args);
app_send_message(APP_MSG_BT_EXIT_SNIFF, 0);
} else {
sys_auto_sniff_controle(0, bt->args);
app_send_message(APP_MSG_BT_ENTER_SNIFF, 0);
}
break;
case BT_STATUS_FIRST_DISCONNECT:
case BT_STATUS_SECOND_DISCONNECT:
sys_auto_sniff_controle(0, bt->args);
break;
}
return 0;
}
APP_MSG_HANDLER(sniff_btstack_msg_stub) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = sniff_btstack_event_handler,
};
#if TCFG_USER_TWS_ENABLE
static int sniff_tws_event_handler(int *_event)
{
struct tws_event *event = (struct tws_event *)_event;
int role = event->args[0];
int reason = event->args[2];
if (app_var.goto_poweroff_flag) {
return 0;
}
switch (event->event) {
case TWS_EVENT_CONNECTION_DETACH:
break;
case TWS_EVENT_ROLE_SWITCH:
if (role == TWS_ROLE_MASTER) {
sys_auto_sniff_controle(1, NULL);
} else {
sys_auto_sniff_controle(0, NULL);
}
break;
}
return 0;
}
APP_MSG_HANDLER(sniff_tws_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_TWS,
.handler = sniff_tws_event_handler,
};
#endif
#endif
+172
View File
@@ -0,0 +1,172 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".tone.data.bss")
#pragma data_seg(".tone.data")
#pragma const_seg(".tone.text.const")
#pragma code_seg(".tone.text")
#endif
#include "btstack/avctp_user.h"
#include "classic/tws_api.h"
#include "app_main.h"
#include "bt.h"
#include "app_config.h"
#include "bt_tws.h"
#include "app_tone.h"
#include "app_testbox.h"
#if TCFG_APP_BT_EN
#define TWS_DLY_DISCONN_TIME 0//2000 //TWS超时断开,快速连接上不播提示音
static u8 g_tws_connected = 0;
static u16 tws_dly_discon_time = 0;
static int tone_btstack_event_handler(int *_event)
{
struct bt_event *event = (struct bt_event *)_event;
switch (event->event) {
case BT_STATUS_FIRST_CONNECTED:
case BT_STATUS_SECOND_CONNECTED:
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_status()) {
break;
}
#endif
/*
* 获取tws状态,如果正在播歌或打电话则返回1,不播连接成功提示音
*/
#if TCFG_USER_TWS_ENABLE
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
break;
}
int state = tws_api_get_lmp_state(event->args);
if (state & TWS_STA_ESCO_OPEN) {
break;
}
tws_play_tone_file(get_tone_files()->bt_connect, 400);
#else
play_tone_file(get_tone_files()->bt_connect);
#endif
break;
case BT_STATUS_FIRST_DISCONNECT:
case BT_STATUS_SECOND_DISCONNECT:
/*
* 关机、重启不播断开提示音
*/
if (app_var.goto_poweroff_flag || app_var.goto_reboot_flag) {
break;
}
if (!g_bt_hdl.ignore_discon_tone) {
#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
}
break;
}
return 0;
}
APP_MSG_HANDLER(tone_stack_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = tone_btstack_event_handler,
};
#if TCFG_USER_TWS_ENABLE
void tws_disconn_dly_deal(void *priv)
{
if (tws_dly_discon_time == 0) {
return;
}
tws_dly_discon_time = 0;
if (app_var.goto_poweroff_flag) {
return;
}
if (!g_bt_hdl.ignore_discon_tone) {
tone_player_stop();
play_tone_file(get_tone_files()->tws_disconnect);
}
}
static int tone_tws_event_handler(int *_event)
{
struct tws_event *event = (struct tws_event *)_event;
int role = event->args[0];
int reason = event->args[2];
switch (event->event) {
case TWS_EVENT_CONNECTED:
g_tws_connected = 1;
if (tws_dly_discon_time) {
sys_timeout_del(tws_dly_discon_time);
tws_dly_discon_time = 0;
break;
}
tone_player_stop();
if (role == TWS_ROLE_MASTER) {
int state = tws_api_get_tws_state();
if (state & (TWS_STA_SBC_OPEN | TWS_STA_ESCO_OPEN)) {
break;
}
#if TCFG_USER_TWS_ENABLE
tws_play_tone_file(get_tone_files()->tws_connect, 400);
#else
play_tone_file(get_tone_files()->tws_connect);
#endif
}
break;
case TWS_EVENT_CONNECTION_DETACH:
if (app_var.goto_poweroff_flag) {
break;
}
if (!g_tws_connected) {
break;
}
g_tws_connected = 0;
if (reason == (TWS_DETACH_BY_REMOTE | TWS_DETACH_BY_POWEROFF)) {
break;
}
#if TWS_DLY_DISCONN_TIME
if (reason & TWS_DETACH_BY_SUPER_TIMEOUT) {
tws_dly_discon_time = sys_timeout_add(NULL, tws_disconn_dly_deal,
TWS_DLY_DISCONN_TIME);
break;
}
#endif
if (!g_bt_hdl.ignore_discon_tone) {
tone_player_stop();
play_tone_file(get_tone_files()->tws_disconnect);
}
break;
case TWS_EVENT_REMOVE_PAIRS:
//play_tone_file(get_tone_files()->tws_disconnect);
break;
}
return 0;
}
APP_MSG_HANDLER(tone_tws_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_TWS,
.handler = tone_tws_event_handler,
};
#endif
#endif