doubao_chat/apps/demo/demo_edr/bt_music.c

1211 lines
37 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "server/server_core.h"
#include "server/audio_server.h"
#include "app_config.h"
#include "btstack/avctp_user.h"
#include "btstack/btstack_task.h"
#include "btstack/a2dp_media_codec.h"
#include "btctrler/btctrler_task.h"
#include "btcontroller_modules.h"
#include "bt_common.h"
#include "bt_emitter.h"
#include "btstack/bluetooth.h"
#include "btstack/btstack_error.h"
#include "classic/hci_lmp.h"
#include "event/bt_event.h"
#include "syscfg/syscfg_id.h"
#include "system/timer.h"
#include "event/key_event.h"
#include "event/bt_event.h"
#include "asm/power_interface.h"
#ifdef CONFIG_BT_ENABLE
#define TIMEOUT_CONN_TIME 30 //超时断开之后回连的时间s
#define POWERON_AUTO_CONN_TIME 18 //开机去回连的时间,要取6的倍数
#define BT_INBAND_RINGTONE 1 //播放手机彩铃
#define VOLUME_STEP 5
#define MIN_VOLUME_VALUE 5
#define MAX_VOLUME_VALUE 100
#define INIT_VOLUME_VALUE 50
extern void *phone_call_begin(void *priv, u8 volume);
extern void phone_call_end(void);
extern void *earphone_a2dp_audio_codec_open(int media_type, u8 volume);
extern void earphone_a2dp_audio_codec_close(void);
extern u8 get_esco_coder_busy_flag(void);
extern void bredr_set_dut_enble(u8 en, u8 phone);
extern void get_remote_device_info_from_vm(void);
extern bool get_esco_busy_flag(void);
extern void bredr_close_all_scan(void);
extern void __set_a2dp_auto_play_flag(u8 auto_en);
extern void __set_simple_pair_flag(bool flag);
struct app_bt_opr {
//phone
u8 phone_ring_flag: 1;
u8 phone_num_flag: 1;
u8 phone_income_flag: 1;
u8 phone_call_dec_begin: 1;
u8 phone_con_sync_num_ring: 1;
u8 phone_con_sync_ring: 1;
u8 emitter_or_receiver: 2;
u8 media_play_flag : 1;
u8 call_flag : 1; // 1-由于蓝牙打电话命令切回蓝牙模式
u8 exit_flag : 1; // 1-可以退出蓝牙标志
u8 enable : 1;
u8 emitter : 1;
u8 mute : 1;
u8 siri_stu; // ios siri
u8 call_volume;
u8 media_volume;
u8 inband_ringtone;
u8 last_call_type;
u8 auto_connection_addr[6];
u8 income_phone_num[30];
u8 income_phone_len;
u16 phone_timer_id;
u16 poweroff_timer_id;
int auto_connection_counter;
int auto_connection_timer;
int sniff_timer;
void *dec_server;
};
static struct app_bt_opr app_bt_hdl;
#define __this (&app_bt_hdl)
void (*lmp_ch_update_resume_hdl)(void *priv) = NULL;
#define SBC_FILTER_TIME_MS 2000 //后台音频过滤时间ms
#define SBC_ZERO_TIME_MS 500 //静音多长时间认为已经退出
#define NO_SBC_TIME_MS 100 //无音频时间ms
/*开关可发现可连接的函数接口*/
static void bt_wait_phone_connect_control(u8 enable)
{
if (!__this->enable && enable) {
return;
}
if (enable) {
log_i("is_1t2_connection:%d \t total_conn_dev:%d\n", is_1t2_connection(), get_total_connect_dev());
if (is_1t2_connection()) {
/*达到最大连接数,可发现(0)可连接(0)*/
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
} else {
if (get_total_connect_dev() == 1) {
/*支持连接2台,只连接一台的情况下,可发现(0)可连接(1)*/
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
} else {
/*可发现(1)可连接(1)*/
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
}
}
} else {
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
}
}
static void bt_init_ok_search_index(void)
{
if (!__this->auto_connection_counter && get_current_poweron_memory_search_index(__this->auto_connection_addr)) {
log_i("bt_wait_connect_and_phone_connect_switch\n");
clear_current_poweron_memory_search_index(1);
__this->auto_connection_counter = POWERON_AUTO_CONN_TIME * 1000; //8000ms
}
}
static int bt_wait_connect_and_phone_connect_switch(void *p)
{
int ret = 0;
int timeout = 0;
log_i("connect_switch: %d, %d\n", (int)p, __this->auto_connection_counter);
if (!__this->enable) {
return 0;
}
__this->auto_connection_timer = 0;
if (__this->auto_connection_counter <= 0) {
__this->auto_connection_counter = 0;
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
if (get_current_poweron_memory_search_index(NULL)) {
bt_init_ok_search_index();
return bt_wait_connect_and_phone_connect_switch(0);
} else {
bt_wait_phone_connect_control(1);
return 0;
}
}
/* log_i(">>>phone_connect_switch=%d\n",__this->auto_connection_counter ); */
if (!p) {
if (__this->auto_connection_counter) {
timeout = 4000;
bt_wait_phone_connect_control(0);
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, __this->auto_connection_addr);
ret = 1;
}
} else {
timeout = 2000;
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
bt_wait_phone_connect_control(1);
}
if (__this->auto_connection_counter) {
__this->auto_connection_counter -= timeout;
log_i("do=%d\n", __this->auto_connection_counter);
}
__this->auto_connection_timer = sys_timeout_add((void *)(!(int)p),
(void (*)(void *))bt_wait_connect_and_phone_connect_switch, timeout);
return ret;
}
static void bt_set_music_device_volume(int volume)
{
struct bt_event evt = {0};
if (volume == 0xff) {
return;
}
volume = volume * 100 / 127;
printf("bt music set volume : %d\n", volume);
__this->media_volume = volume;
if (__this->dec_server) {
union audio_req req = {0};
req.dec.cmd = AUDIO_DEC_SET_VOLUME;
req.dec.volume = volume;
server_request(__this->dec_server, AUDIO_REQ_DEC, &req);
}
}
static int phone_get_device_vol(void)
{
printf("bt music get volume\n");
return __this->call_volume * 127 / 100;
}
static void phone_sync_vol(u8 volume)
{
volume = (u16)volume * 15 / 100;
user_send_cmd_prepare(USER_CTRL_HFP_CALL_SET_VOLUME, 1, &volume);
}
static 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);
#if TCFG_USER_EMITTER_ENABLE
emitter_search_noname(status, addr, (char *)name);
#endif
}
static int bt_get_battery_value()
{
//取消默认蓝牙定时发送电量给手机,需要更新电量给手机使用USER_CTRL_HFP_CMD_UPDATE_BATTARY命令
/*电量协议的是0-9个等级,请比例换算*/
return 9;
}
static void bt_dut_api(u8 value)
{
log_i("bt in dut\n");
bredr_close_all_scan();
}
static void bredr_handle_register(void)
{
#if USER_SUPPORT_PROFILE_SPP
extern void user_spp_data_handler(u8 packet_type, u16 ch, u8 * packet, u16 size);
spp_data_deal_handle_register(user_spp_data_handler);
#endif
#if BT_SUPPORT_MUSIC_VOL_SYNC
///蓝牙音乐和通话音量同步
music_vol_change_handle_register(bt_set_music_device_volume, phone_get_device_vol);
#endif
#if BT_SUPPORT_DISPLAY_BAT
///电量显示获取电量的接口
get_battery_value_register(bt_get_battery_value); /*电量显示获取电量的接口*/
#endif
///被测试盒链接上进入快速测试回调
/* bt_fast_test_handle_register(bt_fast_test_api); */
///样机进入dut被测试仪器链接上回调
bt_dut_test_handle_register(bt_dut_api);
///获取远端设备蓝牙名字回调
read_remote_name_handle_register(bt_read_remote_name);
////获取歌曲信息回调
/* bt_music_info_handle_register(user_get_bt_music_info); */
#if TCFG_USER_EMITTER_ENABLE
////发射器设置回调等
inquiry_result_handle_register(emitter_search_result);
#endif
}
static void bt_function_select_init(void)
{
__this->media_volume = INIT_VOLUME_VALUE;
__this->call_volume = INIT_VOLUME_VALUE;
__set_a2dp_auto_play_flag(1); /* 连接高级音频后自动播放歌曲 */
__set_support_msbc_flag(1);
#if TCFG_BT_SUPPORT_AAC
__set_support_aac_flag(1);
#endif
#if BT_SUPPORT_DISPLAY_BAT
__bt_set_update_battery_time(60);
#else
__bt_set_update_battery_time(0);
#endif
__set_page_timeout_value(8000); /*回连搜索时间长度设置,可使用该函数注册使用,ms单位,u16*/
__set_super_timeout_value(8000); /*回连时超时参数设置。ms单位。做主机有效*/
__set_simple_pair_flag(1); //是否打开简易配对功能,打开后不需要输入pincode
////设置蓝牙加密的level
//io_capabilities ; /*0: Display only 1: Display YesNo 2: KeyboardOnly 3: NoInputNoOutput*/
//authentication_requirements: 0:not protect 1 :protect
__set_simple_pair_param(3, 0, 2);
#if (USER_SUPPORT_PROFILE_PBAP==1)
////设置蓝牙设备类型
__change_hci_class_type(BD_CLASS_CAR_AUDIO);
#endif
#if (TCFG_BT_SNIFF_ENABLE == 0)
void lmp_set_sniff_disable(void);
lmp_set_sniff_disable();
#endif
}
static void a2dp_drop_frame(void)
{
int len;
u8 *frame;
int num = a2dp_media_get_packet_num();
if (num > 1) {
for (int i = 0; i < (num - 1); i++) {
len = a2dp_media_get_packet(&frame);
if (len <= 0) {
break;
}
/* log_i("a2dp_drop_frame: %d\n", len); */
a2dp_media_free_packet(frame);
}
}
}
/*配置通话时前面丢掉的数据包包数*/
#define ESCO_DUMP_PACKET_ADJUST 1 /*配置使能*/
#define ESCO_DUMP_PACKET_DEFAULT 0
#define ESCO_DUMP_PACKET_CALL 120 /*0~0xFF*/
static u8 esco_dump_packet = ESCO_DUMP_PACKET_CALL;
#if ESCO_DUMP_PACKET_ADJUST
u8 get_esco_packet_dump(void)
{
//log_i("esco_dump_packet:%d\n", esco_dump_packet);
return esco_dump_packet;
}
#endif
#define SNIFF_CNT_TIME 5/////<空闲5S之后进入sniff模式
#define SNIFF_MAX_INTERVALSLOT 800
#define SNIFF_MIN_INTERVALSLOT 100
#define SNIFF_ATTEMPT_SLOT 4
#define SNIFF_TIMEOUT_SLOT 1
static int exit_sniff_timer = 0;
static void bt_check_exit_sniff(void)
{
sys_timeout_del(exit_sniff_timer);
exit_sniff_timer = 0;
user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
}
static void bt_check_enter_sniff(void *priv)
{
struct sniff_ctrl_config_t sniff_ctrl_config;
u8 addr[12];
u8 conn_cnt = 0;
u8 i = 0;
/*putchar('H');*/
conn_cnt = bt_api_enter_sniff_status_check(SNIFF_CNT_TIME, addr);
ASSERT(conn_cnt <= 2);
for (i = 0; i < conn_cnt; i++) {
log_i("-----USER SEND SNIFF IN %d %d\n", i, conn_cnt);
sniff_ctrl_config.sniff_max_interval = SNIFF_MAX_INTERVALSLOT;
sniff_ctrl_config.sniff_mix_interval = SNIFF_MIN_INTERVALSLOT;
sniff_ctrl_config.sniff_attemp = SNIFF_ATTEMPT_SLOT;
sniff_ctrl_config.sniff_timeout = SNIFF_TIMEOUT_SLOT;
memcpy(sniff_ctrl_config.sniff_addr, addr + i * 6, 6);
user_send_cmd_prepare(USER_CTRL_SNIFF_IN, sizeof(struct sniff_ctrl_config_t), (u8 *)&sniff_ctrl_config);
}
}
static void sys_auto_sniff_controle(u8 enable, u8 *addr)
{
#if (TCFG_BT_SNIFF_ENABLE == 0)
return;
#endif
if (addr) {
if (bt_api_conn_mode_check(enable, addr) == 0) {
log_i("sniff ctr not change\n");
return;
}
}
if (enable) {
if (get_total_connect_dev() == 0) {
return;
}
if (addr) {
log_i("sniff cmd timer init\n");
user_cmd_timer_init();
}
if (__this->sniff_timer == 0) {
log_i("check_sniff_enable\n");
__this->sniff_timer = sys_timer_add(NULL, bt_check_enter_sniff, 1000);
}
} else {
if (get_total_connect_dev() > 0) {
return;
}
if (addr) {
log_i("sniff cmd timer remove\n");
remove_user_cmd_timer();
}
if (__this->sniff_timer) {
log_i("check_sniff_disable\n");
sys_timeout_del(__this->sniff_timer);
__this->sniff_timer = 0;
if (exit_sniff_timer == 0) {
/* exit_sniff_timer = sys_timer_add(NULL, bt_check_exit_sniff, 5000); */
}
}
}
}
static void phone_num_play_timer(void *priv)
{
if (get_call_status() == BT_CALL_HANGUP) {
log_i("hangup,--phone num play return\n");
return;
}
if (__this->phone_num_flag) {
//TODO 播放手机号码
} else {
/*电话号码还没有获取到,定时查询*/
__this->phone_timer_id = sys_timeout_add(NULL, phone_num_play_timer, 200);
}
}
static void phone_num_play_start(void)
{
/* check if support inband ringtone */
if (!__this->inband_ringtone) {
__this->phone_num_flag = 0;
__this->phone_timer_id = sys_timeout_add(NULL, phone_num_play_timer, 500);
}
}
static void phone_ring_play_timer(void *priv)
{
//通话铃声逻辑暂未处理
__this->phone_timer_id = sys_timeout_add(NULL, phone_ring_play_timer, 1000);
}
static void phone_ring_play_start(void)
{
if (get_call_status() == BT_CALL_HANGUP) {
log_i("hangup,--phone ring play return\n");
return;
}
/* check if support inband ringtone */
if (!__this->inband_ringtone) {
__this->phone_timer_id = sys_timeout_add(NULL, phone_ring_play_timer, 1000);
}
}
void bt_ble_module_init(void)
{
bt_function_select_init();
bredr_handle_register();
btstack_init();
}
//打开蓝牙
void bt_connection_enable(void)
{
if (__this->enable) {
return;
}
if (__this->poweroff_timer_id) {
sys_timeout_del(__this->poweroff_timer_id);
__this->poweroff_timer_id = 0;
}
#ifdef CONFIG_LOW_POWER_ENABLE
low_power_hw_unsleep_lock();
btctrler_task_init_bredr();
low_power_hw_unsleep_unlock();
#endif
__this->enable = 1;
__this->auto_connection_counter = 0;
get_remote_device_info_from_vm();
bt_init_ok_search_index();
#if ((CONFIG_BT_MODE == BT_BQB)||(CONFIG_BT_MODE == BT_PER))
bt_wait_phone_connect_control(1);
#else
#if TCFG_USER_EMITTER_ENABLE
bt_wait_phone_connect_control(1);
#else
bt_wait_connect_and_phone_connect_switch(0);
#endif
#endif
}
static void bt_power_off(void *p)
{
if (is_1t2_connection()) {
__this->poweroff_timer_id = sys_timeout_add(NULL, bt_power_off, 100);
return;
}
__this->poweroff_timer_id = 0;
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
#ifdef CONFIG_LOW_POWER_ENABLE
os_time_dly(50);
low_power_hw_unsleep_lock();
btctrler_task_close_bredr();
low_power_hw_unsleep_unlock();
lmp_set_sniff_establish_by_remote(0);
#endif
}
//关闭蓝牙
void bt_connection_disable(void)
{
#if !TCFG_USER_EMITTER_ENABLE
if (!__this->enable) {
return;
}
#else
__this->emitter = 0;
emitter_or_receiver_switch(0);
#endif
__this->enable = 0;
if (__this->auto_connection_timer) {
sys_timer_del(__this->auto_connection_timer);
__this->auto_connection_timer = 0;
}
bt_wait_phone_connect_control(0);
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL);
if (!__this->poweroff_timer_id) {
__this->poweroff_timer_id = sys_timeout_add(NULL, bt_power_off, 500);
}
/* user_send_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL); */
}
#if TCFG_USER_EMITTER_ENABLE
static void bt_emitter_enable(void *priv)
{
__this->enable = 1;
__this->emitter = 1;
key_event_enable();
#ifdef CONFIG_LOW_POWER_ENABLE
lmp_set_sniff_establish_by_remote(1);
low_power_hw_unsleep_lock();
btctrler_task_init_bredr();
low_power_hw_unsleep_unlock();
#endif
emitter_or_receiver_switch(BT_EMITTER_EN);
}
static void bt_emitter_disable(void)
{
__this->enable = 0;
__this->emitter = 0;
if (__this->auto_connection_timer) {
sys_timer_del(__this->auto_connection_timer);
__this->auto_connection_timer = 0;
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
}
bt_wait_phone_connect_control(0);
emitter_or_receiver_switch(BT_RECEIVER_EN);
bt_connection_enable();
}
#endif
void bredr_a2dp_open_and_close(void)
{
if (get_curr_channel_state() & A2DP_CH) {
puts("start to disconnect a2dp ");
user_send_cmd_prepare(USER_CTRL_DISCONN_A2DP, 0, NULL);
} else {
puts("start to connect a2dp ");
user_send_cmd_prepare(USER_CTRL_CONN_A2DP, 0, NULL);
}
}
void bredr_hfp_open_and_close(void)
{
if (get_curr_channel_state() & HFP_CH) {
user_send_cmd_prepare(USER_CTRL_HFP_DISCONNECT, 0, NULL);
} else {
user_send_cmd_prepare(USER_CTRL_HFP_CMD_BEGIN, 0, NULL);
}
}
/*
* 对应原来的状态处理函数,连接,电话状态等
*/
static int bt_connction_status_event_handler(struct bt_event *bt)
{
log_i("-----------------------bt_connction_status_event_handler %d\n", bt->event);
switch (bt->event) {
case BT_STATUS_INIT_OK:
/*
* 蓝牙初始化完成
*/
log_i("===================BT_STATUS_INIT_OK\n");
#if SPP_TRANS_DATA_EN
extern void transport_spp_init(void);
transport_spp_init();
#endif
bt_connection_enable();
break;
case BT_STATUS_START_CONNECTED:
log_i(" BT_STATUS_START_CONNECTED\n");
break;
case BT_STATUS_ENCRY_COMPLETE:
log_i(" BT_STATUS_ENCRY_COMPLETE\n");
break;
case BT_STATUS_SECOND_CONNECTED:
clear_current_poweron_memory_search_index(0);
case BT_STATUS_FIRST_CONNECTED:
//蓝牙连接成功
log_i("BT_STATUS_CONNECTED\n");
sys_auto_sniff_controle(1, NULL);
/* user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_SEND_VOL, 0, NULL); */
break;
case BT_STATUS_FIRST_DISCONNECT:
case BT_STATUS_SECOND_DISCONNECT:
//蓝牙连接断开
log_i("BT_STATUS_DISCONNECT\n");
__this->call_flag = 0;
__this->media_play_flag = 0;
sys_auto_sniff_controle(0, NULL);
#if TCFG_USER_EMITTER_ENABLE
bt_emitter_stu_set(0);
#endif
break;
//phone status deal
case BT_STATUS_PHONE_INCOME:
//接到来电
log_i("BT_STATUS_PHONE_INCOME\n");
esco_dump_packet = ESCO_DUMP_PACKET_CALL;
u8 tmp_bd_addr[6];
memcpy(tmp_bd_addr, bt->args, 6);
/*
*(1)1t2有一台通话的时候,另一台如果来电不要提示
*(2)1t2两台同时来电,先来的提示,后来的不播
*/
if ((check_esco_state_via_addr(tmp_bd_addr) != BD_ESCO_BUSY_OTHER) && (__this->phone_ring_flag == 0)) {
#if BT_INBAND_RINGTONE
extern u8 get_device_inband_ringtone_flag(void);
__this->inband_ringtone = get_device_inband_ringtone_flag();
#else
__this->inband_ringtone = 0 ;
lmp_private_esco_suspend_resume(3);
#endif
__this->phone_ring_flag = 1;
__this->phone_income_flag = 1;
#if BT_PHONE_NUMBER
phone_num_play_start();
#else
phone_ring_play_start();
#endif
user_send_cmd_prepare(USER_CTRL_HFP_CALL_CURRENT, 0, NULL); //发命令获取电话号码
} else {
log_i("SCO busy now:%d,%d\n", check_esco_state_via_addr(tmp_bd_addr), __this->phone_ring_flag);
}
break;
case BT_STATUS_PHONE_OUT:
//通话打出
log_i("BT_STATUS_PHONE_OUT\n");
lmp_private_esco_suspend_resume(4);
esco_dump_packet = ESCO_DUMP_PACKET_CALL;
__this->phone_income_flag = 0;
user_send_cmd_prepare(USER_CTRL_HFP_CALL_CURRENT, 0, NULL); //发命令获取电话号码
break;
case BT_STATUS_PHONE_ACTIVE:
//通话接通
log_i("BT_STATUS_PHONE_ACTIVE\n");
if (__this->phone_call_dec_begin) {
log_i("call_active,dump_packet clear\n");
esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
}
if (__this->phone_ring_flag) {
__this->phone_ring_flag = 0;
if (__this->phone_timer_id) {
sys_timeout_del(__this->phone_timer_id);
__this->phone_timer_id = 0;
}
}
lmp_private_esco_suspend_resume(4);
__this->phone_income_flag = 0;
__this->phone_num_flag = 0;
__this->phone_con_sync_num_ring = 0;
__this->phone_con_sync_ring = 0;
log_i("phone_active:%d\n", __this->call_volume);
break;
case BT_STATUS_PHONE_HANGUP:
//通话挂断
esco_dump_packet = ESCO_DUMP_PACKET_CALL;
log_i("phone_handup\n");
if (__this->phone_ring_flag) {
__this->phone_ring_flag = 0;
if (__this->phone_timer_id) {
sys_timeout_del(__this->phone_timer_id);
__this->phone_timer_id = 0;
}
}
lmp_private_esco_suspend_resume(4);
__this->phone_num_flag = 0;
__this->phone_con_sync_num_ring = 0;
__this->phone_con_sync_ring = 0;
break;
case BT_STATUS_PHONE_NUMBER:
log_i("BT_STATUS_PHONE_NUMBER\n");
u8 *phone_number = (u8 *)bt->value;
if (__this->phone_num_flag == 1) {
break;
}
__this->income_phone_len = 0;
memset(__this->income_phone_num, '\0', sizeof(__this->income_phone_num));
for (int i = 0; i < strlen((const char *)phone_number); i++) {
if (phone_number[i] >= '0' && phone_number[i] <= '9') {
//过滤,只有数字才能报号
__this->income_phone_num[__this->income_phone_len++] = phone_number[i];
if (__this->income_phone_len >= sizeof(__this->income_phone_num)) {
break; /*buffer 空间不够,后面不要了*/
}
}
}
if (__this->income_phone_len > 0) {
__this->phone_num_flag = 1;
} else {
log_i("PHONE_NUMBER len err\n");
}
break;
case BT_STATUS_INBAND_RINGTONE:
log_i("BT_STATUS_INBAND_RINGTONE\n");
#if BT_INBAND_RINGTONE
__this->inband_ringtone = bt->value;
#else
__this->inband_ringtone = 0;
#endif
break;
case BT_STATUS_BEGIN_AUTO_CON:
log_i("BT_STATUS_BEGIN_AUTO_CON\n");
break;
case BT_STATUS_A2DP_MEDIA_START:
log_i(" BT_STATUS_A2DP_MEDIA_START");
__this->call_flag = 0;
if (!__this->dec_server) {
__this->dec_server = earphone_a2dp_audio_codec_open(bt->value, __this->media_volume);//A2DP_CODEC_SBC);
if (__this->dec_server) {
__this->media_play_flag = 1;
a2dp_drop_frame();
}
}
break;
case BT_STATUS_A2DP_MEDIA_STOP:
log_i(" BT_STATUS_A2DP_MEDIA_STOP");
if (__this->dec_server) {
__this->dec_server = NULL;
earphone_a2dp_audio_codec_close();
}
__this->media_play_flag = 0;
break;
case BT_STATUS_SCO_STATUS_CHANGE:
log_i(" BT_STATUS_SCO_STATUS_CHANGE len:%d ,type:%d", (bt->value >> 16), (bt->value & 0x0000ffff));
if (bt->value != 0xff) {
if (!__this->dec_server) {
__this->dec_server = phone_call_begin(&bt->value, __this->call_volume);
}
__this->call_flag = 1;
__this->phone_call_dec_begin = 1;
if (get_call_status() == BT_CALL_ACTIVE) {
log_i("dec_begin,dump_packet clear\n");
esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
}
} else {
__this->phone_call_dec_begin = 0;
esco_dump_packet = ESCO_DUMP_PACKET_CALL;
if (__this->dec_server) {
phone_call_end();
__this->dec_server = NULL;
}
__this->call_flag = 0;
}
break;
case BT_STATUS_CALL_VOL_CHANGE:
log_i(" BT_STATUS_CALL_VOL_CHANGE %d", bt->value);
u8 volume = 100 * bt->value / 15;
u8 call_status = get_call_status();
__this->call_volume = volume;
if ((call_status == BT_CALL_ACTIVE) || (call_status == BT_CALL_OUTGOING) || __this->siri_stu) {
if (__this->dec_server) {
union audio_req req = {0};
req.dec.cmd = AUDIO_DEC_SET_VOLUME;
req.dec.volume = volume;
server_request(__this->dec_server, AUDIO_REQ_DEC, &req);
}
} else if (call_status != BT_CALL_HANGUP) {
/*只保存,不设置到dac*/
__this->call_volume = volume;
}
break;
case BT_STATUS_SNIFF_STATE_UPDATE:
log_i(" BT_STATUS_SNIFF_STATE_UPDATE %d\n", bt->value); //0退出SNIFF
if (bt->value == 0) {
sys_auto_sniff_controle(1, bt->args);
} else {
sys_auto_sniff_controle(0, bt->args);
}
break;
case BT_STATUS_LAST_CALL_TYPE_CHANGE:
log_i("BT_STATUS_LAST_CALL_TYPE_CHANGE:%d\n", bt->value);
__this->last_call_type = bt->value;
break;
case BT_STATUS_CONN_A2DP_CH:
#if TCFG_USER_EMITTER_ENABLE
bt_emitter_stu_sw();
#endif
break;
case BT_STATUS_CONN_HFP_CH:
if ((!is_1t2_connection()) && (get_current_poweron_memory_search_index(NULL))) { //回连下一个device
if (get_esco_coder_busy_flag()) {
clear_current_poweron_memory_search_index(0);
} else {
user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
}
}
break;
case BT_STATUS_PHONE_MANUFACTURER:
log_i("BT_STATUS_PHONE_MANUFACTURER:%d\n", bt->value);
extern const u8 hid_conn_depend_on_dev_company;
if (hid_conn_depend_on_dev_company) {
if (bt->value) {
//user_send_cmd_prepare(USER_CTRL_HID_CONN, 0, NULL);
} else {
user_send_cmd_prepare(USER_CTRL_HID_DISCONNECT, 0, NULL);
}
}
break;
case BT_STATUS_VOICE_RECOGNITION:
log_i(" BT_STATUS_VOICE_RECOGNITION:%d \n", bt->value);
esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
/* put_buf(bt, sizeof(struct bt_event)); */
__this->siri_stu = bt->value;
break;
case BT_STATUS_AVRCP_INCOME_OPID:
#define AVC_VOLUME_UP 0x41
#define AVC_VOLUME_DOWN 0x42
log_i("BT_STATUS_AVRCP_INCOME_OPID:%d\n", bt->value);
if (bt->value == AVC_VOLUME_UP) {
}
if (bt->value == AVC_VOLUME_DOWN) {
}
break;
case BT_STATUS_RECONN_OR_CONN:
log_i(" BT_STATUS_RECONN_OR_CONN\n");
break;
default:
log_i(" BT STATUS DEFAULT\n");
break;
}
return 0;
}
static void sys_time_auto_connection_deal(void *arg)
{
if (__this->auto_connection_counter) {
__this->auto_connection_counter--;
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, __this->auto_connection_addr);
}
}
static void bt_send_pair(u8 en)
{
user_send_cmd_prepare(USER_CTRL_PAIR, 1, &en);
}
static u8 bt_hci_event_filter(struct bt_event *bt)
{
if (bt->event == HCI_EVENT_VENDOR_REMOTE_TEST) {
if (0 == bt->value) {
set_remote_test_flag(0);
/* log_debug("clear_test_box_flag"); */
return 0;
}
}
if ((bt->event != HCI_EVENT_CONNECTION_COMPLETE) ||
((bt->event == HCI_EVENT_CONNECTION_COMPLETE) && (bt->value != ERROR_CODE_SUCCESS))) {
if (get_remote_test_flag() \
&& !(HCI_EVENT_DISCONNECTION_COMPLETE == bt->event) \
&& !(HCI_EVENT_VENDOR_REMOTE_TEST == bt->event)) {
log_i("cpu reset\n");
/* cpu_reset(); */
}
}
return 1;
}
static int bt_hci_event_handler(struct bt_event *bt)
{
//对应原来的蓝牙连接上断开处理函数 ,bt->value=reason
log_i("------------------------bt_hci_event_handler reason %x", bt->event);
if (bt_hci_event_filter(bt) == 0) {
return 0;
}
switch (bt->event) {
case HCI_EVENT_INQUIRY_COMPLETE:
log_i(" HCI_EVENT_INQUIRY_COMPLETE \n");
#if TCFG_USER_EMITTER_ENABLE
emitter_search_stop(bt->value);
#endif
break;
case HCI_EVENT_IO_CAPABILITY_REQUEST:
log_i(" HCI_EVENT_IO_CAPABILITY_REQUEST \n");
break;
case HCI_EVENT_USER_CONFIRMATION_REQUEST:
log_i(" HCI_EVENT_USER_CONFIRMATION_REQUEST \n");
///<可通过按键来确认是否配对 1:配对 0:取消
bt_send_pair(1);
break;
case HCI_EVENT_USER_PASSKEY_REQUEST:
log_i(" HCI_EVENT_USER_PASSKEY_REQUEST \n");
///<可以开始输入6位passkey
break;
case HCI_EVENT_USER_PRESSKEY_NOTIFICATION:
log_i(" HCI_EVENT_USER_PRESSKEY_NOTIFICATION %x\n", bt->value);
///<可用于显示输入passkey位置 value 0:start 1:enrer 2:earse 3:clear 4:complete
break;
case HCI_EVENT_PIN_CODE_REQUEST :
log_i("HCI_EVENT_PIN_CODE_REQUEST \n");
bt_send_pair(1);
break;
case HCI_EVENT_VENDOR_NO_RECONN_ADDR :
log_i("HCI_EVENT_VENDOR_NO_RECONN_ADDR \n");
case HCI_EVENT_DISCONNECTION_COMPLETE :
log_i("HCI_EVENT_DISCONNECTION_COMPLETE \n");
bt_wait_phone_connect_control(1);
break;
case BTSTACK_EVENT_HCI_CONNECTIONS_DELETE:
case HCI_EVENT_CONNECTION_COMPLETE:
log_i(" HCI_EVENT_CONNECTION_COMPLETE \n");
switch (bt->value) {
case ERROR_CODE_SUCCESS :
log_i("ERROR_CODE_SUCCESS \n");
if (__this->auto_connection_timer) {
sys_timeout_del(__this->auto_connection_timer);
__this->auto_connection_timer = 0;
}
__this->auto_connection_counter = 0;
bt_wait_phone_connect_control(0);
user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
break;
case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION :
case ERROR_CODE_PIN_OR_KEY_MISSING:
log_i(" ERROR_CODE_PIN_OR_KEY_MISSING \n");
case ERROR_CODE_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED :
case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES:
case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR:
case ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED :
case ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST :
case ERROR_CODE_AUTHENTICATION_FAILURE :
case CUSTOM_BB_AUTO_CANCEL_PAGE:
bt_wait_phone_connect_control(1);
break;
case ERROR_CODE_PAGE_TIMEOUT:
log_i(" ERROR_CODE_PAGE_TIMEOUT \n");
if (__this->auto_connection_timer) {
sys_timer_del(__this->auto_connection_timer);
__this->auto_connection_timer = 0;
}
bt_wait_phone_connect_control(1);
break;
case ERROR_CODE_CONNECTION_TIMEOUT:
log_i(" ERROR_CODE_CONNECTION_TIMEOUT \n");
if (!get_remote_test_flag() && !get_esco_busy_flag()) {
__this->auto_connection_counter = (TIMEOUT_CONN_TIME * 1000);
memcpy(__this->auto_connection_addr, bt->args, 6);
if (__this->auto_connection_timer) {
sys_timer_del(__this->auto_connection_timer);
__this->auto_connection_timer = 0;
}
#if ((CONFIG_BT_MODE == BT_BQB)||(CONFIG_BT_MODE == BT_PER))
bt_wait_phone_connect_control(1);
#else
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
bt_wait_connect_and_phone_connect_switch(0);
#endif
//user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, bt->args);
} else {
bt_wait_phone_connect_control(1);
}
break;
case ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS :
log_i("ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS \n");
if (!get_remote_test_flag() && !get_esco_busy_flag()) {
__this->auto_connection_counter = (8 * 1000);
memcpy(__this->auto_connection_addr, bt->args, 6);
if (__this->auto_connection_timer) {
sys_timer_del(__this->auto_connection_timer);
__this->auto_connection_timer = 0;
}
bt_wait_connect_and_phone_connect_switch(0);
} else {
bt_wait_phone_connect_control(1);
}
break;
default:
break;
}
break;
default:
break;
}
return 0;
}
//蓝牙协议栈事件处理
int app_music_bt_event_handler(struct sys_event *event)
{
if (event->from == BT_EVENT_FROM_CON) {
return bt_connction_status_event_handler((struct bt_event *)event->payload);
} else if (event->from == BT_EVENT_FROM_HCI) {
return bt_hci_event_handler((struct bt_event *)event->payload);
}
return false;
}
//暂停/继续播放
static int bt_music_play_pause(void)
{
#if TCFG_USER_EMITTER_ENABLE
if (__this->emitter) {
return bt_emitter_stu_sw();
}
#endif
if (__this->phone_ring_flag) {
user_send_cmd_prepare(USER_CTRL_HFP_CALL_ANSWER, 0, NULL);
} else if (__this->call_flag) {
user_send_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
} else {
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PLAY, 0, NULL);
}
return 0;
}
//切换歌曲
static int bt_music_switch_song(int fsel_mode)
{
if (!__this->call_flag) {
if (fsel_mode == FSEL_NEXT_FILE) {
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_NEXT, 0, NULL);
} else if (fsel_mode == FSEL_PREV_FILE) {
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PREV, 0, NULL);
}
}
return 0;
}
//调整设备音量
static int bt_music_set_volume_step(int step)
{
union audio_req req = {0};
if (__this->media_play_flag) {
int volume = __this->media_volume + step;
if (volume < MIN_VOLUME_VALUE) {
volume = MIN_VOLUME_VALUE;
} else if (volume > MAX_VOLUME_VALUE) {
volume = MAX_VOLUME_VALUE;
}
if (volume == __this->media_volume) {
return 0;
}
__this->media_volume = volume;
__this->call_volume = volume;
if (step > 0) {
user_send_cmd_prepare(USER_CTRL_CMD_SYNC_VOL_INC, 0, NULL);
} else {
user_send_cmd_prepare(USER_CTRL_CMD_SYNC_VOL_DEC, 0, NULL);
}
if (__this->dec_server) {
req.dec.cmd = AUDIO_DEC_SET_VOLUME;
req.dec.volume = volume;
return server_request(__this->dec_server, AUDIO_REQ_DEC, &req);
}
} else if (__this->call_flag) {
int volume = __this->call_volume + step;
if (volume < MIN_VOLUME_VALUE) {
volume = MIN_VOLUME_VALUE;
} else if (volume > MAX_VOLUME_VALUE) {
volume = MAX_VOLUME_VALUE;
}
if (volume == __this->call_volume) {
return 0;
}
__this->media_volume = volume;
__this->call_volume = volume * 127 / 100;
if (step > 0) {
user_send_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_UP, 0, NULL);
} else {
user_send_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_DOWN, 0, NULL);
}
if (__this->dec_server) {
req.dec.cmd = AUDIO_DEC_SET_VOLUME;
req.dec.volume = volume;
return server_request(__this->dec_server, AUDIO_REQ_DEC, &req);
}
}
return 0;
}
int bt_music_key_event_handler(struct key_event *key)
{
switch (key->action) {
case KEY_EVENT_CLICK:
switch (key->value) {
case KEY_OK:
bt_music_play_pause();
break;
case KEY_VOLUME_DEC:
if (__this->emitter) {
#if TCFG_USER_EMITTER_ENABLE
bt_emitter_enc_gain_set(-VOLUME_STEP);
#endif
} else {
bt_music_set_volume_step(-VOLUME_STEP);
}
break;
case KEY_VOLUME_INC:
if (__this->emitter) {
#if TCFG_USER_EMITTER_ENABLE
bt_emitter_enc_gain_set(VOLUME_STEP);
#endif
} else {
bt_music_set_volume_step(VOLUME_STEP);
}
break;
case KEY_MODE:
if (__this->enable) {
bt_connection_disable();
} else {
bt_connection_enable();
}
break;
default:
break;
}
break;
case KEY_EVENT_LONG:
switch (key->value) {
case KEY_OK:
break;
case KEY_VOLUME_DEC:
if (!__this->emitter) {
bt_music_switch_song(FSEL_PREV_FILE);
}
break;
case KEY_VOLUME_INC:
if (!__this->emitter) {
bt_music_switch_song(FSEL_NEXT_FILE);
}
break;
case KEY_MODE:
#if TCFG_USER_EMITTER_ENABLE
//发射器或者接收器切换
if (__this->enable) {
if (__this->emitter) {
bt_emitter_disable();
} else {
key_event_disable();
bt_connection_disable();
sys_timeout_add(NULL, bt_emitter_enable, 1000);
}
}
#endif
break;
default:
break;
}
break;
default:
break;
}
return false;
}
#endif