2155 lines
73 KiB
C++
2155 lines
73 KiB
C++
|
/***************************************************************************
|
|||
|
*
|
|||
|
* Copyright 2015-2019 BES.
|
|||
|
* All rights reserved. All unpublished rights reserved.
|
|||
|
*
|
|||
|
* No part of this work may be used or reproduced in any form or by any
|
|||
|
* means, or stored in a database or retrieval system, without prior written
|
|||
|
* permission of BES.
|
|||
|
*
|
|||
|
* Use of this work is governed by a license granted by BES.
|
|||
|
* This work contains confidential and proprietary information of
|
|||
|
* BES. which is protected by copyright, trade secret,
|
|||
|
* trademark and other intellectual property rights.
|
|||
|
*
|
|||
|
****************************************************************************/
|
|||
|
//#include "mbed.h"
|
|||
|
#include <stdio.h>
|
|||
|
#include "cmsis_os.h"
|
|||
|
#include "hal_uart.h"
|
|||
|
#include "hal_timer.h"
|
|||
|
#include "audioflinger.h"
|
|||
|
#include "lockcqueue.h"
|
|||
|
#include "hal_trace.h"
|
|||
|
#include "hal_cmu.h"
|
|||
|
#include "hal_chipid.h"
|
|||
|
#include "analog.h"
|
|||
|
#include "app_audio.h"
|
|||
|
#include "app_battery.h"
|
|||
|
#include "app_status_ind.h"
|
|||
|
#include "bluetooth.h"
|
|||
|
#include "nvrecord.h"
|
|||
|
#include "nvrecord_env.h"
|
|||
|
#include "nvrecord_dev.h"
|
|||
|
#if defined(NEW_NV_RECORD_ENABLED)
|
|||
|
#include "nvrecord_bt.h"
|
|||
|
#endif
|
|||
|
#include "hfp_api.h"
|
|||
|
#include "besbt.h"
|
|||
|
#include "cqueue.h"
|
|||
|
#include "btapp.h"
|
|||
|
#include "app_bt.h"
|
|||
|
#include "apps.h"
|
|||
|
#include "resources.h"
|
|||
|
#include "app_bt_media_manager.h"
|
|||
|
#include "bt_if.h"
|
|||
|
#include "app_hfp.h"
|
|||
|
#include "app_fp_rfcomm.h"
|
|||
|
#include "os_api.h"
|
|||
|
#include "app_bt_func.h"
|
|||
|
#ifdef BT_USB_AUDIO_DUAL_MODE
|
|||
|
#include "btusb_audio.h"
|
|||
|
#endif
|
|||
|
#ifdef __THIRDPARTY
|
|||
|
#include "app_thirdparty.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#include "bt_drv_interface.h"
|
|||
|
|
|||
|
#ifdef __IAG_BLE_INCLUDE__
|
|||
|
#include "app_ble_mode_switch.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef VOICE_DATAPATH
|
|||
|
#include "app_voicepath.h"
|
|||
|
#endif
|
|||
|
#include "app.h"
|
|||
|
#ifdef __AI_VOICE__
|
|||
|
#include "ai_control.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(IBRT)
|
|||
|
#include "app_ibrt_if.h"
|
|||
|
#include "app_tws_ibrt_cmd_sync_hfp_status.h"
|
|||
|
#include "app_ibrt_hf.h"
|
|||
|
#include "besaud_api.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#include "bt_drv_reg_op.h"
|
|||
|
|
|||
|
#ifdef BISTO_ENABLED
|
|||
|
#include "gsound_custom_bt.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(__BTMAP_ENABLE__)
|
|||
|
#include "app_btmap_sms.h"
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
#ifdef __INTERCONNECTION__
|
|||
|
#define HF_COMMAND_HUAWEI_BATTERY_HEAD "AT+HUAWEIBATTERY="
|
|||
|
#define BATTERY_REPORT_NUM 2
|
|||
|
#define BATTERY_REPORT_TYPE_BATTERY_LEVEL 1
|
|||
|
#define BATTERY_REPORT_KEY_LEFT_BATTERY_LEVEL 2
|
|||
|
#define BATTERY_REPORT_KEY_LEFT_CHARGE_STATE 3
|
|||
|
char ATCommand[42];
|
|||
|
const char* huawei_self_defined_command_response = "+HUAWEIBATTERY=OK";
|
|||
|
#endif
|
|||
|
|
|||
|
/* hfp */
|
|||
|
int store_voicebtpcm_m2p_buffer(unsigned char *buf, unsigned int len);
|
|||
|
int get_voicebtpcm_p2m_frame(unsigned char *buf, unsigned int len);
|
|||
|
|
|||
|
int store_voicecvsd_buffer(unsigned char *buf, unsigned int len);
|
|||
|
int store_voicemsbc_buffer(unsigned char *buf, unsigned int len);
|
|||
|
|
|||
|
void btapp_hfp_mic_need_skip_frame_set(int32_t skip_frame);
|
|||
|
void a2dp_dual_slave_handling_refresh(void);
|
|||
|
void a2dp_dual_slave_setup_during_sco(enum BT_DEVICE_ID_T currentId);
|
|||
|
|
|||
|
extern "C" bool bt_media_cur_is_bt_stream_media(void);
|
|||
|
bool bt_is_sco_media_open();
|
|||
|
extern bool app_audio_list_playback_exist(void);
|
|||
|
#ifdef GFPS_ENABLED
|
|||
|
extern "C" void app_exit_fastpairing_mode(void);
|
|||
|
#endif
|
|||
|
|
|||
|
extern void app_bt_profile_connect_manager_hf(enum BT_DEVICE_ID_T id, hf_chan_handle_t Chan, struct hfp_context *ctx);
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
extern void hfcall_next_sta_handler(hf_event_t event);
|
|||
|
#endif
|
|||
|
#ifndef _SCO_BTPCM_CHANNEL_
|
|||
|
struct hf_sendbuff_control hf_sendbuff_ctrl;
|
|||
|
#endif
|
|||
|
#ifdef __INTERACTION__
|
|||
|
const char* oppo_self_defined_command_response = "+VDSF:7";
|
|||
|
#endif
|
|||
|
#if defined(SCO_LOOP)
|
|||
|
#define HF_LOOP_CNT (20)
|
|||
|
#define HF_LOOP_SIZE (360)
|
|||
|
|
|||
|
static uint8_t hf_loop_buffer[HF_LOOP_CNT*HF_LOOP_SIZE];
|
|||
|
static uint32_t hf_loop_buffer_len[HF_LOOP_CNT];
|
|||
|
static uint32_t hf_loop_buffer_valid = 1;
|
|||
|
static uint32_t hf_loop_buffer_size = 0;
|
|||
|
static char hf_loop_buffer_w_idx = 0;
|
|||
|
#endif
|
|||
|
|
|||
|
static void app_hfp_set_starting_media_pending_flag(bool isEnabled, uint8_t devId);
|
|||
|
void app_hfp_resume_pending_voice_media(void);
|
|||
|
|
|||
|
static void app_hfp_mediaplay_delay_resume_timer_cb(void const *n)
|
|||
|
{
|
|||
|
app_hfp_resume_pending_voice_media();
|
|||
|
}
|
|||
|
|
|||
|
#define HFP_MEDIAPLAY_DELAY_RESUME_IN_MS 3000//This time must be greater than SOUND_CONNECTED play time.
|
|||
|
static void app_hfp_mediaplay_delay_resume_timer_cb(void const *n);
|
|||
|
osTimerDef (APP_HFP_MEDIAPLAY_DELAY_RESUME_TIMER, app_hfp_mediaplay_delay_resume_timer_cb);
|
|||
|
osTimerId app_hfp_mediaplay_delay_resume_timer_id = NULL;
|
|||
|
|
|||
|
#ifdef __IAG_BLE_INCLUDE__
|
|||
|
static void app_hfp_resume_ble_adv(void);
|
|||
|
#endif
|
|||
|
|
|||
|
#define HFP_AUDIO_CLOSED_DELAY_RESUME_ADV_IN_MS 1500
|
|||
|
static void app_hfp_audio_closed_delay_resume_ble_adv_timer_cb(void const *n);
|
|||
|
osTimerDef (APP_HFP_AUDIO_CLOSED_DELAY_RESUME_BLE_ADV_TIMER,
|
|||
|
app_hfp_audio_closed_delay_resume_ble_adv_timer_cb);
|
|||
|
osTimerId app_hfp_audio_closed_delay_resume_ble_adv_timer_id = NULL;
|
|||
|
|
|||
|
extern struct BT_DEVICE_T app_bt_device;
|
|||
|
|
|||
|
#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS)
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
static uint8_t battery_level[BT_DEVICE_NUM] = {0xff, 0xff};
|
|||
|
#else
|
|||
|
static uint8_t battery_level[BT_DEVICE_NUM] = {0xff};
|
|||
|
#endif
|
|||
|
|
|||
|
static uint8_t report_battery_level = 0xff;
|
|||
|
void app_hfp_set_battery_level(uint8_t level)
|
|||
|
{
|
|||
|
osapi_lock_stack();
|
|||
|
if (report_battery_level == 0xff) {
|
|||
|
report_battery_level = level;
|
|||
|
osapi_notify_evm();
|
|||
|
}
|
|||
|
osapi_unlock_stack();
|
|||
|
}
|
|||
|
|
|||
|
int app_hfp_battery_report_reset(uint8_t bt_device_id)
|
|||
|
{
|
|||
|
ASSERT(bt_device_id < BT_DEVICE_NUM, "bt_device_id error");
|
|||
|
battery_level[bt_device_id] = 0xff;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef __INTERACTION_CUSTOMER_AT_COMMAND__
|
|||
|
#define HF_COMMAND_BATTERY_HEAD "AT+VDBTY="
|
|||
|
#define HF_COMMAND_VERSION_HEAD "AT+VDRV="
|
|||
|
#define HF_COMMAND_FEATURE_HEAD "AT+VDSF="
|
|||
|
#define REPORT_NUM 3
|
|||
|
#define LEFT_UNIT_REPORT 1
|
|||
|
#define RIGHT_UNIT_REPORT 2
|
|||
|
#define BOX_REPORT 3
|
|||
|
char ATCommand[42];
|
|||
|
|
|||
|
bt_status_t Send_customer_battery_report_AT_command(hf_chan_handle_t chan_h, uint8_t level)
|
|||
|
{
|
|||
|
TRACE(0,"Send battery report at commnad.");
|
|||
|
/// head and keyNumber
|
|||
|
sprintf(ATCommand, "%s%d", HF_COMMAND_BATTERY_HEAD,REPORT_NUM);
|
|||
|
/// keys and corresponding values
|
|||
|
sprintf(ATCommand, "%s,%d,%d,%d,%d,%d,%d\r", ATCommand, LEFT_UNIT_REPORT, level, RIGHT_UNIT_REPORT, level, BOX_REPORT, 9);
|
|||
|
/// send AT command
|
|||
|
return btif_hf_send_at_cmd(chan_h, ATCommand);
|
|||
|
}
|
|||
|
|
|||
|
bt_status_t Send_customer_phone_feature_support_AT_command(hf_chan_handle_t chan_h, uint8_t val)
|
|||
|
{
|
|||
|
TRACE(0,"Send_customer_phone_feature_support_AT_command.");
|
|||
|
/// keys and corresponding values
|
|||
|
sprintf(ATCommand, "%s%d\r", HF_COMMAND_FEATURE_HEAD,val);
|
|||
|
/// send AT command
|
|||
|
return btif_hf_send_at_cmd(chan_h, ATCommand);
|
|||
|
}
|
|||
|
|
|||
|
bt_status_t Send_customer_version_report_AT_command(hf_chan_handle_t chan_h)
|
|||
|
{
|
|||
|
TRACE(0,"Send version report at commnad.");
|
|||
|
/// head and keyNumber
|
|||
|
sprintf(ATCommand, "%s%d", HF_COMMAND_VERSION_HEAD,REPORT_NUM);
|
|||
|
/// keys and corresponding values
|
|||
|
sprintf(ATCommand, "%s,%d,%d,%d,%d,%d,%d\r", ATCommand, LEFT_UNIT_REPORT, 0x1111, RIGHT_UNIT_REPORT, 0x2222, BOX_REPORT,0x3333);
|
|||
|
/// send AT command
|
|||
|
return btif_hf_send_at_cmd(chan_h, ATCommand);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __INTERCONNECTION__
|
|||
|
uint8_t ask_is_selfdefined_battery_report_AT_command_support(void)
|
|||
|
{
|
|||
|
TRACE(0,"ask if mobile support self-defined at commnad.");
|
|||
|
uint8_t *pSelfDefinedCommandSupport = app_battery_get_mobile_support_self_defined_command_p();
|
|||
|
*pSelfDefinedCommandSupport = 0;
|
|||
|
|
|||
|
sprintf(ATCommand, "%s?", HF_COMMAND_HUAWEI_BATTERY_HEAD);
|
|||
|
btif_hf_send_at_cmd((hf_chan_handle_t)app_bt_device.hf_channel[BT_DEVICE_ID_1], ATCommand);
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
uint8_t send_selfdefined_battery_report_AT_command(void)
|
|||
|
{
|
|||
|
uint8_t *pSelfDefinedCommandSupport = app_battery_get_mobile_support_self_defined_command_p();
|
|||
|
uint8_t batteryInfo = 0;
|
|||
|
|
|||
|
if(*pSelfDefinedCommandSupport)
|
|||
|
{
|
|||
|
app_battery_get_info(NULL, &batteryInfo, NULL);
|
|||
|
|
|||
|
/// head and keyNumber
|
|||
|
sprintf(ATCommand, "%s%d", HF_COMMAND_HUAWEI_BATTERY_HEAD, BATTERY_REPORT_NUM);
|
|||
|
|
|||
|
/// keys and corresponding values
|
|||
|
sprintf(ATCommand, "%s,%d,%d,%d,%d", ATCommand, BATTERY_REPORT_KEY_LEFT_BATTERY_LEVEL, batteryInfo&0x7f, BATTERY_REPORT_KEY_LEFT_CHARGE_STATE, (batteryInfo&0x80)?1:0);
|
|||
|
|
|||
|
/// send AT command
|
|||
|
btif_hf_send_at_cmd((hf_chan_handle_t)app_bt_device.hf_channel[BT_DEVICE_ID_1], ATCommand);
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
int app_hfp_battery_report(uint8_t level)
|
|||
|
{
|
|||
|
// Care: BT_DEVICE_NUM<-->{0xff, 0xff, ...}
|
|||
|
bt_status_t status = BT_STS_LAST_CODE;
|
|||
|
hf_chan_handle_t chan;
|
|||
|
|
|||
|
uint8_t i;
|
|||
|
int nRet = 0;
|
|||
|
|
|||
|
if (level>9)
|
|||
|
return -1;
|
|||
|
|
|||
|
for(i=0; i<BT_DEVICE_NUM; i++)
|
|||
|
{
|
|||
|
chan = app_bt_device.hf_channel[i];
|
|||
|
if (btif_get_hf_chan_state(chan) == BTIF_HF_STATE_OPEN)
|
|||
|
{
|
|||
|
if (btif_hf_is_hf_indicators_support(chan))
|
|||
|
{
|
|||
|
if (battery_level[i] != level)
|
|||
|
{
|
|||
|
uint8_t assigned_num = 2;///battery level assigned num:2
|
|||
|
status = btif_hf_update_indicators_batt_level(chan, assigned_num, level);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (btif_hf_is_batt_report_support(chan))
|
|||
|
{
|
|||
|
if (battery_level[i] != level)
|
|||
|
{
|
|||
|
#ifdef GFPS_ENABLED
|
|||
|
app_fp_msg_send_battery_levels();
|
|||
|
#endif
|
|||
|
#ifdef __INTERACTION_CUSTOMER_AT_COMMAND__
|
|||
|
status = Send_customer_battery_report_AT_command(chan, level);
|
|||
|
#endif
|
|||
|
status = btif_hf_batt_report(chan, level);
|
|||
|
}
|
|||
|
}
|
|||
|
if (BT_STS_PENDING == status){
|
|||
|
battery_level[i] = level;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
nRet = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
battery_level[i] = 0xff;
|
|||
|
nRet = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
return nRet;
|
|||
|
}
|
|||
|
|
|||
|
void app_hfp_battery_report_proc(void)
|
|||
|
{
|
|||
|
osapi_lock_stack();
|
|||
|
|
|||
|
if(report_battery_level != 0xff)
|
|||
|
{
|
|||
|
app_hfp_battery_report(report_battery_level);
|
|||
|
report_battery_level = 0xff;
|
|||
|
}
|
|||
|
osapi_unlock_stack();
|
|||
|
}
|
|||
|
|
|||
|
bt_status_t app_hfp_send_at_command(const char *cmd)
|
|||
|
{
|
|||
|
bt_status_t ret = 0;
|
|||
|
//send AT command
|
|||
|
ret = btif_hf_send_at_cmd((hf_chan_handle_t)app_bt_device.hf_channel[BT_DEVICE_ID_1], cmd);
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
void a2dp_get_curStream_remDev(btif_remote_device_t **p_remDev);
|
|||
|
|
|||
|
bool app_hfp_curr_audio_up(hf_chan_handle_t hfp_chnl)
|
|||
|
{
|
|||
|
int i = 0;
|
|||
|
for(i=0;i<BT_DEVICE_NUM;i++)
|
|||
|
{
|
|||
|
if (app_bt_device.hf_channel[i] == hfp_chnl) {
|
|||
|
return app_bt_device.hf_conn_flag[i] && app_bt_device.hf_audio_state[i] == BTIF_HF_AUDIO_CON;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
uint8_t app_hfp_get_chnl_via_remDev(hf_chan_handle_t *p_hfp_chnl)
|
|||
|
{
|
|||
|
uint8_t i =0;
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
btif_remote_device_t *p_a2dp_remDev;
|
|||
|
btif_remote_device_t *p_hfp_remDev;
|
|||
|
|
|||
|
a2dp_get_curStream_remDev(&p_a2dp_remDev);
|
|||
|
for(i=0;i<BT_DEVICE_NUM;i++)
|
|||
|
{
|
|||
|
p_hfp_remDev = (btif_remote_device_t *)btif_hf_cmgr_get_remote_device(app_bt_device.hf_channel[i]);
|
|||
|
if(p_hfp_remDev == p_a2dp_remDev)
|
|||
|
break;
|
|||
|
}
|
|||
|
if(i != BT_DEVICE_NUM)
|
|||
|
*p_hfp_chnl = app_bt_device.hf_channel[i];
|
|||
|
#else
|
|||
|
i = BT_DEVICE_ID_1;
|
|||
|
*p_hfp_chnl = app_bt_device.hf_channel[i];
|
|||
|
#endif
|
|||
|
return i;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef SUPPORT_SIRI
|
|||
|
int app_hfp_siri_report()
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
bt_status_t status = BT_STS_LAST_CODE;
|
|||
|
hf_chan_handle_t chan;
|
|||
|
|
|||
|
for(i=0; i<BT_DEVICE_NUM; i++) {
|
|||
|
chan = app_bt_device.hf_channel[i];
|
|||
|
if (btif_get_hf_chan_state(chan) == BTIF_HF_STATE_OPEN) {
|
|||
|
status = btif_hf_siri_report(chan);
|
|||
|
if (status == BT_STS_PENDING){
|
|||
|
return 0;
|
|||
|
} else {
|
|||
|
return -1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
extern int open_siri_flag ;
|
|||
|
int app_hfp_siri_voice(bool en)
|
|||
|
{
|
|||
|
static enum BT_DEVICE_ID_T hf_id = BT_DEVICE_ID_1;
|
|||
|
bt_status_t res = BT_STS_LAST_CODE;
|
|||
|
|
|||
|
hf_chan_handle_t POSSIBLY_UNUSED hf_siri_chnl = NULL;
|
|||
|
if(open_siri_flag == 1){
|
|||
|
if(btif_hf_is_voice_rec_active(app_bt_device.hf_channel[hf_id]) == false){
|
|||
|
open_siri_flag = 0;
|
|||
|
TRACE(0,"end auto");
|
|||
|
}else{
|
|||
|
TRACE(0,"need close");
|
|||
|
en = false;
|
|||
|
}
|
|||
|
}
|
|||
|
if(open_siri_flag == 0){
|
|||
|
if(btif_hf_is_voice_rec_active(app_bt_device.hf_channel[BT_DEVICE_ID_1]) == true){
|
|||
|
TRACE(0,"1 ->close");
|
|||
|
hf_id = BT_DEVICE_ID_1;
|
|||
|
en = false;
|
|||
|
hf_siri_chnl = app_bt_device.hf_channel[BT_DEVICE_ID_1];
|
|||
|
}
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
else if(btif_hf_is_voice_rec_active(app_bt_device.hf_channel[BT_DEVICE_ID_2]) == true){
|
|||
|
TRACE(0,"2->close");
|
|||
|
hf_id = BT_DEVICE_ID_2;
|
|||
|
en = false;
|
|||
|
hf_siri_chnl = app_bt_device.hf_channel[BT_DEVICE_ID_2];
|
|||
|
}
|
|||
|
#endif
|
|||
|
else{
|
|||
|
open_siri_flag =1;
|
|||
|
en = true;
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
hf_id = (enum BT_DEVICE_ID_T)app_hfp_get_chnl_via_remDev(&hf_siri_chnl);
|
|||
|
#else
|
|||
|
hf_id = BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
TRACE(1,"a2dp id = %d",hf_id);
|
|||
|
}
|
|||
|
}
|
|||
|
TRACE(4,"[%s]id =%d/%d/%d",__func__,hf_id,open_siri_flag,en);
|
|||
|
if(hf_id == BT_DEVICE_NUM)
|
|||
|
hf_id = BT_DEVICE_ID_1;
|
|||
|
|
|||
|
if((btif_get_hf_chan_state(app_bt_device.hf_channel[hf_id]) == BTIF_HF_STATE_OPEN)) {
|
|||
|
res = btif_hf_enable_voice_recognition(app_bt_device.hf_channel[hf_id], en);
|
|||
|
}
|
|||
|
|
|||
|
TRACE(3,"[%s] Line =%d, res = %d", __func__, __LINE__, res);
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#define _THREE_WAY_ONE_CALL_COUNT__ 1
|
|||
|
#ifdef _THREE_WAY_ONE_CALL_COUNT__
|
|||
|
static enum BT_DEVICE_ID_T hfp_cur_call_chnl = BT_DEVICE_NUM;
|
|||
|
static int8_t cur_chnl_call_on_active[BT_DEVICE_NUM] = {0};
|
|||
|
int app_bt_get_audio_up_id(void);
|
|||
|
|
|||
|
void app_hfp_3_way_call_counter_set(enum BT_DEVICE_ID_T id,uint8_t set)
|
|||
|
{
|
|||
|
if (set > 0) {
|
|||
|
cur_chnl_call_on_active[id]++;
|
|||
|
if (cur_chnl_call_on_active[id] > BT_DEVICE_NUM)
|
|||
|
cur_chnl_call_on_active[id] = 2;
|
|||
|
} else {
|
|||
|
cur_chnl_call_on_active[id]--;
|
|||
|
if (cur_chnl_call_on_active[id] < 0)
|
|||
|
cur_chnl_call_on_active[id] = 0;
|
|||
|
if (app_bt_device.hfchan_call[id] == 1)
|
|||
|
cur_chnl_call_on_active[id] = 1;
|
|||
|
}
|
|||
|
TRACE(1,"call_on_active = %d",cur_chnl_call_on_active[id]);
|
|||
|
}
|
|||
|
|
|||
|
void app_hfp_set_cur_chnl_id(uint8_t id)
|
|||
|
{
|
|||
|
if (hfp_cur_call_chnl == BT_DEVICE_NUM) {
|
|||
|
hfp_cur_call_chnl = (enum BT_DEVICE_ID_T)id;
|
|||
|
cur_chnl_call_on_active[id] = 1;
|
|||
|
}
|
|||
|
TRACE(3,"%s hfp_cur_call_chnl = %d id=%d",__func__,hfp_cur_call_chnl,id);
|
|||
|
}
|
|||
|
|
|||
|
uint8_t app_hfp_get_cur_call_chnl(void ** chnl)
|
|||
|
{
|
|||
|
TRACE(2,"%s hfp_cur_call_chnl = %d",__func__,hfp_cur_call_chnl);
|
|||
|
if(hfp_cur_call_chnl != BT_DEVICE_NUM){
|
|||
|
return hfp_cur_call_chnl;
|
|||
|
}
|
|||
|
return BT_DEVICE_NUM;
|
|||
|
}
|
|||
|
|
|||
|
void app_hfp_clear_cur_call_chnl(enum BT_DEVICE_ID_T id)
|
|||
|
{
|
|||
|
hfp_cur_call_chnl = BT_DEVICE_NUM;
|
|||
|
cur_chnl_call_on_active[id] = 0;
|
|||
|
TRACE(2,"%s id= %d",__func__,id);
|
|||
|
}
|
|||
|
|
|||
|
void app_hfp_cur_call_chnl_reset(enum BT_DEVICE_ID_T id)
|
|||
|
{
|
|||
|
if(id == hfp_cur_call_chnl)
|
|||
|
hfp_cur_call_chnl = BT_DEVICE_NUM;
|
|||
|
TRACE(3,"%s hfp_cur_call_chnl = %d id=%d",__func__,hfp_cur_call_chnl,id);
|
|||
|
}
|
|||
|
|
|||
|
bool app_hfp_cur_chnl_is_on_3_way_calling(void)
|
|||
|
{
|
|||
|
uint8_t i = 0;
|
|||
|
TRACE(1,"hfp_cur_call_chnl = %d",hfp_cur_call_chnl);
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
TRACE(2,"cur_chnl_call_on_active[0] = %d [1] = %d",cur_chnl_call_on_active[0],
|
|||
|
cur_chnl_call_on_active[1]);
|
|||
|
#else
|
|||
|
TRACE(1,"cur_chnl_call_on_active[0] = %d",cur_chnl_call_on_active[0]);
|
|||
|
#endif
|
|||
|
if(hfp_cur_call_chnl == BT_DEVICE_NUM)
|
|||
|
return false;
|
|||
|
for(i=0;i<BT_DEVICE_NUM;i++){
|
|||
|
if(cur_chnl_call_on_active[i] >1){
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if(i == BT_DEVICE_NUM)
|
|||
|
return false;
|
|||
|
return true;
|
|||
|
}
|
|||
|
#endif
|
|||
|
#if !defined(FPGA) && defined(__BTIF_EARPHONE__)
|
|||
|
static void hfp_app_status_indication(enum BT_DEVICE_ID_T chan_id, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
enum BT_DEVICE_ID_T chan_id_other = (chan_id==BT_DEVICE_ID_1)?(BT_DEVICE_ID_2):(BT_DEVICE_ID_1);
|
|||
|
#else
|
|||
|
enum BT_DEVICE_ID_T chan_id_other =BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
switch(ctx->event)
|
|||
|
{
|
|||
|
/*
|
|||
|
case HF_EVENT_SERVICE_CONNECTED:
|
|||
|
break;
|
|||
|
case HF_EVENT_SERVICE_DISCONNECTED:
|
|||
|
break;
|
|||
|
*/
|
|||
|
case BTIF_HF_EVENT_CURRENT_CALL_STATE:
|
|||
|
TRACE(2,"!!!HF_EVENT_CURRENT_CALL_STATE chan_id:%d, call_number:%s\n", chan_id, ctx->call_number);
|
|||
|
if(app_bt_device.hfchan_callSetup[chan_id] == BTIF_HF_CALL_SETUP_IN){
|
|||
|
//////report incoming call number
|
|||
|
//app_status_set_num(ctx->call_number);
|
|||
|
#ifdef __BT_WARNING_TONE_MERGE_INTO_STREAM_SBC__
|
|||
|
app_voice_report(APP_STATUS_RING_WARNING,chan_id);
|
|||
|
#endif
|
|||
|
}
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_CALL_IND:
|
|||
|
if(ctx->call == BTIF_HF_CALL_NONE && app_bt_device.hfchan_call[chan_id] == BTIF_HF_CALL_ACTIVE){
|
|||
|
//////report call hangup voice
|
|||
|
TRACE(1,"!!!HF_EVENT_CALL_IND APP_STATUS_INDICATION_HANGUPCALL chan_id:%d\n",chan_id);
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA,BT_STREAM_VOICE,chan_id,0);
|
|||
|
///disable media prompt
|
|||
|
if(app_bt_device.hf_endcall_dis[chan_id] == false)
|
|||
|
{
|
|||
|
TRACE(0,"HANGUPCALL PROMPT");
|
|||
|
//app_voice_report(APP_STATUS_INDICATION_HANGUPCALL,chan_id);
|
|||
|
}
|
|||
|
#if defined(_THREE_WAY_ONE_CALL_COUNT__)
|
|||
|
if(app_hfp_get_cur_call_chnl(NULL) == chan_id){
|
|||
|
app_hfp_clear_cur_call_chnl(chan_id);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if defined(_THREE_WAY_ONE_CALL_COUNT__)
|
|||
|
else if((ctx->call == BTIF_HF_CALL_ACTIVE) &&
|
|||
|
(app_bt_get_audio_up_id() == chan_id))
|
|||
|
{
|
|||
|
app_hfp_set_cur_chnl_id(chan_id);
|
|||
|
}
|
|||
|
#endif
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_CALLSETUP_IND:
|
|||
|
if(ctx->call_setup == BTIF_HF_CALL_SETUP_NONE &&
|
|||
|
(app_bt_device.hfchan_call[chan_id] != BTIF_HF_CALL_ACTIVE) &&
|
|||
|
(app_bt_device.hfchan_callSetup[chan_id] != BTIF_HF_CALL_SETUP_NONE)) {
|
|||
|
////check the call refuse and stop media of (ring and call number)
|
|||
|
TRACE(1,"!!!HF_EVENT_CALLSETUP_IND APP_STATUS_INDICATION_REFUSECALL chan_id:%d\n",chan_id);
|
|||
|
#if 0//def __BT_ONE_BRING_TWO__
|
|||
|
if (app_bt_device.hf_audio_state[chan_id_other] == BTIF_HF_AUDIO_DISCON){
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA,BT_STREAM_VOICE,chan_id,0);
|
|||
|
app_voice_report(APP_STATUS_INDICATION_REFUSECALL,chan_id);
|
|||
|
}
|
|||
|
#else
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA,BT_STREAM_VOICE,chan_id,0);
|
|||
|
#if !defined(IBRT) && defined(MEDIA_PLAYER_SUPPORT)
|
|||
|
app_voice_report(APP_STATUS_INDICATION_REFUSECALL,chan_id);/////////////du<64><75><EFBFBD><EFBFBD>
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
if((app_bt_device.hfchan_call[chan_id_other] == BTIF_HF_CALL_ACTIVE) &&
|
|||
|
(app_bt_device.hf_audio_state[chan_id_other] == BTIF_HF_AUDIO_CON)){
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_other;
|
|||
|
}
|
|||
|
}else if(ctx->call_setup == BTIF_HF_CALL_SETUP_NONE &&
|
|||
|
(app_bt_device.hfchan_callSetup[chan_id] != BTIF_HF_CALL_SETUP_NONE) &&
|
|||
|
(app_bt_device.hfchan_call[chan_id] == BTIF_HF_CALL_ACTIVE)){
|
|||
|
TRACE(1,"!!!HF_EVENT_CALLSETUP_IND APP_STATUS_INDICATION_ANSWERCALL but noneed sco chan_id:%d\n",chan_id);
|
|||
|
#ifdef _THREE_WAY_ONE_CALL_COUNT__
|
|||
|
if(app_bt_device.hf_callheld[chan_id] == BTIF_HF_CALL_HELD_NONE) {
|
|||
|
if(app_hfp_get_cur_call_chnl(NULL) == chan_id) {
|
|||
|
app_hfp_3_way_call_counter_set(chan_id,0);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif /* _THREE_WAY_ONE_CALL_COUNT__ */
|
|||
|
|
|||
|
#ifdef MEDIA_PLAYER_SUPPORT
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA, BT_STREAM_MEDIA ,chan_id, 0);
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if defined(_THREE_WAY_ONE_CALL_COUNT__)
|
|||
|
else if((ctx->call_setup != BTIF_HF_CALL_SETUP_NONE) &&
|
|||
|
(app_bt_device.hfchan_call[chan_id] == BTIF_HF_CALL_ACTIVE)){
|
|||
|
if(app_hfp_get_cur_call_chnl(NULL) == chan_id){
|
|||
|
app_hfp_3_way_call_counter_set(chan_id,1);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
break;
|
|||
|
/*
|
|||
|
case HF_EVENT_AUDIO_CONNECTED:
|
|||
|
TRACE(1,"!!!HF_EVENT_AUDIO_CONNECTED APP_STATUS_INDICATION_ANSWERCALL chan_id:%d\n",chan_id);
|
|||
|
// app_voice_report(APP_STATUS_INDICATION_ANSWERCALL,chan_id);//////////////duһ<75><D2BB>
|
|||
|
break;
|
|||
|
*/
|
|||
|
case BTIF_HF_EVENT_RING_IND:
|
|||
|
#ifdef MEDIA_PLAYER_SUPPORT
|
|||
|
app_voice_report(APP_STATUS_INDICATION_INCOMINGCALL,chan_id);
|
|||
|
#endif
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
struct BT_DEVICE_ID_DIFF chan_id_flag;
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
void hfp_chan_id_distinguish(hf_chan_handle_t chan)
|
|||
|
{
|
|||
|
if(chan == app_bt_device.hf_channel[BT_DEVICE_ID_1]){
|
|||
|
chan_id_flag.id = BT_DEVICE_ID_1;
|
|||
|
}else if(chan == app_bt_device.hf_channel[BT_DEVICE_ID_2]){
|
|||
|
chan_id_flag.id = BT_DEVICE_ID_2;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
int hfp_volume_get(enum BT_DEVICE_ID_T id)
|
|||
|
{
|
|||
|
int vol = TGT_VOLUME_LEVEL_15;
|
|||
|
|
|||
|
nvrec_btdevicerecord *record = NULL;
|
|||
|
bt_bdaddr_t bdAdd;
|
|||
|
if (btif_hf_get_remote_bdaddr(app_bt_device.hf_channel[id], &bdAdd) && !nv_record_btdevicerecord_find(&bdAdd,&record)){
|
|||
|
vol = record->device_vol.hfp_vol - 2;
|
|||
|
}else if (app_audio_manager_hfp_is_active(id)){
|
|||
|
vol = app_bt_stream_hfpvolume_get() - 2;
|
|||
|
}else{
|
|||
|
vol = TGT_VOLUME_LEVEL_15;
|
|||
|
}
|
|||
|
|
|||
|
if (vol > 15)
|
|||
|
vol = 15;
|
|||
|
if (vol < 0)
|
|||
|
vol = 0;
|
|||
|
|
|||
|
#ifndef BES_AUTOMATE_TEST
|
|||
|
TRACE(2,"hfp get vol raw:%d loc:%d", vol, vol+2);
|
|||
|
#endif
|
|||
|
return (vol);
|
|||
|
}
|
|||
|
|
|||
|
void hfp_volume_local_set(enum BT_DEVICE_ID_T id, int8_t vol)
|
|||
|
{
|
|||
|
nvrec_btdevicerecord *record = NULL;
|
|||
|
bt_bdaddr_t bdAdd;
|
|||
|
if (btif_hf_get_remote_bdaddr(app_bt_device.hf_channel[id], &bdAdd)){
|
|||
|
if (!nv_record_btdevicerecord_find(&bdAdd,&record)){
|
|||
|
nv_record_btdevicerecord_set_hfp_vol(record, vol);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(app_bt_stream_volume_get_ptr()->hfp_vol != vol){
|
|||
|
#if defined(NEW_NV_RECORD_ENABLED)
|
|||
|
nv_record_btdevicevolume_set_hfp_vol(app_bt_stream_volume_get_ptr(), vol);
|
|||
|
#endif
|
|||
|
#ifndef FPGA
|
|||
|
nv_record_touch_cause_flush();
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int hfp_volume_set(enum BT_DEVICE_ID_T id, int vol)
|
|||
|
{
|
|||
|
if (vol > 15)
|
|||
|
vol = 15;
|
|||
|
if (vol < 0)
|
|||
|
vol = 0;
|
|||
|
|
|||
|
hfp_volume_local_set(id, vol+2);
|
|||
|
if (app_audio_manager_hfp_is_active(id)){
|
|||
|
app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_SET, vol+2);
|
|||
|
}
|
|||
|
|
|||
|
TRACE(2,"hfp put vol raw:%d loc:%d", vol, vol+2);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
static uint8_t call_setup_running_on = 0;
|
|||
|
void hfp_call_setup_running_on_set(uint8_t set)
|
|||
|
{
|
|||
|
call_setup_running_on = set;
|
|||
|
}
|
|||
|
|
|||
|
void hfp_call_setup_running_on_clr(void)
|
|||
|
{
|
|||
|
call_setup_running_on = 0;
|
|||
|
}
|
|||
|
|
|||
|
uint8_t hfp_get_call_setup_running_on_state(void)
|
|||
|
{
|
|||
|
TRACE(2,"%s state = %d",__func__,call_setup_running_on);
|
|||
|
return call_setup_running_on;
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_connected_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef GFPS_ENABLED
|
|||
|
app_exit_fastpairing_mode();
|
|||
|
#endif
|
|||
|
|
|||
|
app_bt_clear_connecting_profiles_state(chan_id_flag.id);
|
|||
|
|
|||
|
TRACE(1,"::HF_EVENT_SERVICE_CONNECTED Chan_id:%d\n", chan_id_flag.id);
|
|||
|
app_bt_device.phone_earphone_mark = 1;
|
|||
|
|
|||
|
#if !defined(FPGA) && defined(__BTIF_EARPHONE__)
|
|||
|
if (ctx->state == BTIF_HF_STATE_OPEN) {
|
|||
|
////report connected voice
|
|||
|
app_bt_device.hf_conn_flag[chan_id_flag.id] = 1;
|
|||
|
}
|
|||
|
#endif
|
|||
|
#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS)
|
|||
|
uint8_t battery_level;
|
|||
|
app_hfp_battery_report_reset(chan_id_flag.id);
|
|||
|
app_battery_get_info(NULL, &battery_level, NULL);
|
|||
|
app_hfp_set_battery_level(battery_level);
|
|||
|
#endif
|
|||
|
// app_bt_stream_hfpvolume_reset();
|
|||
|
btif_hf_report_speaker_volume(chan, hfp_volume_get(chan_id_flag.id));
|
|||
|
|
|||
|
#if defined(HFP_DISABLE_NREC)
|
|||
|
btif_hf_disable_nrec(chan);
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
////if a call is active and start bt open reconnect procedure, process the curr_hf_channel_id
|
|||
|
if((app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON)
|
|||
|
||(app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)){
|
|||
|
app_bt_device.curr_hf_channel_id = anotherDevice;
|
|||
|
}else{
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(__BTMAP_ENABLE__) && defined(BTIF_DIP_DEVICE)
|
|||
|
if ((btif_dip_get_process_status(app_bt_get_remoteDev(chan_id_flag.id)))&& (app_btmap_check_is_idle(chan_id_flag.id)))
|
|||
|
{
|
|||
|
app_btmap_sms_open(chan_id_flag.id, &ctx->remote_dev_bdaddr);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
app_bt_profile_connect_manager_hf(chan_id_flag.id, chan, ctx);
|
|||
|
#ifdef __INTERCONNECTION__
|
|||
|
ask_is_selfdefined_battery_report_AT_command_support();
|
|||
|
#endif
|
|||
|
#ifdef __INTERACTION_CUSTOMER_AT_COMMAND__
|
|||
|
Send_customer_phone_feature_support_AT_command(chan,7);
|
|||
|
Send_customer_battery_report_AT_command(chan, battery_level);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_disconnected_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
TRACE(2,"::HF_EVENT_SERVICE_DISCONNECTED Chan_id:%d, reason=%x\n", chan_id_flag.id, ctx->disc_reason);
|
|||
|
#if defined(HFP_1_6_ENABLE)
|
|||
|
btif_hf_set_negotiated_codec(chan, BTIF_HF_SCO_CODEC_CVSD);
|
|||
|
#endif
|
|||
|
#if !defined(FPGA) && defined(__BTIF_EARPHONE__)
|
|||
|
if(app_bt_device.hf_conn_flag[chan_id_flag.id] ){
|
|||
|
////report device disconnected voice
|
|||
|
app_bt_device.hf_conn_flag[chan_id_flag.id] = 0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_VOICE,chan_id_flag.id,MAX_RECORD_NUM);
|
|||
|
for (uint8_t i=0; i<BT_DEVICE_NUM; i++){
|
|||
|
if (chan == app_bt_device.hf_channel[i]) {
|
|||
|
app_bt_device.hfchan_call[i] = 0;
|
|||
|
app_bt_device.hfchan_callSetup[i] = 0;
|
|||
|
app_bt_device.hf_audio_state[i] = BTIF_HF_AUDIO_DISCON;
|
|||
|
app_bt_device.hf_conn_flag[i] = 0;
|
|||
|
app_bt_device.hf_voice_en[i] = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
app_bt_profile_connect_manager_hf(chan_id_flag.id, chan, ctx);
|
|||
|
}
|
|||
|
static void hfp_audio_data_sent_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#if defined(SCO_LOOP)
|
|||
|
hf_loop_buffer_valid = 1;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_audio_data_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
if(app_bt_device.hf_voice_en[chan_id_flag.id])
|
|||
|
{
|
|||
|
#endif
|
|||
|
|
|||
|
#ifndef _SCO_BTPCM_CHANNEL_
|
|||
|
uint32_t idx = 0;
|
|||
|
if (app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)){
|
|||
|
store_voicebtpcm_m2p_buffer(ctx->audio_data, ctx->audio_data_len);
|
|||
|
|
|||
|
idx = hf_sendbuff_ctrl.index % HF_SENDBUFF_MEMPOOL_NUM;
|
|||
|
get_voicebtpcm_p2m_frame(&(hf_sendbuff_ctrl.mempool[idx].buffer[0]), ctx->audio_data_len);
|
|||
|
hf_sendbuff_ctrl.mempool[idx].packet.data = &(hf_sendbuff_ctrl.mempool[idx].buffer[0]);
|
|||
|
hf_sendbuff_ctrl.mempool[idx].packet.dataLen = ctx->audio_data_len;
|
|||
|
hf_sendbuff_ctrl.mempool[idx].packet.flags = BTIF_BTP_FLAG_NONE;
|
|||
|
if(!app_bt_device.hf_mute_flag){
|
|||
|
btif_hf_send_audio_data(chan, &hf_sendbuff_ctrl.mempool[idx].packet);
|
|||
|
}
|
|||
|
hf_sendbuff_ctrl.index++;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(SCO_LOOP)
|
|||
|
memcpy(hf_loop_buffer + hf_loop_buffer_w_idx*HF_LOOP_SIZE, Info->p.audioData->data, Info->p.audioData->len);
|
|||
|
hf_loop_buffer_len[hf_loop_buffer_w_idx] = Info->p.audioData->len;
|
|||
|
hf_loop_buffer_w_idx = (hf_loop_buffer_w_idx+1)%HF_LOOP_CNT;
|
|||
|
++hf_loop_buffer_size;
|
|||
|
|
|||
|
if (hf_loop_buffer_size >= 18 && hf_loop_buffer_valid == 1) {
|
|||
|
hf_loop_buffer_valid = 0;
|
|||
|
idx = hf_loop_buffer_w_idx-17<0?(HF_LOOP_CNT-(17-hf_loop_buffer_w_idx)):hf_loop_buffer_w_idx-17;
|
|||
|
pkt.flags = BTP_FLAG_NONE;
|
|||
|
pkt.dataLen = hf_loop_buffer_len[idx];
|
|||
|
pkt.data = hf_loop_buffer + idx*HF_LOOP_SIZE;
|
|||
|
HF_SendAudioData(Chan, &pkt);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_call_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
TRACE(8,"::HF_EVENT_CALL_IND %d chan_id %dx call %d %d held %d %d audio_state %d %d\n",
|
|||
|
ctx->call, chan_id_flag.id,
|
|||
|
app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2],
|
|||
|
app_bt_device.hf_callheld[BT_DEVICE_ID_1], app_bt_device.hf_callheld[BT_DEVICE_ID_2],
|
|||
|
app_bt_device.hf_audio_state[BT_DEVICE_ID_1], app_bt_device.hf_audio_state[BT_DEVICE_ID_2]);
|
|||
|
#else
|
|||
|
TRACE(2,"::HF_EVENT_CALL_IND chan_id:%d, call:%d\n",chan_id_flag.id, ctx->call);
|
|||
|
#endif
|
|||
|
if(ctx->call == BTIF_HF_CALL_NONE)
|
|||
|
{
|
|||
|
hfp_call_setup_running_on_clr();
|
|||
|
#if defined(_AUTO_TEST_)
|
|||
|
AUTO_TEST_SEND("Call hangup ok.");
|
|||
|
#endif
|
|||
|
app_bt_device.hf_callheld[chan_id_flag.id] = BTIF_HF_CALL_HELD_NONE;
|
|||
|
}
|
|||
|
else if(ctx->call == BTIF_HF_CALL_ACTIVE)
|
|||
|
{
|
|||
|
#if defined(_AUTO_TEST_)
|
|||
|
AUTO_TEST_SEND("Call setup ok.");
|
|||
|
#endif
|
|||
|
|
|||
|
///call is active so check if it's a outgoing call
|
|||
|
if(app_bt_device.hfchan_callSetup[chan_id_flag.id] == BTIF_HF_CALL_SETUP_ALERT)
|
|||
|
{
|
|||
|
TRACE(1,"HF CALLACTIVE TIME=%d",hal_sys_timer_get());
|
|||
|
if(TICKS_TO_MS(hal_sys_timer_get()-app_bt_device.hf_callsetup_time[chan_id_flag.id])<1000)
|
|||
|
{
|
|||
|
TRACE(0,"DISABLE HANGUPCALL PROMPT");
|
|||
|
app_bt_device.hf_endcall_dis[chan_id_flag.id] = true;
|
|||
|
}
|
|||
|
}
|
|||
|
/////stop media of (ring and call number) and switch to sco
|
|||
|
#if defined (HFP_NO_PRERMPT)
|
|||
|
if(app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE){
|
|||
|
}else
|
|||
|
#endif
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
TRACE(1,"%s another %d,hf_callheld %d",__func__,anotherDevice,app_bt_device.hf_callheld[anotherDevice]);
|
|||
|
if((btapp_hfp_get_call_state())
|
|||
|
&&(app_bt_device.hf_callheld[anotherDevice] == BTIF_HF_CALL_HELD_NONE))
|
|||
|
#else
|
|||
|
if(btapp_hfp_get_call_state())
|
|||
|
#endif
|
|||
|
{
|
|||
|
TRACE(0,"DON'T SIWTCH_TO_SCO");
|
|||
|
app_bt_device.hfchan_call[chan_id_flag.id] = ctx->call;
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
#ifndef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWITCHTO_SCO,BT_STREAM_VOICE,chan_id_flag.id,0);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
#if defined(_AUTO_TEST_)
|
|||
|
AUTO_TEST_SEND("Call hangup ok.");
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if !defined(FPGA) && defined(__BTIF_EARPHONE__)
|
|||
|
hfp_app_status_indication(chan_id_flag.id, ctx);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
if(ctx->call == BTIF_HF_CALL_ACTIVE){
|
|||
|
#if defined (HFP_NO_PRERMPT)
|
|||
|
#else
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
#endif
|
|||
|
}
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
else if((ctx->call == BTIF_HF_CALL_NONE)&&
|
|||
|
((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)||
|
|||
|
(app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)||
|
|||
|
(app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_OUT) ||
|
|||
|
(app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_ALERT))){
|
|||
|
app_bt_device.curr_hf_channel_id = anotherDevice;
|
|||
|
}
|
|||
|
#endif
|
|||
|
TRACE(1,"!!!HF_EVENT_CALL_IND curr_hf_channel_id:%d\n",app_bt_device.curr_hf_channel_id);
|
|||
|
app_bt_device.hfchan_call[chan_id_flag.id] = ctx->call;
|
|||
|
if(ctx->call == BTIF_HF_CALL_NONE)
|
|||
|
{
|
|||
|
app_bt_device.hf_endcall_dis[chan_id_flag.id] = false;
|
|||
|
}
|
|||
|
#if defined( __BT_ONE_BRING_TWO__)
|
|||
|
if(bt_get_sco_number() > 1
|
|||
|
#ifdef CHIP_BEST1000
|
|||
|
&& hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2
|
|||
|
#endif
|
|||
|
){
|
|||
|
////a call is active:
|
|||
|
if(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE){
|
|||
|
#if !defined(HFP_NO_PRERMPT)
|
|||
|
if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
#ifdef __HF_KEEP_ONE_ALIVE__
|
|||
|
#ifdef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA
|
|||
|
if (bt_media_cur_is_bt_stream_media())
|
|||
|
{
|
|||
|
app_hfp_set_starting_media_pending_flag(true, chan_id_flag.id);
|
|||
|
}
|
|||
|
else
|
|||
|
#endif
|
|||
|
{
|
|||
|
app_hfp_start_voice_media(chan_id_flag.id);
|
|||
|
}
|
|||
|
#else
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWAP_SCO,BT_STREAM_SBC, chan_id_flag.id, 0);
|
|||
|
#endif
|
|||
|
}
|
|||
|
app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_ENABLE;
|
|||
|
app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_DISABLE;
|
|||
|
#endif
|
|||
|
}else{
|
|||
|
////a call is hung up:
|
|||
|
///if one device setup a sco connect so get the other device's sco state, if both connect mute the earlier one
|
|||
|
if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){
|
|||
|
app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_ENABLE;
|
|||
|
app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_DISABLE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_UPDATE_MEDIA,BT_STREAM_VOICE,chan_id_flag.id,MAX_RECORD_NUM);
|
|||
|
}
|
|||
|
|
|||
|
extern uint8_t once_event_case;
|
|||
|
extern void startonce_delay_event_Timer_(int ms);
|
|||
|
extern void bt_drv_clear_skip_flag();
|
|||
|
static void hfp_callsetup_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
//clear flag_skip_resv and flag_skip_retx
|
|||
|
bt_drv_clear_skip_flag();
|
|||
|
enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
|
|||
|
TRACE(2,"::HF_EVENT_CALLSETUP_IND chan_id:%d, callSetup =%d\n", chan_id_flag.id, ctx->call_setup);
|
|||
|
if(ctx->call_setup == 0x03)
|
|||
|
{
|
|||
|
once_event_case = 8;
|
|||
|
startonce_delay_event_Timer_(1000);
|
|||
|
}
|
|||
|
if((ctx->call_setup & 0x03) != 0){
|
|||
|
hfp_call_setup_running_on_set(1);
|
|||
|
}
|
|||
|
#if !defined(FPGA) && defined(__BTIF_EARPHONE__)
|
|||
|
hfp_app_status_indication(chan_id_flag.id, ctx);
|
|||
|
#endif
|
|||
|
|
|||
|
if (BTIF_HF_CALL_SETUP_NONE != ctx->call_setup)
|
|||
|
{
|
|||
|
// exit sniff mode and stay active
|
|||
|
app_bt_active_mode_set(ACTIVE_MODE_KEEPEER_SCO_STREAMING,
|
|||
|
UPDATE_ACTIVE_MODE_FOR_ALL_LINKS);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// resume sniff mode
|
|||
|
app_bt_active_mode_clear(ACTIVE_MODE_KEEPEER_SCO_STREAMING,
|
|||
|
UPDATE_ACTIVE_MODE_FOR_ALL_LINKS);
|
|||
|
}
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
TRACE(2,"call [0]/[1] =%d / %d",app_bt_device.hfchan_call[BT_DEVICE_ID_1],app_bt_device.hfchan_call[BT_DEVICE_ID_2]);
|
|||
|
TRACE(2,"audio [0]/[1] =%d / %d",app_bt_device.hf_audio_state[BT_DEVICE_ID_1],app_bt_device.hf_audio_state[BT_DEVICE_ID_2]);
|
|||
|
|
|||
|
app_bt_device.callSetupBitRec |= (1 << ctx->call_setup);
|
|||
|
if(ctx->call_setup == 0){
|
|||
|
//do nothing
|
|||
|
}else{
|
|||
|
|
|||
|
#ifdef BT_USB_AUDIO_DUAL_MODE
|
|||
|
if(!btusb_is_bt_mode())
|
|||
|
{
|
|||
|
TRACE(0,"btusb_usbaudio_close doing.");
|
|||
|
btusb_usbaudio_close();
|
|||
|
}
|
|||
|
#endif
|
|||
|
#if defined (HFP_NO_PRERMPT)
|
|||
|
if(((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)&&
|
|||
|
(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_NONE))||
|
|||
|
((app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)&&
|
|||
|
(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_NONE))){
|
|||
|
app_bt_device.curr_hf_channel_id = anotherDevice;
|
|||
|
}
|
|||
|
else if((app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE)&&
|
|||
|
(app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)){
|
|||
|
}else{
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
}
|
|||
|
#else
|
|||
|
if((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)||((app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)&&(app_bt_device.hfchan_call[chan_id_flag.id] != BTIF_HF_CALL_ACTIVE))){
|
|||
|
app_bt_device.curr_hf_channel_id = anotherDevice;
|
|||
|
}else{
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
TRACE(1,"!!!HF_EVENT_CALLSETUP_IND curr_hf_channel_id:%d\n",app_bt_device.curr_hf_channel_id);
|
|||
|
#endif
|
|||
|
app_bt_device.hfchan_callSetup[chan_id_flag.id] = ctx->call_setup;
|
|||
|
/////call is alert so remember this time
|
|||
|
if(app_bt_device.hfchan_callSetup[chan_id_flag.id] == BTIF_HF_CALL_SETUP_ALERT )
|
|||
|
{
|
|||
|
TRACE(1,"HF CALLSETUP TIME=%d",hal_sys_timer_get());
|
|||
|
app_bt_device.hf_callsetup_time[chan_id_flag.id] = hal_sys_timer_get();
|
|||
|
}
|
|||
|
if(app_bt_device.hfchan_callSetup[chan_id_flag.id]== BTIF_HF_CALL_SETUP_IN){
|
|||
|
btif_hf_list_current_calls(chan);
|
|||
|
}
|
|||
|
|
|||
|
if((app_bt_device.hfchan_callSetup[chan_id_flag.id] == 0) &&
|
|||
|
(app_bt_device.hfchan_call[chan_id_flag.id]==0)){
|
|||
|
hfp_call_setup_running_on_clr();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_current_call_state_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
TRACE(1,"::HF_EVENT_CURRENT_CALL_STATE chan_id:%d\n", chan_id_flag.id);
|
|||
|
#if !defined(FPGA) && defined(__BTIF_EARPHONE__)
|
|||
|
hfp_app_status_indication(chan_id_flag.id,ctx);
|
|||
|
#endif
|
|||
|
}
|
|||
|
void app_hfp_mute_upstream(uint8_t devId, bool isMute);
|
|||
|
|
|||
|
static void hfp_audio_connected_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
#if defined(HFP_1_6_ENABLE)
|
|||
|
hf_chan_handle_t chan_tmp;
|
|||
|
#endif
|
|||
|
#ifdef __AI_VOICE__
|
|||
|
ai_function_handle(CALLBACK_STOP_SPEECH, NULL, 0);
|
|||
|
ai_function_handle(CALLBACK_AI_APP_KEEPALIVE_POST_HANDLER, NULL, 0); // check
|
|||
|
#endif
|
|||
|
if(ctx->status != BT_STS_SUCCESS)
|
|||
|
return;
|
|||
|
#if defined(IBRT)
|
|||
|
app_ibrt_if_sniff_checker_start(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP);
|
|||
|
#endif
|
|||
|
|
|||
|
btdrv_set_powerctrl_rssi_low(0xffff);
|
|||
|
btapp_hfp_mic_need_skip_frame_set(2);
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
#ifdef SUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING
|
|||
|
if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){
|
|||
|
TRACE(0,"::HF_EVENT_AUDIO_CONNECTED no need to update state");
|
|||
|
return;
|
|||
|
}
|
|||
|
hfp_suspend_another_device_a2dp();
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
a2dp_dual_slave_setup_during_sco(chan_id_flag.id);
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(HFP_1_6_ENABLE)
|
|||
|
chan_tmp = app_bt_device.hf_channel[chan_id_flag.id];
|
|||
|
uint16_t codec_id;
|
|||
|
#if defined(IBRT)
|
|||
|
ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx();
|
|||
|
if(p_ibrt_ctrl->current_role==IBRT_SLAVE)
|
|||
|
{
|
|||
|
codec_id= p_ibrt_ctrl->ibrt_sco_codec;
|
|||
|
}
|
|||
|
else
|
|||
|
#endif
|
|||
|
{
|
|||
|
codec_id = btif_hf_get_negotiated_codec(chan_tmp);
|
|||
|
}
|
|||
|
TRACE(2,"::HF_EVENT_AUDIO_CONNECTED chan_id:%d, codec_id:%d\n", chan_id_flag.id, codec_id);
|
|||
|
app_audio_manager_set_scocodecid(chan_id_flag.id, codec_id);
|
|||
|
|
|||
|
|
|||
|
// bt_drv_reg_op_sco_txfifo_reset(codec_id);
|
|||
|
#else
|
|||
|
TRACE(1,"::HF_EVENT_AUDIO_CONNECTED chan_id:%d\n", chan_id_flag.id);
|
|||
|
// bt_drv_reg_op_sco_txfifo_reset(1);
|
|||
|
#endif
|
|||
|
#if defined (HFP_NO_PRERMPT)
|
|||
|
if(((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)&&
|
|||
|
(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_DISCON))&&
|
|||
|
((app_bt_device.hf_audio_state[chan_id_flag.id] == BTIF_HF_AUDIO_DISCON)&&
|
|||
|
(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE))){
|
|||
|
app_bt_device.phone_earphone_mark = 0;
|
|||
|
app_bt_device.hf_mute_flag = 0;
|
|||
|
}else if((app_bt_device.hf_audio_state[chan_id_flag.id] == BTIF_HF_AUDIO_CON)||
|
|||
|
(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON)){
|
|||
|
}else
|
|||
|
#endif
|
|||
|
{
|
|||
|
app_bt_device.phone_earphone_mark = 0;
|
|||
|
app_bt_device.hf_mute_flag = 0;
|
|||
|
}
|
|||
|
app_bt_device.hf_audio_state[chan_id_flag.id] = BTIF_HF_AUDIO_CON;
|
|||
|
|
|||
|
#if defined(__FORCE_REPORTVOLUME_SOCON__)
|
|||
|
btif_hf_report_speaker_volume(chan, hfp_volume_get(chan_id_flag.id));
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
if( bt_get_sco_number()>1
|
|||
|
#ifdef CHIP_BEST1000
|
|||
|
&& hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2
|
|||
|
#endif
|
|||
|
){
|
|||
|
if(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE){
|
|||
|
#if !defined (HFP_NO_PRERMPT)
|
|||
|
#ifndef __HF_KEEP_ONE_ALIVE__
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWAP_SCO,BT_STREAM_SBC, chan_id_flag.id, 0);
|
|||
|
#endif
|
|||
|
app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_ENABLE;
|
|||
|
app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_DISABLE;
|
|||
|
#else
|
|||
|
if((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_NONE)&&
|
|||
|
(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_DISCON))
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
#ifdef _THREE_WAY_ONE_CALL_COUNT__
|
|||
|
app_hfp_set_cur_chnl_id(chan_id_flag.id);
|
|||
|
TRACE(4,"%s :%d : app_bt_device.hf_callheld[%d]: %d\n", __func__, __LINE__, chan_id_flag.id, app_bt_device.hf_callheld[chan_id_flag.id]);
|
|||
|
if(app_bt_device.hf_callheld[chan_id_flag.id] == BTIF_HF_CALL_HELD_ACTIVE){
|
|||
|
if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id)
|
|||
|
app_hfp_3_way_call_counter_set(chan_id_flag.id,1);
|
|||
|
}else if((app_bt_device.hf_callheld[chan_id_flag.id] == BTIF_HF_CALL_HELD_NONE) ||
|
|||
|
(app_bt_device.hf_callheld[chan_id_flag.id] == BTIF_HF_CALL_HELD_NO_ACTIVE)){
|
|||
|
if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id)
|
|||
|
app_hfp_3_way_call_counter_set(chan_id_flag.id,0);
|
|||
|
}
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
}else if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){
|
|||
|
app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_DISABLE;
|
|||
|
app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_ENABLE;
|
|||
|
}
|
|||
|
}else{
|
|||
|
///if one device setup a sco connect so get the other device's sco state, if both connect mute the earlier one
|
|||
|
if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){
|
|||
|
app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_DISABLE;
|
|||
|
}
|
|||
|
app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_ENABLE;
|
|||
|
}
|
|||
|
#ifndef __HF_KEEP_ONE_ALIVE__
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_VOICE,chan_id_flag.id,MAX_RECORD_NUM);
|
|||
|
#endif
|
|||
|
#if defined (HFP_NO_PRERMPT)
|
|||
|
TRACE(2,"call[id_other] =%d audio[id_other] = %d",app_bt_device.hfchan_call[anotherDevice],
|
|||
|
app_bt_device.hf_audio_state[anotherDevice]);
|
|||
|
if(/*(app_bt_device.hfchan_call[anotherDevice] == HF_CALL_ACTIVE)&&*/
|
|||
|
(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON)){
|
|||
|
}else
|
|||
|
#endif
|
|||
|
{
|
|||
|
if (bt_media_cur_is_bt_stream_media())
|
|||
|
{
|
|||
|
app_hfp_start_voice_media(chan_id_flag.id);
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
TRACE(1,"%s another[%d] hf_audio_state %d,",__func__,anotherDevice,app_bt_device.hf_audio_state[anotherDevice]);
|
|||
|
|
|||
|
if(BTIF_HF_AUDIO_CON == app_bt_device.hf_audio_state[anotherDevice])
|
|||
|
{
|
|||
|
TRACE(1,"disconnect current audio link and don't swith to current sco");
|
|||
|
btif_hf_disc_audio_link(app_bt_device.hf_channel[chan_id_flag.id]);
|
|||
|
app_bt_device.curr_hf_channel_id = anotherDevice;
|
|||
|
}
|
|||
|
#else
|
|||
|
if(bt_is_sco_media_open())
|
|||
|
{
|
|||
|
TRACE(0,"disconnect current audio link and don't swith to current sco");
|
|||
|
app_bt_HF_DisconnectAudioLink(app_bt_device.hf_channel[chan_id_flag.id]);
|
|||
|
}
|
|||
|
#endif
|
|||
|
else
|
|||
|
{
|
|||
|
app_hfp_start_voice_media(chan_id_flag.id);
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#else
|
|||
|
#ifdef _THREE_WAY_ONE_CALL_COUNT__
|
|||
|
app_hfp_set_cur_chnl_id(chan_id_flag.id);
|
|||
|
#endif
|
|||
|
#ifdef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA
|
|||
|
if (bt_media_cur_is_bt_stream_media())
|
|||
|
{
|
|||
|
app_hfp_set_starting_media_pending_flag(true, BT_DEVICE_ID_1);
|
|||
|
}
|
|||
|
else
|
|||
|
#endif
|
|||
|
{
|
|||
|
app_hfp_start_voice_media(BT_DEVICE_ID_1);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __IAG_BLE_INCLUDE__
|
|||
|
app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_HFP_ON, true);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_audio_disconnected_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
//clear flag_skip_resv and flag_skip_retx
|
|||
|
bt_drv_clear_skip_flag();
|
|||
|
enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef BT_USB_AUDIO_DUAL_MODE
|
|||
|
if(!btusb_is_bt_mode())
|
|||
|
{
|
|||
|
TRACE(0,"btusb_usbaudio_open doing.");
|
|||
|
btusb_usbaudio_open();
|
|||
|
}
|
|||
|
#endif
|
|||
|
app_hfp_set_starting_media_pending_flag(false, 0);
|
|||
|
#if defined(IBRT)
|
|||
|
app_ibrt_if_sniff_checker_stop(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP);
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
#ifdef SUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING
|
|||
|
if (app_bt_is_to_resume_music_player(anotherDevice))
|
|||
|
{
|
|||
|
app_bt_resume_music_player(anotherDevice);
|
|||
|
}
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
a2dp_dual_slave_handling_refresh();
|
|||
|
#endif
|
|||
|
TRACE(1,"::HF_EVENT_AUDIO_DISCONNECTED chan_id:%d\n", chan_id_flag.id);
|
|||
|
if(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE){
|
|||
|
app_bt_device.phone_earphone_mark = 1;
|
|||
|
}
|
|||
|
|
|||
|
app_bt_device.hf_audio_state[chan_id_flag.id] = BTIF_HF_AUDIO_DISCON;
|
|||
|
|
|||
|
/* Dont clear callsetup status when audio disc: press iphone volume button
|
|||
|
will disc audio link, but the iphone incoming call is still exist. The
|
|||
|
callsetup status will be reported after call rejected or answered. */
|
|||
|
//app_bt_device.hfchan_callSetup[chan_id_flag.id] = BTIF_HF_CALL_SETUP_NONE;
|
|||
|
|
|||
|
#ifdef __IAG_BLE_INCLUDE__
|
|||
|
if (!app_bt_is_in_reconnecting())
|
|||
|
{
|
|||
|
app_hfp_resume_ble_adv();
|
|||
|
}
|
|||
|
|
|||
|
app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_HFP_ON, false);
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402)
|
|||
|
bt_drv_reg_op_clean_flags_of_ble_and_sco();
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
if (btif_get_hf_chan_state(app_bt_device.hf_channel[anotherDevice]) != BTIF_HF_STATE_OPEN){
|
|||
|
TRACE(2,"!!!HF_EVENT_AUDIO_DISCONNECTED hfchan_call[%d]:%d\n",anotherDevice,
|
|||
|
app_bt_device.hfchan_call[anotherDevice]);
|
|||
|
}
|
|||
|
if ((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE) ||
|
|||
|
(app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)){
|
|||
|
// app_bt_device.curr_hf_channel_id = chan_id_flag.id_other;
|
|||
|
TRACE(1,"!!!HF_EVENT_AUDIO_DISCONNECTED app_bt_device.curr_hf_channel_id:%d\n",
|
|||
|
app_bt_device.curr_hf_channel_id);
|
|||
|
} else {
|
|||
|
app_bt_device.curr_hf_channel_id = chan_id_flag.id;
|
|||
|
}
|
|||
|
#if defined(_THREE_WAY_ONE_CALL_COUNT__)
|
|||
|
if (chan_id_flag.id == app_hfp_get_cur_call_chnl(NULL)) {
|
|||
|
app_hfp_cur_call_chnl_reset(chan_id_flag.id);
|
|||
|
}
|
|||
|
#endif
|
|||
|
app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_DISABLE;
|
|||
|
if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){
|
|||
|
app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_ENABLE;
|
|||
|
TRACE(1,"chan_id:%d AUDIO_DISCONNECTED, then enable id_other voice",chan_id_flag.id);
|
|||
|
}
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, BT_STREAM_VOICE,
|
|||
|
chan_id_flag.id, MAX_RECORD_NUM);
|
|||
|
#else
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, BT_STREAM_VOICE,
|
|||
|
BT_DEVICE_ID_1, MAX_RECORD_NUM);
|
|||
|
|
|||
|
#endif
|
|||
|
app_bt_device.callSetupBitRec = 0;
|
|||
|
//app_hfp_mute_upstream(chan_id_flag.id, true);
|
|||
|
#if defined(HFP_1_6_ENABLE)
|
|||
|
uint16_t codec_id = btif_hf_get_negotiated_codec(app_bt_device.hf_channel[chan_id_flag.id]);
|
|||
|
bt_drv_reg_op_sco_txfifo_reset(codec_id);
|
|||
|
#else
|
|||
|
bt_drv_reg_op_sco_txfifo_reset(1);
|
|||
|
#endif
|
|||
|
|
|||
|
app_bt_active_mode_clear(ACTIVE_MODE_KEEPEER_SCO_STREAMING,
|
|||
|
UPDATE_ACTIVE_MODE_FOR_ALL_LINKS);
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_ring_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#if !defined(FPGA) && defined(__BTIF_EARPHONE__) && defined(MEDIA_PLAYER_SUPPORT)
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
TRACE(1,"::HF_EVENT_RING_IND chan_id:%d\n", chan_id_flag.id);
|
|||
|
TRACE(1,"btif_hf_is_inbandring_enabled:%d",btif_hf_is_inbandring_enabled(chan));
|
|||
|
#if defined(__BT_ONE_BRING_TWO__)
|
|||
|
if((app_bt_device.hf_audio_state[chan_id_flag.id] != BTIF_HF_AUDIO_CON) &&
|
|||
|
(app_bt_device.hf_audio_state[anotherDevice] != BTIF_HF_AUDIO_CON))
|
|||
|
app_voice_report(APP_STATUS_INDICATION_INCOMINGCALL,chan_id_flag.id);
|
|||
|
#else
|
|||
|
|
|||
|
#if defined(IBRT)
|
|||
|
ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx();
|
|||
|
if(p_ibrt_ctrl->current_role == IBRT_SLAVE)
|
|||
|
return;
|
|||
|
#endif
|
|||
|
if(app_bt_device.hf_audio_state[chan_id_flag.id] != BTIF_HF_AUDIO_CON)
|
|||
|
app_voice_report(APP_STATUS_INDICATION_INCOMINGCALL,chan_id_flag.id);
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_speak_volume_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
TRACE(2,"::HF_EVENT_SPEAKER_VOLUME chan_id:%d,speaker gain = %d\n",
|
|||
|
chan_id_flag.id, ctx->speaker_volume);
|
|||
|
hfp_volume_set(chan_id_flag.id, (int)ctx->speaker_volume);
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_voice_rec_state_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
TRACE(2,"::HF_EVENT_VOICE_REC_STATE chan_id:%d,voice_rec_state = %d\n",
|
|||
|
chan_id_flag.id, ctx->voice_rec_state);
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_bes_test_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
//TRACE(0,"HF_EVENT_BES_TEST content =d", Info->p.ptr);
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_read_ag_ind_status_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
TRACE(1,"HF_EVENT_READ_AG_INDICATORS_STATUS %s\n", __func__);
|
|||
|
}
|
|||
|
|
|||
|
static void hfp_call_held_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
#if defined( __BT_ONE_BRING_TWO__)
|
|||
|
TRACE(8,"::HF_EVENT_CALLHELD_IND %d chan_id %d call %d %d held %d %d audio_state %d %d\n",
|
|||
|
ctx->call_held, chan_id_flag.id,
|
|||
|
app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2],
|
|||
|
app_bt_device.hf_callheld[BT_DEVICE_ID_1], app_bt_device.hf_callheld[BT_DEVICE_ID_2],
|
|||
|
app_bt_device.hf_audio_state[BT_DEVICE_ID_1], app_bt_device.hf_audio_state[BT_DEVICE_ID_2]);
|
|||
|
#else
|
|||
|
TRACE(2,"::HF_EVENT_CALLHELD_IND chan_id:%d HELD_STATUS = %d \n",chan_id_flag.id, ctx->call_held);
|
|||
|
#endif
|
|||
|
#if defined(_THREE_WAY_ONE_CALL_COUNT__)
|
|||
|
#if defined( __BT_ONE_BRING_TWO__)
|
|||
|
if (app_bt_device.hf_audio_state[chan_id_flag.id] == BTIF_HF_AUDIO_CON && (ctx->call_held == BTIF_HF_CALL_HELD_NONE || ctx->call_held == BTIF_HF_CALL_HELD_ACTIVE)) {
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWITCHTO_SCO, BT_STREAM_VOICE, chan_id_flag.id, 0);
|
|||
|
}
|
|||
|
#endif
|
|||
|
app_bt_device.hf_callheld[chan_id_flag.id] = ctx->call_held;
|
|||
|
if(ctx->call_held == BTIF_HF_CALL_HELD_ACTIVE){
|
|||
|
if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id)
|
|||
|
app_hfp_3_way_call_counter_set(chan_id_flag.id,1);
|
|||
|
}else if((ctx->call_held == BTIF_HF_CALL_HELD_NONE) ||
|
|||
|
(ctx->call_held == BTIF_HF_CALL_HELD_NO_ACTIVE)){
|
|||
|
if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id)
|
|||
|
app_hfp_3_way_call_counter_set(chan_id_flag.id,0);
|
|||
|
}else{
|
|||
|
TRACE(0,"UNKNOWN CMD.IGNORE");
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static uint8_t skip_frame_cnt = 0;
|
|||
|
void app_hfp_set_skip_frame(uint8_t frames)
|
|||
|
{
|
|||
|
skip_frame_cnt = frames;
|
|||
|
}
|
|||
|
uint8_t app_hfp_run_skip_frame(void)
|
|||
|
{
|
|||
|
if(skip_frame_cnt >0){
|
|||
|
skip_frame_cnt--;
|
|||
|
return 1;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
uint8_t hfp_is_service_connected(uint8_t device_id)
|
|||
|
{
|
|||
|
if(device_id >= BT_DEVICE_NUM)
|
|||
|
return 0;
|
|||
|
return app_bt_device.hf_conn_flag[device_id];
|
|||
|
}
|
|||
|
#if HF_VERSION_1_6 == XA_ENABLED
|
|||
|
//HfCommand hf_codec_sel_command;
|
|||
|
#endif
|
|||
|
|
|||
|
static uint8_t app_hfp_is_starting_media_pending_flag = false;
|
|||
|
static uint8_t app_hfp_pending_dev_id;
|
|||
|
bool app_hfp_is_starting_media_pending(void)
|
|||
|
{
|
|||
|
return app_hfp_is_starting_media_pending_flag;
|
|||
|
}
|
|||
|
static uint8_t upstreamMute = 0xff;
|
|||
|
void app_hfp_mute_upstream(uint8_t devId, bool isMute)
|
|||
|
{
|
|||
|
if (upstreamMute != isMute){
|
|||
|
TRACE(3,"%s devId %d isMute %d",__func__,devId,isMute);
|
|||
|
upstreamMute = isMute;
|
|||
|
if (isMute){
|
|||
|
btdrv_set_bt_pcm_en(0);
|
|||
|
}else{
|
|||
|
btdrv_set_bt_pcm_en(1);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void app_hfp_set_starting_media_pending_flag(bool isEnabled, uint8_t devId)
|
|||
|
{
|
|||
|
TRACE(1,"%s %d.Current state %d toEnable %d",__func__,__LINE__,
|
|||
|
app_hfp_is_starting_media_pending_flag, isEnabled);
|
|||
|
if ((app_hfp_is_starting_media_pending_flag && isEnabled) ||
|
|||
|
(!app_hfp_is_starting_media_pending_flag && !isEnabled))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
app_hfp_is_starting_media_pending_flag = isEnabled;
|
|||
|
|
|||
|
app_hfp_pending_dev_id = devId;
|
|||
|
#if 0
|
|||
|
if (isEnabled)
|
|||
|
{
|
|||
|
if (!app_hfp_mediaplay_delay_resume_timer_id ) {
|
|||
|
app_hfp_mediaplay_delay_resume_timer_id =
|
|||
|
osTimerCreate(osTimer(APP_HFP_MEDIAPLAY_DELAY_RESUME_TIMER),
|
|||
|
osTimerOnce, NULL);
|
|||
|
}
|
|||
|
osTimerStart(app_hfp_mediaplay_delay_resume_timer_id ,
|
|||
|
HFP_MEDIAPLAY_DELAY_RESUME_IN_MS);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
void app_hfp_start_voice_media(uint8_t devId)
|
|||
|
{
|
|||
|
app_hfp_set_starting_media_pending_flag(false, 0);
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,
|
|||
|
BT_STREAM_VOICE, devId, MAX_RECORD_NUM);
|
|||
|
}
|
|||
|
|
|||
|
void app_hfp_resume_pending_voice_media(void)
|
|||
|
{
|
|||
|
if (btapp_hfp_is_dev_sco_connected(app_hfp_pending_dev_id))
|
|||
|
{
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,
|
|||
|
BT_STREAM_VOICE, app_hfp_pending_dev_id, MAX_RECORD_NUM);
|
|||
|
app_hfp_set_starting_media_pending_flag(false, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#include "app_bt_func.h"
|
|||
|
void hfp_multipoint_audio_manage_a2dp_callback()
|
|||
|
{
|
|||
|
#ifdef SUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING
|
|||
|
int i = 0;
|
|||
|
int j = 0;
|
|||
|
TRACE(1,"%s",__func__);
|
|||
|
|
|||
|
for(i =0;i<BT_DEVICE_NUM;i++){
|
|||
|
if(app_bt_device.a2dp_streamming[i] == 1)
|
|||
|
break;
|
|||
|
}
|
|||
|
if(i == BT_DEVICE_NUM)
|
|||
|
return;
|
|||
|
|
|||
|
for(j =0;j<BT_DEVICE_NUM;j++){
|
|||
|
if(app_bt_device.hf_audio_state[j] == BTIF_HF_AUDIO_CON)
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if(j == BT_DEVICE_NUM)
|
|||
|
return;
|
|||
|
|
|||
|
btif_remote_device_t* activeA2dpRem =
|
|||
|
A2DP_GetRemoteDevice(app_bt_device.a2dp_connected_stream[i]);
|
|||
|
|
|||
|
btif_remote_device_t* activeHfpRem =
|
|||
|
(btif_remote_device_t *)btif_hf_cmgr_get_remote_device(app_bt_device.hf_channel[j]);
|
|||
|
|
|||
|
if(activeA2dpRem == activeHfpRem)
|
|||
|
return;
|
|||
|
|
|||
|
TRACE(0,"different profile device");
|
|||
|
if (app_bt_is_music_player_working(i)) {
|
|||
|
bool isPaused = app_bt_pause_music_player(i);
|
|||
|
if (isPaused) {
|
|||
|
app_bt_set_music_player_resume_device(i);
|
|||
|
}
|
|||
|
} else if (app_bt_is_a2dp_streaming(i)) {
|
|||
|
app_bt_suspend_a2dp_streaming(i);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void hfp_suspend_another_device_a2dp(void)
|
|||
|
{
|
|||
|
app_bt_start_custom_function_in_bt_thread(0,
|
|||
|
0, (uint32_t)hfp_multipoint_audio_manage_a2dp_callback);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
static void app_hfp_audio_closed_delay_resume_ble_adv_timer_cb(void const *n)
|
|||
|
{
|
|||
|
#ifdef __IAG_BLE_INCLUDE__
|
|||
|
app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL);
|
|||
|
#endif
|
|||
|
}
|
|||
|
#ifdef __IAG_BLE_INCLUDE__
|
|||
|
static void app_hfp_resume_ble_adv(void)
|
|||
|
{
|
|||
|
if (!app_hfp_audio_closed_delay_resume_ble_adv_timer_id) {
|
|||
|
app_hfp_audio_closed_delay_resume_ble_adv_timer_id =
|
|||
|
osTimerCreate(osTimer(APP_HFP_AUDIO_CLOSED_DELAY_RESUME_BLE_ADV_TIMER),
|
|||
|
osTimerOnce, NULL);
|
|||
|
}
|
|||
|
|
|||
|
osTimerStart(app_hfp_audio_closed_delay_resume_ble_adv_timer_id,
|
|||
|
HFP_AUDIO_CLOSED_DELAY_RESUME_ADV_IN_MS);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
#if defined(__BT_SELECT_PROF_DEVICE_ID__)
|
|||
|
static void _app_hfp_select_channel(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
uint32_t i = 0;
|
|||
|
btif_remote_device_t *matching_remdev = NULL, *wanted_remdev = NULL;
|
|||
|
hf_chan_handle_t curr_channel;
|
|||
|
|
|||
|
wanted_remdev = ctx->chan_sel_remDev;
|
|||
|
// default channel is NULL
|
|||
|
*(ctx->chan_sel_channel) = NULL;
|
|||
|
for(i = 0 ; i < BT_DEVICE_NUM ; i++) {
|
|||
|
// Other profile connected
|
|||
|
curr_channel = app_bt_device.hf_channel[i];
|
|||
|
if (app_bt_is_any_profile_connected(i)) {
|
|||
|
matching_remdev = app_bt_get_connected_profile_remdev(i);
|
|||
|
TRACE(3,"device_id=%d, hfp_select_channel : remdev=0x%x:0x%x.", i, wanted_remdev, matching_remdev);
|
|||
|
TRACE(1,"device_id=%d, hfp_select_channel : other_profile_connected.", i);
|
|||
|
if (wanted_remdev == matching_remdev) {
|
|||
|
TRACE(2,"device_id=%d, hfp_select_channel : found_same_remdev : 0x%x", i, &(app_bt_device.hf_channel[i]));
|
|||
|
if (btif_get_hf_chan_state(curr_channel) == BTIF_HF_STATE_CLOSED) {
|
|||
|
TRACE(1,"device_id=%d, hfp_select_channel : current_channel_is_closed, good.", i);
|
|||
|
*(ctx->chan_sel_channel) = (uint32_t *)curr_channel;
|
|||
|
}
|
|||
|
else {
|
|||
|
TRACE(2,"device_id=%d, hfp_select_channel : other_profile_connected: current_channel_is_not_closed %d, ohno.", i, btif_get_hf_chan_state(curr_channel));
|
|||
|
TRACE(1,"device_id=%d, hfp_select_channel : other_profile_connected: missed right channel, found nothing, return", i);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
else {
|
|||
|
TRACE(1,"device_id=%d, hfp_select_channel : different_remdev, see next device id", i);
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
TRACE(1,"device_id=%d, hfp_select_channel : other_profile_not_connected.", i);
|
|||
|
// first found idle device id is min device id we want
|
|||
|
// Assume : other profile will use device id ascending
|
|||
|
// TODO to keep other profile use device id ascending
|
|||
|
if (btif_get_hf_chan_state(curr_channel) == BTIF_HF_STATE_CLOSED) {
|
|||
|
TRACE(1,"device_id=%d, hfp_select_channel : current_channel_is_closed, choose this idle channel.", i);
|
|||
|
*(ctx->chan_sel_channel) = (uint32_t *)curr_channel;
|
|||
|
}
|
|||
|
else {
|
|||
|
TRACE(2,"device_id=%d, hfp_select_channel : no_other_profile_connected : current_channel_is_not_closed %d, ohno.", i, btif_get_hf_chan_state(curr_channel));
|
|||
|
TRACE(1,"device_id=%d, hfp_select_channel : no_other_profile_connected : missed right channel, found nothing, return", i);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
|
|||
|
void app_hfp_event_callback(hf_chan_handle_t chan, struct hfp_context *ctx)
|
|||
|
{
|
|||
|
struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr();
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
if (ctx->event == BTIF_HF_EVENT_SELECT_CHANNEL) {
|
|||
|
#if defined(__BT_SELECT_PROF_DEVICE_ID__)
|
|||
|
_app_hfp_select_channel(chan, ctx);
|
|||
|
#endif
|
|||
|
return;
|
|||
|
}
|
|||
|
hfp_chan_id_distinguish(chan);
|
|||
|
#else
|
|||
|
if (ctx->event == BTIF_HF_EVENT_SELECT_CHANNEL) {
|
|||
|
return;
|
|||
|
}
|
|||
|
chan_id_flag.id = BT_DEVICE_ID_1;
|
|||
|
#endif
|
|||
|
switch(ctx->event) {
|
|||
|
case BTIF_HF_EVENT_SERVICE_CONNECTED:
|
|||
|
hfp_connected_ind_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_AUDIO_DATA_SENT:
|
|||
|
hfp_audio_data_sent_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_AUDIO_DATA:
|
|||
|
hfp_audio_data_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_SERVICE_DISCONNECTED:
|
|||
|
hfp_disconnected_ind_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_CALL_IND:
|
|||
|
hfp_call_ind_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_CALLSETUP_IND:
|
|||
|
hfp_callsetup_ind_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_CURRENT_CALL_STATE:
|
|||
|
hfp_current_call_state_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_AUDIO_CONNECTED:
|
|||
|
#ifdef IBRT
|
|||
|
{
|
|||
|
ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx();
|
|||
|
bt_drv_reg_op_set_agc_thd(p_ibrt_ctrl->current_role == IBRT_MASTER,true);
|
|||
|
|
|||
|
if(!btif_besaud_is_connected())
|
|||
|
{
|
|||
|
bt_drv_reg_op_hack_max_slot(p_ibrt_ctrl->mobile_conhandle-0x80,1);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if(bt_drv_func_cb->bt_switch_agc != NULL)
|
|||
|
{
|
|||
|
bt_drv_func_cb->bt_switch_agc(BT_HFP_WORK_MODE);
|
|||
|
}
|
|||
|
|
|||
|
hfp_audio_connected_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_AUDIO_DISCONNECTED:
|
|||
|
|
|||
|
if(bt_drv_func_cb->bt_switch_agc != NULL)
|
|||
|
{
|
|||
|
bt_drv_func_cb->bt_switch_agc(BT_IDLE_MODE);
|
|||
|
}
|
|||
|
|
|||
|
hfp_audio_disconnected_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_RING_IND:
|
|||
|
hfp_ring_ind_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_SPEAKER_VOLUME:
|
|||
|
hfp_speak_volume_handler(chan, ctx);
|
|||
|
break;
|
|||
|
#ifdef SUPPORT_SIRI
|
|||
|
case BTIF_HF_EVENT_SIRI_STATUS:
|
|||
|
break;
|
|||
|
#endif
|
|||
|
case BTIF_HF_EVENT_BES_TEST:
|
|||
|
hfp_bes_test_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_READ_AG_INDICATORS_STATUS:
|
|||
|
hfp_read_ag_ind_status_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_CALLHELD_IND:
|
|||
|
hfp_call_held_ind_handler(chan, ctx);
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_COMMAND_COMPLETE:
|
|||
|
break;
|
|||
|
case BTIF_HF_EVENT_AT_RESULT_DATA:
|
|||
|
TRACE(1,"received AT command: %s", ctx->ptr);
|
|||
|
#ifdef __INTERACTION__
|
|||
|
if(!memcmp(oppo_self_defined_command_response, ctx->ptr, strlen(oppo_self_defined_command_response)))
|
|||
|
{
|
|||
|
for(int i=0; i<BT_DEVICE_NUM; i++)
|
|||
|
{
|
|||
|
chan = app_bt_device.hf_channel[i];
|
|||
|
{
|
|||
|
TRACE(2,"hf state=%x %d",chan, btif_get_hf_chan_state(chan));
|
|||
|
if (btif_get_hf_chan_state(chan) == BTIF_HF_STATE_OPEN)
|
|||
|
{
|
|||
|
//char firmwareversion[] = "AT+VDRV=3,1,9,2,9,3,9";
|
|||
|
//sprintf(&firmwareversion[27], "%d", (int)NeonFwVersion[0]);
|
|||
|
//sprintf(&firmwareversion[28], "%d", (int)NeonFwVersion[1]);
|
|||
|
//sprintf(&firmwareversion[29], "%d", (int)NeonFwVersion[2]);
|
|||
|
//btif_hf_send_at_cmd(chan,firmwareversion);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
TRACE(0,"oppo_self_defined_command_response");
|
|||
|
}
|
|||
|
#endif
|
|||
|
#ifdef __INTERCONNECTION__
|
|||
|
if (!memcmp(huawei_self_defined_command_response, ctx->ptr, strlen(huawei_self_defined_command_response)+1))
|
|||
|
{
|
|||
|
uint8_t *pSelfDefinedCommandSupport = app_battery_get_mobile_support_self_defined_command_p();
|
|||
|
*pSelfDefinedCommandSupport = 1;
|
|||
|
|
|||
|
TRACE(0,"send self defined AT command to mobile.");
|
|||
|
send_selfdefined_battery_report_AT_command();
|
|||
|
}
|
|||
|
#endif
|
|||
|
break;
|
|||
|
|
|||
|
case BTIF_HF_EVENT_VOICE_REC_STATE:
|
|||
|
hfp_voice_rec_state_ind_handler(chan, ctx);
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef __BT_ONE_BRING_TWO__
|
|||
|
hfcall_next_sta_handler(ctx->event);
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(IBRT)
|
|||
|
app_tws_ibrt_profile_callback(BTIF_APP_HFP_PROFILE_ID,(void *)chan, (void *)ctx);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
uint8_t btapp_hfp_get_call_state(void)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
for (i = 0; i < BT_DEVICE_NUM; i++) {
|
|||
|
if (app_bt_device.hfchan_call[i] == BTIF_HF_CALL_ACTIVE) {
|
|||
|
return 1;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
uint8_t btapp_hfp_get_call_setup(void)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
for (i = 0; i < BT_DEVICE_NUM; i++){
|
|||
|
if ((app_bt_device.hfchan_callSetup[i] != BTIF_HF_CALL_SETUP_NONE)){
|
|||
|
return (app_bt_device.hfchan_callSetup[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
uint8_t btapp_hfp_incoming_calls(void)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
for (i = 0; i < BT_DEVICE_NUM; i++) {
|
|||
|
if (app_bt_device.hfchan_callSetup[i] == BTIF_HF_CALL_SETUP_IN) {
|
|||
|
return 1;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
bool btapp_hfp_is_call_active(void)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
for (i = 0; i < BT_DEVICE_NUM; i++){
|
|||
|
if ((app_bt_device.hfchan_call[i] == BTIF_HF_CALL_ACTIVE) &&
|
|||
|
(app_bt_device.hf_audio_state[i] == BTIF_HF_AUDIO_CON)) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool btapp_hfp_is_sco_active(void)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
for (i = 0; i < BT_DEVICE_NUM; i++) {
|
|||
|
if (app_bt_device.hf_audio_state[i] == BTIF_HF_AUDIO_CON) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool btapp_hfp_is_dev_call_active(uint8_t devId)
|
|||
|
{
|
|||
|
return ((app_bt_device.hfchan_call[devId] == BTIF_HF_CALL_ACTIVE) &&
|
|||
|
(app_bt_device.hf_audio_state[devId] == BTIF_HF_AUDIO_CON));
|
|||
|
}
|
|||
|
|
|||
|
bool btapp_hfp_is_dev_sco_connected(uint8_t devId)
|
|||
|
{
|
|||
|
return (app_bt_device.hf_audio_state[devId] == BTIF_HF_AUDIO_CON);
|
|||
|
}
|
|||
|
|
|||
|
uint8_t btapp_hfp_get_call_active(void)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
for (i = 0; i < BT_DEVICE_NUM; i++) {
|
|||
|
if ((app_bt_device.hfchan_call[i] == BTIF_HF_CALL_ACTIVE) ||
|
|||
|
(app_bt_device.hfchan_callSetup[i] == BTIF_HF_CALL_SETUP_ALERT)){
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
void btapp_hfp_report_speak_gain(void)
|
|||
|
{
|
|||
|
uint8_t i;
|
|||
|
btif_remote_device_t *remDev = NULL;
|
|||
|
btif_link_mode_t mode = BTIF_BLM_SNIFF_MODE;
|
|||
|
hf_chan_handle_t chan;
|
|||
|
|
|||
|
|
|||
|
for(i = 0; i < BT_DEVICE_NUM; i++) {
|
|||
|
osapi_lock_stack();
|
|||
|
remDev = (btif_remote_device_t *)btif_hf_cmgr_get_remote_device(app_bt_device.hf_channel[i]);
|
|||
|
if (remDev){
|
|||
|
mode = btif_me_get_current_mode(remDev);
|
|||
|
} else {
|
|||
|
mode = BTIF_BLM_SNIFF_MODE;
|
|||
|
}
|
|||
|
chan = app_bt_device.hf_channel[i];
|
|||
|
if ((btif_get_hf_chan_state(chan) == BTIF_HF_STATE_OPEN) &&
|
|||
|
(mode == BTIF_BLM_ACTIVE_MODE)) {
|
|||
|
btif_hf_report_speaker_volume(chan, hfp_volume_get((enum BT_DEVICE_ID_T)i));
|
|||
|
}
|
|||
|
osapi_unlock_stack();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
uint8_t btapp_hfp_need_mute(void)
|
|||
|
{
|
|||
|
return app_bt_device.hf_mute_flag;
|
|||
|
}
|
|||
|
|
|||
|
int32_t hfp_mic_need_skip_frame_cnt = 0;
|
|||
|
|
|||
|
bool btapp_hfp_mic_need_skip_frame(void)
|
|||
|
{
|
|||
|
bool nRet;
|
|||
|
|
|||
|
if (hfp_mic_need_skip_frame_cnt > 0) {
|
|||
|
hfp_mic_need_skip_frame_cnt--;
|
|||
|
nRet = true;
|
|||
|
} else {
|
|||
|
app_hfp_mute_upstream(0, false);
|
|||
|
nRet = false;
|
|||
|
}
|
|||
|
return nRet;
|
|||
|
}
|
|||
|
|
|||
|
void btapp_hfp_mic_need_skip_frame_set(int32_t skip_frame)
|
|||
|
{
|
|||
|
hfp_mic_need_skip_frame_cnt = skip_frame;
|
|||
|
}
|
|||
|
|
|||
|
#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)
|
|||
|
typedef void (*btapp_set_sco_switch_cmd_callback)(void);
|
|||
|
|
|||
|
btapp_set_sco_switch_cmd_callback set_sco_switch_cmd_callback;
|
|||
|
|
|||
|
void btapp_sco_switch_set_pcm(void)
|
|||
|
{
|
|||
|
TRACE(0,"btapp_sco_switch_set_pcm\n");
|
|||
|
TRACE(1,"0xd02201b0 = 0x%x before\n",*(volatile uint32_t *)(0xd02201b0));
|
|||
|
osDelay(20);
|
|||
|
btdrv_pcm_enable();
|
|||
|
TRACE(1,"0xd02201b0 = 0x%x after\n",*(volatile uint32_t *)(0xd02201b0));
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
void app_hfp_init(void)
|
|||
|
{
|
|||
|
hfp_hfcommand_mempool_init();
|
|||
|
#if defined(ENHANCED_STACK)
|
|||
|
btif_hfp_initialize();
|
|||
|
#endif /* ENHANCED_STACK */
|
|||
|
app_bt_device.curr_hf_channel_id = BT_DEVICE_ID_1;
|
|||
|
app_bt_device.hf_mute_flag = 0;
|
|||
|
|
|||
|
for (uint8_t i = 0; i < BT_DEVICE_NUM; i++) {
|
|||
|
app_bt_device.hf_channel[i] = btif_hf_create_channel();
|
|||
|
if (!app_bt_device.hf_channel[i]) {
|
|||
|
ASSERT(0, "Serious error: cannot create hf channel\n");
|
|||
|
}
|
|||
|
btif_hf_init_channel(app_bt_device.hf_channel[i]);
|
|||
|
app_bt_device.hfchan_call[i] = 0;
|
|||
|
app_bt_device.hfchan_callSetup[i] = 0;
|
|||
|
app_bt_device.hf_audio_state[i] = BTIF_HF_AUDIO_DISCON,
|
|||
|
app_bt_device.hf_conn_flag[i] = false;
|
|||
|
app_bt_device.hf_voice_en[i] = 0;
|
|||
|
}
|
|||
|
btif_hf_register_callback(app_hfp_event_callback);
|
|||
|
#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS)
|
|||
|
Besbt_hook_handler_set(BESBT_HOOK_USER_3, app_hfp_battery_report_proc);
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)
|
|||
|
set_sco_switch_cmd_callback = btapp_sco_switch_set_pcm;
|
|||
|
#endif
|
|||
|
app_hfp_mute_upstream(chan_id_flag.id, true);
|
|||
|
}
|
|||
|
|
|||
|
void app_hfp_enable_audio_link(bool isEnable)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
#if defined(IBRT)
|
|||
|
int hfp_ibrt_service_connected_mock(void)
|
|||
|
{
|
|||
|
if (btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_1]) == BTIF_HF_STATE_OPEN){
|
|||
|
TRACE(0,"::HF_EVENT_SERVICE_CONNECTED mock");
|
|||
|
app_bt_device.hf_conn_flag[chan_id_flag.id] = 1;
|
|||
|
}else{
|
|||
|
TRACE(1,"::HF_EVENT_SERVICE_CONNECTED mock need check chan_state:%d", btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_1]));
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
int hfp_ibrt_sync_get_status(ibrt_hfp_status_t *hfp_status)
|
|||
|
{
|
|||
|
hfp_status->audio_state = (uint8_t)app_bt_device.hf_audio_state[BT_DEVICE_ID_1];
|
|||
|
hfp_status->volume = hfp_volume_get(BT_DEVICE_ID_1);
|
|||
|
hfp_status->lmp_sco_hdl = 0;
|
|||
|
|
|||
|
if (hfp_status->audio_state == BTIF_HF_AUDIO_CON &&
|
|||
|
app_tws_ibrt_mobile_link_connected())
|
|||
|
{
|
|||
|
ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx();
|
|||
|
uint16_t sco_connhdl = btif_me_get_scohdl_by_connhdl(p_ibrt_ctrl->mobile_conhandle);
|
|||
|
hfp_status->lmp_sco_hdl = bt_drv_reg_op_lmp_sco_hdl_get(sco_connhdl);
|
|||
|
TRACE(2,"ibrt_ui_log:get sco lmp hdl %04x %02x\n", sco_connhdl, hfp_status->lmp_sco_hdl);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
int hfp_ibrt_sync_set_status(ibrt_hfp_status_t *hfp_status)
|
|||
|
{
|
|||
|
ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx();
|
|||
|
btif_remote_device_t *remDev = NULL;
|
|||
|
|
|||
|
TRACE(4,"%s audio_state:%d volume:%d lmp_scohdl:%02x", __func__, hfp_status->audio_state,
|
|||
|
hfp_status->volume, hfp_status->lmp_sco_hdl);
|
|||
|
|
|||
|
app_bt_device.hf_audio_state[BT_DEVICE_ID_1] = (btif_audio_state_t)hfp_status->audio_state;
|
|||
|
|
|||
|
if (app_tws_ibrt_mobile_link_connected()){
|
|||
|
remDev = btif_me_get_remote_device_by_handle(p_ibrt_ctrl->mobile_conhandle);
|
|||
|
}else if (app_tws_ibrt_slave_ibrt_link_connected()){
|
|||
|
remDev = btif_me_get_remote_device_by_handle(p_ibrt_ctrl->ibrt_conhandle);
|
|||
|
}
|
|||
|
|
|||
|
if (remDev){
|
|||
|
app_bt_stream_volume_ptr_update((uint8_t *) btif_me_get_remote_device_bdaddr(remDev));
|
|||
|
}else{
|
|||
|
app_bt_stream_volume_ptr_update(NULL);
|
|||
|
}
|
|||
|
|
|||
|
hfp_volume_set(BT_DEVICE_ID_1, hfp_status->volume);
|
|||
|
|
|||
|
p_ibrt_ctrl->ibrt_sco_lmphdl = 0;
|
|||
|
|
|||
|
if (hfp_status->audio_state == BTIF_HF_AUDIO_CON &&
|
|||
|
hfp_status->lmp_sco_hdl != 0 &&
|
|||
|
app_tws_ibrt_slave_ibrt_link_connected())
|
|||
|
{
|
|||
|
uint16_t sco_connhdl = 0x0100; //SYNC_HFP_STATUS arrive before mock sniffer_sco, so use 0x0100 directly
|
|||
|
if (bt_drv_reg_op_lmp_sco_hdl_set(sco_connhdl, hfp_status->lmp_sco_hdl))
|
|||
|
{
|
|||
|
TRACE(2,"ibrt_ui_log:set sco %04x lmp hdl %02x\n", sco_connhdl, hfp_status->lmp_sco_hdl);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// SYNC_HFP_STATUS may so much faster lead bt_drv_reg_op_lmp_sco_hdl_set fail, backup the value
|
|||
|
p_ibrt_ctrl->ibrt_sco_lmphdl = hfp_status->lmp_sco_hdl;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
int hfp_ibrt_sco_audio_connected(hfp_sco_codec_t codec, uint16_t sco_connhdl)
|
|||
|
{
|
|||
|
int ret = BT_STS_SUCCESS;
|
|||
|
ibrt_ctrl_t *p_ibrt_ctrl = NULL;
|
|||
|
|
|||
|
TRACE(0,"::HF_EVENT_AUDIO_CONNECTED mock");
|
|||
|
|
|||
|
app_bt_device.hf_audio_state[BT_DEVICE_ID_1] = BTIF_HF_AUDIO_CON;
|
|||
|
btif_hf_set_negotiated_codec(app_bt_device.hf_channel[BT_DEVICE_ID_1] ,codec);
|
|||
|
app_audio_manager_set_scocodecid(BT_DEVICE_ID_1,codec);
|
|||
|
#ifdef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA
|
|||
|
if (bt_media_cur_is_bt_stream_media())
|
|||
|
{
|
|||
|
app_hfp_set_starting_media_pending_flag(true, BT_DEVICE_ID_1);
|
|||
|
}
|
|||
|
else
|
|||
|
#endif
|
|||
|
{
|
|||
|
app_hfp_start_voice_media(BT_DEVICE_ID_1);
|
|||
|
}
|
|||
|
app_ibrt_if_sniff_checker_start(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP);
|
|||
|
|
|||
|
struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr();
|
|||
|
if(bt_drv_func_cb->bt_switch_agc != NULL)
|
|||
|
{
|
|||
|
bt_drv_func_cb->bt_switch_agc(BT_HFP_WORK_MODE);
|
|||
|
}
|
|||
|
|
|||
|
p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx();
|
|||
|
if (p_ibrt_ctrl->ibrt_sco_lmphdl != 0)
|
|||
|
{
|
|||
|
// set backuped lmphdl if it is failed in hfp_ibrt_sync_set_status
|
|||
|
TRACE(2,"ibrt_ui_log:set sco %04x lmp hdl %02x\n", sco_connhdl, p_ibrt_ctrl->ibrt_sco_lmphdl);
|
|||
|
bt_drv_reg_op_lmp_sco_hdl_set(sco_connhdl, p_ibrt_ctrl->ibrt_sco_lmphdl);
|
|||
|
p_ibrt_ctrl->ibrt_sco_lmphdl = 0;
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
int hfp_ibrt_sco_audio_disconnected(void)
|
|||
|
{
|
|||
|
int ret = BT_STS_SUCCESS;
|
|||
|
TRACE(0,"::HF_EVENT_AUDIO_DISCONNECTED mock");
|
|||
|
app_bt_device.hf_audio_state[BT_DEVICE_ID_1] = BTIF_HF_AUDIO_DISCON;
|
|||
|
app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_VOICE,BT_DEVICE_ID_1,0);
|
|||
|
app_ibrt_if_sniff_checker_stop(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP);
|
|||
|
|
|||
|
struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr();
|
|||
|
if(bt_drv_func_cb->bt_switch_agc != NULL)
|
|||
|
{
|
|||
|
bt_drv_func_cb->bt_switch_agc(BT_IDLE_MODE);
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|