初版
This commit is contained in:
@@ -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
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user