New Clean Commit for AG.
Only Support single AG control block.
This commit is contained in:
parent
8fbece32a9
commit
26b69f1363
32 changed files with 11714 additions and 29 deletions
|
@ -33,6 +33,7 @@ if(CONFIG_BT_ENABLED)
|
||||||
host/bluedroid/bta/av/include
|
host/bluedroid/bta/av/include
|
||||||
host/bluedroid/bta/dm/include
|
host/bluedroid/bta/dm/include
|
||||||
host/bluedroid/bta/gatt/include
|
host/bluedroid/bta/gatt/include
|
||||||
|
host/bluedroid/bta/hf_ag/include
|
||||||
host/bluedroid/bta/hf_client/include
|
host/bluedroid/bta/hf_client/include
|
||||||
host/bluedroid/bta/hh/include
|
host/bluedroid/bta/hh/include
|
||||||
host/bluedroid/bta/jv/include
|
host/bluedroid/bta/jv/include
|
||||||
|
@ -74,6 +75,7 @@ if(CONFIG_BT_ENABLED)
|
||||||
"host/bluedroid/api/esp_gatt_common_api.c"
|
"host/bluedroid/api/esp_gatt_common_api.c"
|
||||||
"host/bluedroid/api/esp_gattc_api.c"
|
"host/bluedroid/api/esp_gattc_api.c"
|
||||||
"host/bluedroid/api/esp_gatts_api.c"
|
"host/bluedroid/api/esp_gatts_api.c"
|
||||||
|
"host/bluedroid/api/esp_hf_ag_api.c"
|
||||||
"host/bluedroid/api/esp_hf_client_api.c"
|
"host/bluedroid/api/esp_hf_client_api.c"
|
||||||
"host/bluedroid/api/esp_spp_api.c"
|
"host/bluedroid/api/esp_spp_api.c"
|
||||||
"host/bluedroid/bta/ar/bta_ar.c"
|
"host/bluedroid/bta/ar/bta_ar.c"
|
||||||
|
@ -116,6 +118,15 @@ if(CONFIG_BT_ENABLED)
|
||||||
"host/bluedroid/bta/jv/bta_jv_api.c"
|
"host/bluedroid/bta/jv/bta_jv_api.c"
|
||||||
"host/bluedroid/bta/jv/bta_jv_cfg.c"
|
"host/bluedroid/bta/jv/bta_jv_cfg.c"
|
||||||
"host/bluedroid/bta/jv/bta_jv_main.c"
|
"host/bluedroid/bta/jv/bta_jv_main.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_act.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_api.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_at.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_cfg.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_cmd.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_main.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_rfc.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_sco.c"
|
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_sdp.c"
|
||||||
"host/bluedroid/bta/hf_client/bta_hf_client_act.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_act.c"
|
||||||
"host/bluedroid/bta/hf_client/bta_hf_client_api.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_api.c"
|
||||||
"host/bluedroid/bta/hf_client/bta_hf_client_at.c"
|
"host/bluedroid/bta/hf_client/bta_hf_client_at.c"
|
||||||
|
@ -151,6 +162,8 @@ if(CONFIG_BT_ENABLED)
|
||||||
"host/bluedroid/btc/profile/std/a2dp/btc_av.c"
|
"host/bluedroid/btc/profile/std/a2dp/btc_av.c"
|
||||||
"host/bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
"host/bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
||||||
"host/bluedroid/btc/profile/std/avrc/bta_avrc_co.c"
|
"host/bluedroid/btc/profile/std/avrc/bta_avrc_co.c"
|
||||||
|
"host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c"
|
||||||
|
"host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c"
|
||||||
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
||||||
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
||||||
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||||
|
|
|
@ -47,6 +47,9 @@
|
||||||
#if (BTC_SPP_INCLUDED == TRUE)
|
#if (BTC_SPP_INCLUDED == TRUE)
|
||||||
#include "btc_spp.h"
|
#include "btc_spp.h"
|
||||||
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
||||||
|
#if BTC_HF_INCLUDED
|
||||||
|
#include "btc_hf_ag.h"
|
||||||
|
#endif/* #if BTC_HF_INCLUDED */
|
||||||
#if BTC_HF_CLIENT_INCLUDED
|
#if BTC_HF_CLIENT_INCLUDED
|
||||||
#include "btc_hf_client.h"
|
#include "btc_hf_client.h"
|
||||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||||
|
@ -108,6 +111,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||||
#if (BTC_SPP_INCLUDED == TRUE)
|
#if (BTC_SPP_INCLUDED == TRUE)
|
||||||
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
|
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
|
||||||
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */
|
||||||
|
#if BTC_HF_INCLUDED
|
||||||
|
[BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler},
|
||||||
|
#endif /* #if BTC_HF_INCLUDED */
|
||||||
#if BTC_HF_CLIENT_INCLUDED
|
#if BTC_HF_CLIENT_INCLUDED
|
||||||
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
||||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||||
|
|
|
@ -63,6 +63,9 @@ typedef enum {
|
||||||
BTC_PID_AVRC_CT,
|
BTC_PID_AVRC_CT,
|
||||||
BTC_PID_AVRC_TG,
|
BTC_PID_AVRC_TG,
|
||||||
BTC_PID_SPP,
|
BTC_PID_SPP,
|
||||||
|
#if (BTC_HF_INCLUDED == TRUE)
|
||||||
|
BTC_PID_HF,
|
||||||
|
#endif /* BTC_HF_INCLUDED */
|
||||||
#if (BTC_HF_CLIENT_INCLUDED == TRUE)
|
#if (BTC_HF_CLIENT_INCLUDED == TRUE)
|
||||||
BTC_PID_HF_CLIENT,
|
BTC_PID_HF_CLIENT,
|
||||||
#endif /* BTC_HF_CLIENT_INCLUDED */
|
#endif /* BTC_HF_CLIENT_INCLUDED */
|
||||||
|
|
|
@ -27,6 +27,7 @@ ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||||
COMPONENT_PRIV_INCLUDEDIRS += host/bluedroid/bta/include \
|
COMPONENT_PRIV_INCLUDEDIRS += host/bluedroid/bta/include \
|
||||||
host/bluedroid/bta/ar/include \
|
host/bluedroid/bta/ar/include \
|
||||||
host/bluedroid/bta/av/include \
|
host/bluedroid/bta/av/include \
|
||||||
|
host/bluedroid/bta/hf_ag/include \
|
||||||
host/bluedroid/bta/hf_client/include \
|
host/bluedroid/bta/hf_client/include \
|
||||||
host/bluedroid/bta/dm/include \
|
host/bluedroid/bta/dm/include \
|
||||||
host/bluedroid/bta/gatt/include \
|
host/bluedroid/bta/gatt/include \
|
||||||
|
@ -77,6 +78,7 @@ COMPONENT_SRCDIRS += host/bluedroid/bta/dm \
|
||||||
host/bluedroid/bta/ar \
|
host/bluedroid/bta/ar \
|
||||||
host/bluedroid/bta/sys \
|
host/bluedroid/bta/sys \
|
||||||
host/bluedroid/bta/jv \
|
host/bluedroid/bta/jv \
|
||||||
|
host/bluedroid/bta/hf_ag \
|
||||||
host/bluedroid/bta/hf_client \
|
host/bluedroid/bta/hf_client \
|
||||||
host/bluedroid/bta \
|
host/bluedroid/bta \
|
||||||
host/bluedroid/btif \
|
host/bluedroid/btif \
|
||||||
|
@ -94,6 +96,7 @@ COMPONENT_SRCDIRS += host/bluedroid/bta/dm \
|
||||||
host/bluedroid/btc/profile/std/a2dp \
|
host/bluedroid/btc/profile/std/a2dp \
|
||||||
host/bluedroid/btc/profile/std/avrc \
|
host/bluedroid/btc/profile/std/avrc \
|
||||||
host/bluedroid/btc/profile/std/spp \
|
host/bluedroid/btc/profile/std/spp \
|
||||||
|
host/bluedroid/btc/profile/std/hf_ag \
|
||||||
host/bluedroid/btc/profile/std/hf_client \
|
host/bluedroid/btc/profile/std/hf_client \
|
||||||
host/bluedroid/btc/profile \
|
host/bluedroid/btc/profile \
|
||||||
host/bluedroid/stack/btm \
|
host/bluedroid/stack/btm \
|
||||||
|
|
|
@ -72,6 +72,9 @@ choice BT_HFP_ROLE
|
||||||
|
|
||||||
config BT_HFP_CLIENT_ENABLE
|
config BT_HFP_CLIENT_ENABLE
|
||||||
bool "Hands Free Unit"
|
bool "Hands Free Unit"
|
||||||
|
|
||||||
|
config BT_HFP_AG_ENABLE
|
||||||
|
bool "Audio Gateway"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
choice BT_HFP_AUDIO_DATA_PATH
|
choice BT_HFP_AUDIO_DATA_PATH
|
||||||
|
|
529
components/bt/host/bluedroid/api/esp_hf_ag_api.c
Normal file
529
components/bt/host/bluedroid/api/esp_hf_ag_api.c
Normal file
|
@ -0,0 +1,529 @@
|
||||||
|
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "bt_common.h"
|
||||||
|
#include "btc/btc_common.h"
|
||||||
|
#include "btc/btc_dm.h"
|
||||||
|
#include "btc_hf_ag.h"
|
||||||
|
#include "btc/btc_profile_queue.h"
|
||||||
|
#include "btc/btc_manage.h"
|
||||||
|
#include "btc/btc_util.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta/bta_api.h"
|
||||||
|
#include "common/bt_target.h"
|
||||||
|
#include "common/bt_defs.h"
|
||||||
|
#include "device/bdaddr.h"
|
||||||
|
#include "esp_bt.h"
|
||||||
|
#include "esp_hf_ag_api.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_bt_main.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
|
||||||
|
#if (BTC_HF_INCLUDED == TRUE)
|
||||||
|
esp_err_t esp_bt_hf_register_callback(esp_hf_cb_t callback)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
if (callback == NULL) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
btc_profile_cb_set(BTC_PID_HF, callback);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_init(esp_bd_addr_t remote_addr)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_INIT_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.init), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_deinit(esp_bd_addr_t remote_addr)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_DEINIT_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.deinit), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_connect(esp_bd_addr_t remote_addr)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_CONNECT_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.connect), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_disconnect(esp_bd_addr_t remote_addr)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_DISCONNECT_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.disconnect), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_connect_audio(esp_bd_addr_t remote_addr)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_CONNECT_AUDIO_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.connect_audio), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_disconnect_audio(esp_bd_addr_t remote_addr)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_DISCONNECT_AUDIO_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.disconnect_audio), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_vra(esp_bd_addr_t remote_addr, esp_hf_vr_state_t value)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_VRA_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
arg.vra_rep.value = value;
|
||||||
|
memcpy(&(arg.volcon.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_volume_control(esp_bd_addr_t remote_addr, esp_hf_volume_control_target_t type, int volume)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_VOLUME_CONTROL_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
arg.volcon.target_type = type;
|
||||||
|
arg.volcon.volume = volume;
|
||||||
|
memcpy(&(arg.volcon.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_hf_unat_response(esp_bd_addr_t remote_addr, char *unat)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_UNAT_RESPONSE_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
arg.unat_rep.unat = unat;
|
||||||
|
memcpy(&(arg.unat_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_cmee_response(esp_bd_addr_t remote_addr, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_CME_ERR_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
arg.ext_at.response_code = response_code;
|
||||||
|
arg.ext_at.error_code = error_code;
|
||||||
|
memcpy(&(arg.ext_at.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_indchange_notification(esp_bd_addr_t remote_addr,
|
||||||
|
esp_hf_call_status_t call_state,
|
||||||
|
esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
esp_hf_network_state_t ntk_state, int signal)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_IND_NOTIFICATION_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.ind_change.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.ind_change.call_state = call_state;
|
||||||
|
arg.ind_change.call_setup_state = call_setup_state;
|
||||||
|
arg.ind_change.ntk_state = ntk_state;
|
||||||
|
arg.ind_change.signal = signal;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t state = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (state == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_cind_response(esp_bd_addr_t remote_addr,
|
||||||
|
esp_hf_call_status_t call_state,
|
||||||
|
esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
esp_hf_network_state_t ntk_state, int signal, esp_hf_roaming_status_t roam, int batt_lev,
|
||||||
|
esp_hf_call_held_status_t call_held_status)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_CIND_RESPONSE_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.cind_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.cind_rep.call_state = call_state;
|
||||||
|
arg.cind_rep.call_setup_state = call_setup_state;
|
||||||
|
arg.cind_rep.ntk_state = ntk_state;
|
||||||
|
arg.cind_rep.signal = signal;
|
||||||
|
arg.cind_rep.roam = roam;
|
||||||
|
arg.cind_rep.batt_lev = batt_lev;
|
||||||
|
arg.cind_rep.call_held_state = call_held_status;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_cops_response(esp_bd_addr_t remote_addr, char *name)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_COPS_RESPONSE_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.cops_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.cops_rep.name = name; //deep_copy
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_current_call_direction_t dir,
|
||||||
|
esp_hf_current_call_status_t current_call_state, esp_hf_current_call_mode_t mode,
|
||||||
|
esp_hf_current_call_mpty_type_t mpty, char *number, esp_hf_call_addr_type_t type)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_CLCC_RESPONSE_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.clcc_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
//mandatory args
|
||||||
|
arg.clcc_rep.index = index;
|
||||||
|
arg.clcc_rep.dir = dir;
|
||||||
|
arg.clcc_rep.current_call_state = current_call_state;
|
||||||
|
arg.clcc_rep.mode = mode;
|
||||||
|
arg.clcc_rep.mpty = mpty;
|
||||||
|
// option args
|
||||||
|
arg.clcc_rep.number = number; //deep_copy
|
||||||
|
arg.clcc_rep.type = type;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_hf_subscriber_service_type_t type)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_CNUM_RESPONSE_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.cnum_rep), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.cnum_rep.number = number; //deep_copy
|
||||||
|
arg.cnum_rep.type = type;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t state)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_INBAND_RING_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.bsir.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.bsir.state = state;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_answer_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_AC_INCALL_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.phone.num_active = num_active;
|
||||||
|
arg.phone.num_held = num_held;
|
||||||
|
arg.phone.call_state = call_state;
|
||||||
|
arg.phone.call_setup_state = call_setup_state;
|
||||||
|
arg.phone.number = number; //deep_copy
|
||||||
|
arg.phone.call_addr_type = call_addr_type;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_reject_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_RJ_INCALL_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.phone.num_active = num_active;
|
||||||
|
arg.phone.num_held = num_held;
|
||||||
|
arg.phone.call_state = call_state;
|
||||||
|
arg.phone.call_setup_state = call_setup_state;
|
||||||
|
arg.phone.number = number; //deep_copy
|
||||||
|
arg.phone.call_addr_type = call_addr_type;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_end_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_END_CALL_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.phone.num_active = num_active;
|
||||||
|
arg.phone.num_held = num_held;
|
||||||
|
arg.phone.call_state = call_state;
|
||||||
|
arg.phone.call_setup_state = call_setup_state;
|
||||||
|
arg.phone.number = number; //deep_copy
|
||||||
|
arg.phone.call_addr_type = call_addr_type;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_out_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_OUT_CALL_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
memcpy(&(arg.phone.remote_addr), remote_addr, sizeof(esp_bd_addr_t));
|
||||||
|
arg.phone.num_active = num_active;
|
||||||
|
arg.phone.num_held = num_held;
|
||||||
|
arg.phone.call_state = call_state;
|
||||||
|
arg.phone.call_setup_state = call_setup_state;
|
||||||
|
arg.phone.number = number; //deep_copy
|
||||||
|
arg.phone.call_addr_type = call_addr_type;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), btc_hf_arg_deep_copy);
|
||||||
|
return (status = BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_bt_hf_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send)
|
||||||
|
{
|
||||||
|
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_HF;
|
||||||
|
msg.act = BTC_HF_REGISTER_DATA_CALLBACK_EVT;
|
||||||
|
|
||||||
|
btc_hf_args_t arg;
|
||||||
|
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||||
|
arg.reg_data_cb.recv = recv;
|
||||||
|
arg.reg_data_cb.send = send;
|
||||||
|
|
||||||
|
/* Switch to BTC context */
|
||||||
|
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL);
|
||||||
|
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||||
|
void esp_hf_outgoing_data_ready(void)
|
||||||
|
{
|
||||||
|
BTA_AgCiData();
|
||||||
|
}
|
||||||
|
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */
|
||||||
|
|
||||||
|
#endif // BTC_HF_INCLUDED
|
535
components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h
Normal file
535
components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h
Normal file
|
@ -0,0 +1,535 @@
|
||||||
|
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef __ESP_HF_AG_API_H__
|
||||||
|
#define __ESP_HF_AG_API_H__
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_bt_defs.h"
|
||||||
|
#include "esp_hf_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* features masks of HF AG */
|
||||||
|
#define ESP_HF_PEER_FEAT_3WAY 0x01 /* Three-way calling */
|
||||||
|
#define ESP_HF_PEER_FEAT_ECNR 0x02 /* Echo cancellation and/or noise reduction */
|
||||||
|
#define ESP_HF_PEER_FEAT_VREC 0x04 /* Voice recognition */
|
||||||
|
#define ESP_HF_PEER_FEAT_INBAND 0x08 /* In-band ring tone */
|
||||||
|
#define ESP_HF_PEER_FEAT_VTAG 0x10 /* Attach a phone number to a voice tag */
|
||||||
|
#define ESP_HF_PEER_FEAT_REJECT 0x20 /* Ability to reject incoming call */
|
||||||
|
#define ESP_HF_PEER_FEAT_ECS 0x40 /* Enhanced Call Status */
|
||||||
|
#define ESP_HF_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */
|
||||||
|
#define ESP_HF_PEER_FEAT_EXTERR 0x100 /* Extended error codes */
|
||||||
|
#define ESP_HF_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */
|
||||||
|
|
||||||
|
/* CHLD feature masks of HF AG */
|
||||||
|
#define ESP_HF_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */
|
||||||
|
#define ESP_HF_CHLD_FEAT_REL_ACC 0x02 /* 1 Release active calls and accept other waiting or held call */
|
||||||
|
#define ESP_HF_CHLD_FEAT_REL_X 0x04 /* 1x Release specified active call only */
|
||||||
|
#define ESP_HF_CHLD_FEAT_HOLD_ACC 0x08 /* 2 Active calls on hold and accept other waiting or held call */
|
||||||
|
#define ESP_HF_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold) */
|
||||||
|
#define ESP_HF_CHLD_FEAT_MERGE 0x20 /* 3 Add held call to multiparty */
|
||||||
|
#define ESP_HF_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnect from multiparty) */
|
||||||
|
|
||||||
|
/// HF callback events
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ESP_HF_CONNECTION_STATE_EVT = 0, /*!< Connection state changed event */
|
||||||
|
ESP_HF_AUDIO_STATE_EVT, /*!< Audio connection state change event */
|
||||||
|
ESP_HF_BVRA_EVT, /*!< Voice recognition state change event */
|
||||||
|
ESP_HF_VOLUME_CONTROL_EVT, /*!< Audio volume control command from HF Client, provided by +VGM or +VGS message */
|
||||||
|
|
||||||
|
ESP_HF_UNAT_RESPONSE_EVT, /*!< Unknown AT cmd Response*/
|
||||||
|
ESP_HF_CIND_RESPONSE_EVT, /*!< Call And Device Indicator Response*/
|
||||||
|
ESP_HF_COPS_RESPONSE_EVT, /*!< Current operator information */
|
||||||
|
ESP_HF_CLCC_RESPONSE_EVT, /*!< List of current calls notification */
|
||||||
|
ESP_HF_CNUM_RESPONSE_EVT, /*!< Subscriber information response from HF Client */
|
||||||
|
ESP_HF_VTS_RESPONSE_EVT, /*!< Enable or not DTMF */
|
||||||
|
ESP_HF_NREC_RESPONSE_EVT, /*!< Enable or not NREC */
|
||||||
|
|
||||||
|
ESP_HF_ATA_RESPONSE_EVT, /*!< Answer an Incoming Call */
|
||||||
|
ESP_HF_CHUP_RESPONSE_EVT, /*!< Reject an Incoming Call */
|
||||||
|
ESP_HF_DIAL_EVT, /*!< Origin an outgoing call with specific number or the dial the last number */
|
||||||
|
ESP_HF_BAC_RESPONSE_EVT, /*!< Codec Negotiation */
|
||||||
|
ESP_HF_BCS_RESPONSE_EVT, /*!< Codec Negotiation */
|
||||||
|
} esp_hf_cb_event_t;
|
||||||
|
|
||||||
|
// HF callback parameters of corresponding esp event in esp_hf_cb_event_t
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief ESP_HS_CONNECTION_STATE_EVT
|
||||||
|
*/
|
||||||
|
struct hf_conn_stat_param {
|
||||||
|
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||||
|
esp_hf_connection_state_t state; /*!< HF connection state */
|
||||||
|
uint32_t peer_feat; /*!< AG supported features */
|
||||||
|
uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */
|
||||||
|
} conn_stat; /*!< AG callback param of ESP_AG_CONNECTION_STATE_EVT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_AUDIO_STATE_EVT
|
||||||
|
*/
|
||||||
|
struct hf_audio_stat_param {
|
||||||
|
esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */
|
||||||
|
esp_hf_audio_state_t state; /*!< audio connection state */
|
||||||
|
} audio_stat; /*!< AG callback param of ESP_AG_AUDIO_STATE_EVT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_BVRA_EVT
|
||||||
|
*/
|
||||||
|
struct hf_bvra_param {
|
||||||
|
esp_bd_addr_t remote_addr;
|
||||||
|
esp_hf_vr_state_t value; /*!< voice recognition state */
|
||||||
|
} vra_rep; /*!< AG callback param of ESP_AG_BVRA_EVT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_VOLUME_CONTROL_EVT
|
||||||
|
*/
|
||||||
|
struct hf_volume_control_param {
|
||||||
|
esp_hf_volume_type_t type; /*!< volume control target, speaker or microphone */
|
||||||
|
int volume; /*!< gain, ranges from 0 to 15 */
|
||||||
|
} volume_control; /*!< AG callback param of ESP_AG_VOLUME_CONTROL_EVT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_UNAT_RESPOSNE_EVT
|
||||||
|
*/
|
||||||
|
struct hf_unat_param {
|
||||||
|
char *unat;
|
||||||
|
}unat_rep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_AT_RESPONSE_EVT
|
||||||
|
*/
|
||||||
|
struct hf_at_code_param {
|
||||||
|
esp_hf_at_response_code_t code; /*!< AT response code */
|
||||||
|
esp_hf_cme_err_t cme; /*!< Extended Audio Gateway Error Result Code */
|
||||||
|
} at; /*!< AG callback param of ESP_HF_EXT_AT_EVT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_CIND_CALL_EVT
|
||||||
|
*/
|
||||||
|
struct hf_cind_param {
|
||||||
|
esp_hf_call_status_t call_status; /*!< call status indicator */
|
||||||
|
esp_hf_call_setup_status_t call_setup_status; /*!< call setup status indicator */
|
||||||
|
esp_hf_network_state_t svc; /*!< bluetooth proprietary call hold status indicator */
|
||||||
|
int signal_strength; /*!< bluetooth proprietary call hold status indicator */
|
||||||
|
esp_hf_roaming_status_t roam; /*!< bluetooth proprietary call hold status indicator */
|
||||||
|
int battery_level; /*!< battery charge value, ranges from 0 to 5 */
|
||||||
|
esp_hf_call_held_status_t call_held_status; /*!< bluetooth proprietary call hold status indicator */
|
||||||
|
} cind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_VTS_RESPOSNE_EVT
|
||||||
|
*/
|
||||||
|
struct hf_vts_param {
|
||||||
|
char *code;
|
||||||
|
}vts_rep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_NREC_RESPOSNE_EVT
|
||||||
|
*/
|
||||||
|
struct hf_nrec_param {
|
||||||
|
esp_hf_nrec_t state;
|
||||||
|
} nrec;
|
||||||
|
|
||||||
|
struct hf_outcall_param {
|
||||||
|
esp_bd_addr_t remote_addr;
|
||||||
|
char *num_or_loc;
|
||||||
|
} out_call;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_BSIR_EVT
|
||||||
|
*/
|
||||||
|
struct hf_bsir_param {
|
||||||
|
esp_bd_addr_t remote_addr;
|
||||||
|
esp_hf_in_band_ring_state_t state; /*!< setting state of in-band ring tone */
|
||||||
|
} bsir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_HF_BCS_RESPONSE_EVT
|
||||||
|
*/
|
||||||
|
struct hf_codec_param {
|
||||||
|
esp_hf_wbs_config_t mode;
|
||||||
|
} codec;
|
||||||
|
|
||||||
|
} esp_hf_cb_param_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AG incoming data callback function, the callback is useful in case of
|
||||||
|
* Voice Over HCI.
|
||||||
|
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||||
|
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||||
|
* invoke of the callback is finished.
|
||||||
|
* @param[in] len : size(in bytes) in buf
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AG outgoing data callback function, the callback is useful in case of
|
||||||
|
* Voice Over HCI. Once audio connection is set up and the application layer has
|
||||||
|
* prepared data to send, the lower layer will call this function to read data
|
||||||
|
* and then send. This callback is supposed to be implemented as non-blocking,
|
||||||
|
* and if data is not enough, return value 0 is supposed.
|
||||||
|
*
|
||||||
|
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||||
|
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||||
|
* invoke of the callback is finished.
|
||||||
|
* @param[in] len : size(in bytes) in buf
|
||||||
|
* @param[out] length of data successfully read
|
||||||
|
*/
|
||||||
|
typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HF AG callback function type
|
||||||
|
*
|
||||||
|
* @param event : Event type
|
||||||
|
*
|
||||||
|
* @param param : Pointer to callback parameter
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param);
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
** ESP HF API
|
||||||
|
************************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Register application callback function to HFP client module. This function should be called
|
||||||
|
* only after esp_bluedroid_enable() completes successfully, used by HFP client
|
||||||
|
*
|
||||||
|
* @param[in] callback: HFP AG event callback function
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: success
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: if callback is a NULL function pointer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_register_callback(esp_hf_cb_t callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Initialize the bluetooth HF AG module. This function should be called
|
||||||
|
* after esp_bluedroid_enable() completes successfully
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: if the initialization request is sent successfully
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_init(esp_bd_addr_t remote_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief De-initialize for HF AG module. This function
|
||||||
|
* should be called only after esp_bluedroid_enable() completes successfully
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: success
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_deinit(esp_bd_addr_t remote_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Connect to remote bluetooth HFP client device, must after esp_bt_hf_init()
|
||||||
|
*
|
||||||
|
* @param[in] remote_bda: remote bluetooth HFP client device address
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: connect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_connect(esp_bd_addr_t remote_bda);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Disconnect from the remote HFP client
|
||||||
|
*
|
||||||
|
* @param[in] remote_bda: remote bluetooth device address
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_disconnect(esp_bd_addr_t remote_bda);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Create audio connection with remote HFP client. As a precondition to use this API,
|
||||||
|
* Service Level Connection shall exist between HF client and AG.
|
||||||
|
*
|
||||||
|
* @param[in] remote_bda: remote bluetooth device address
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_connect_audio(esp_bd_addr_t remote_bda);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Release the established audio connection with remote HFP client.
|
||||||
|
*
|
||||||
|
* @param[in] remote_bda: remote bluetooth device address
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_disconnect_audio(esp_bd_addr_t remote_bda);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Response of Volume Recognition Command(AT+VRA) from HFP client. As a precondition to use this API,
|
||||||
|
* Service Level Connection shall exist with HFP client.
|
||||||
|
*
|
||||||
|
* @param[in] remote: volume control target, speaker or microphone
|
||||||
|
* @param[in] volume: gain of the speaker of microphone, ranges 0 to 15
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_vra(esp_bd_addr_t remote_bda, esp_hf_vr_state_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Volume synchronization with HFP client. As a precondition to use this API,
|
||||||
|
* Service Level Connection shall exist with HFP client
|
||||||
|
*
|
||||||
|
* @param[in] type: volume control target, speaker or microphone
|
||||||
|
* @param[in] volume: gain of the speaker of microphone, ranges 0 to 15
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_volume_control(esp_bd_addr_t remote_bda, esp_hf_volume_control_target_t type, int volume);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Handle Unknown AT command from HFP Client.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_hf_unat_response(esp_bd_addr_t remote_addr, char *unat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Unsolicited send extend AT error code to HFP Client.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_cmee_response(esp_bd_addr_t remote_bda, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Usolicited send device status notificationto HFP Client.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_indchange_notification(esp_bd_addr_t remote_addr, esp_hf_call_status_t call_state,
|
||||||
|
esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
esp_hf_network_state_t ntk_state, int signal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Response to device individual indicatiors to HFP Client.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_cind_response(esp_bd_addr_t remote_addr,
|
||||||
|
esp_hf_call_status_t call_state,
|
||||||
|
esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
esp_hf_network_state_t ntk_state, int signal, esp_hf_roaming_status_t roam, int batt_lev,
|
||||||
|
esp_hf_call_held_status_t call_held_status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Query the name of currently selected network operator in AG,
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist with HFP Client
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_cops_response(esp_bd_addr_t remote_addr, char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Response to Query list of current calls from HFP Client (use AT+CLCC command),
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_current_call_direction_t dir,
|
||||||
|
esp_hf_current_call_status_t current_call_state, esp_hf_current_call_mode_t mode,
|
||||||
|
esp_hf_current_call_mpty_type_t mpty, char *number, esp_hf_call_addr_type_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Get subscriber information number from HFP client(send AT+CNUM command),
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist with AG
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_hf_subscriber_service_type_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Inform HF Client of Provided or not Inband Ring Tone.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist with AG
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Answer Incoming Call by AG or response to the AT+A command from Hands-Free Unit.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_answer_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Reject Incoming Call by AG or response to the AT+CHUP command from Hands-Free Unit.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_reject_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Reject Incoming Call by AG or response to the AT+CHUP command from Hands-Free Unit.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_out_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Reject Incoming Call by AG or response to the AT+CHUP command from Hands-Free Unit.
|
||||||
|
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: disconnect request is sent to lower layer
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_end_call(esp_bd_addr_t remote_addr, int num_active, int num_held,
|
||||||
|
esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
|
||||||
|
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register AG data output function; the callback is only used in
|
||||||
|
* the case that Voice Over HCI is enabled.
|
||||||
|
*
|
||||||
|
* @param[in] recv: HFP client incoming data callback function
|
||||||
|
* @param[in] send: HFP client outgoing data callback function
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: success
|
||||||
|
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||||
|
* - ESP_FAIL: if callback is a NULL function pointer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_bt_hf_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger the lower-layer to fetch and send audio data. This function is only
|
||||||
|
* only used in the case that Voice Over HCI is enabled. Precondition is that
|
||||||
|
* the HFP audio connection is connected. After this function is called, lower
|
||||||
|
* layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void esp_hf_outgoing_data_ready(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //__ESP_HF_AG_API_H__
|
|
@ -126,7 +126,7 @@ typedef union {
|
||||||
* @brief ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT
|
* @brief ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT
|
||||||
*/
|
*/
|
||||||
struct hf_client_service_availability_param {
|
struct hf_client_service_availability_param {
|
||||||
esp_hf_service_availability_status_t status; /*!< service availability status */
|
esp_hf_network_state_t status; /*!< service availability status */
|
||||||
} service_availability; /*!< HF callback param of ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT */
|
} service_availability; /*!< HF callback param of ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,6 +21,44 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ESP_BT_HF_NUMBER_LEN (32)
|
||||||
|
#define ESP_BT_HF_OPERATOR_NAME_LEN (16)
|
||||||
|
|
||||||
|
#ifndef BTC_HSAG_SERVICE_NAME
|
||||||
|
#define BTC_HSAG_SERVICE_NAME ("Headset Gateway")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BTC_HFAG_SERVICE_NAME
|
||||||
|
#define BTC_HFAG_SERVICE_NAME ("Handsfree Gateway")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BTC_HF_SERVICES
|
||||||
|
#define BTC_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BTC_HF_SERVICE_NAMES
|
||||||
|
#define BTC_HF_SERVICE_NAMES {BTC_HSAG_SERVICE_NAME , BTC_HFAG_SERVICE_NAME}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BTC_HF_SECURITY
|
||||||
|
#define BTC_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BTC_HF_CALL_END_TIMEOUT 6
|
||||||
|
|
||||||
|
#define BTC_HF_INVALID_IDX -1
|
||||||
|
|
||||||
|
/// in-band ring tone state
|
||||||
|
typedef enum {
|
||||||
|
ESP_HF_IN_BAND_RINGTONE_NOT_PROVIDED = 0,
|
||||||
|
ESP_HF_IN_BAND_RINGTONE_PROVIDED,
|
||||||
|
} esp_hf_in_band_ring_state_t;
|
||||||
|
|
||||||
|
/// voice recognition state
|
||||||
|
typedef enum {
|
||||||
|
ESP_HF_VR_STATE_DISABLED = 0, /*!< voice recognition disabled */
|
||||||
|
ESP_HF_VR_STATE_ENABLED, /*!< voice recognition enabled */
|
||||||
|
} esp_hf_vr_state_t;
|
||||||
|
|
||||||
/// Bluetooth HFP audio volume control target
|
/// Bluetooth HFP audio volume control target
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -28,11 +66,32 @@ typedef enum {
|
||||||
ESP_HF_VOLUME_CONTROL_TARGET_MIC, /*!< microphone */
|
ESP_HF_VOLUME_CONTROL_TARGET_MIC, /*!< microphone */
|
||||||
} esp_hf_volume_control_target_t;
|
} esp_hf_volume_control_target_t;
|
||||||
|
|
||||||
/// +CIND roaming status indicator values
|
/// Bluetooth HFP audio connection status
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_HF_ROAMING_STATUS_INACTIVE = 0, /*!< roaming is not active */
|
ESP_HF_AUDIO_STATE_DISCONNECTED = 0, /*!< audio connection released */
|
||||||
ESP_HF_ROAMING_STATUS_ACTIVE, /*!< a roaming is active */
|
ESP_HF_AUDIO_STATE_CONNECTING, /*!< audio connection has been initiated */
|
||||||
} esp_hf_roaming_status_t;
|
ESP_HF_AUDIO_STATE_CONNECTED, /*!< audio connection is established */
|
||||||
|
ESP_HF_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */
|
||||||
|
} esp_hf_audio_state_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ESP_HF_VOLUME_TYPE_SPK = 0,
|
||||||
|
ESP_HF_VOLUME_TYPE_MIC
|
||||||
|
} esp_hf_volume_type_t;
|
||||||
|
|
||||||
|
/// +CIND network service availability status
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ESP_HF_NETWORK_STATE_NOT_AVAILABLE = 0,
|
||||||
|
ESP_HF_NETWORK_STATE_AVAILABLE
|
||||||
|
} esp_hf_network_state_t;
|
||||||
|
|
||||||
|
/** +CIEV Service type */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ESP_HF_SERVICE_TYPE_HOME = 0,
|
||||||
|
ESP_HF_SERVICE_TYPE_ROAMING
|
||||||
|
} esp_hf_service_type_t;
|
||||||
|
|
||||||
/// +CIND call status indicator values
|
/// +CIND call status indicator values
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -42,12 +101,18 @@ typedef enum {
|
||||||
|
|
||||||
/// +CIND call setup status indicator values
|
/// +CIND call setup status indicator values
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_HF_CALL_SETUP_STATUS_NONE = 0, /*!< no call setup in progress */
|
ESP_HF_CALL_SETUP_STATUS_IDLE = 0, /*!< no call setup in progress */
|
||||||
ESP_HF_CALL_SETUP_STATUS_INCOMING = 1, /*!< incoming call setup in progress */
|
ESP_HF_CALL_SETUP_STATUS_INCOMING = 1, /*!< incoming call setup in progress */
|
||||||
ESP_HF_CALL_SETUP_STATUS_OUTGOING_DIALING = 2, /*!< outgoing call setup in dialing state */
|
ESP_HF_CALL_SETUP_STATUS_OUTGOING_DIALING = 2, /*!< outgoing call setup in dialing state */
|
||||||
ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING = 3, /*!< outgoing call setup in alerting state */
|
ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING = 3, /*!< outgoing call setup in alerting state */
|
||||||
} esp_hf_call_setup_status_t;
|
} esp_hf_call_setup_status_t;
|
||||||
|
|
||||||
|
/// +CIND roaming status indicator values
|
||||||
|
typedef enum {
|
||||||
|
ESP_HF_ROAMING_STATUS_INACTIVE = 0, /*!< roaming is not active */
|
||||||
|
ESP_HF_ROAMING_STATUS_ACTIVE, /*!< a roaming is active */
|
||||||
|
} esp_hf_roaming_status_t;
|
||||||
|
|
||||||
/// +CIND call held indicator values
|
/// +CIND call held indicator values
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_HF_CALL_HELD_STATUS_NONE = 0, /*!< no calls held */
|
ESP_HF_CALL_HELD_STATUS_NONE = 0, /*!< no calls held */
|
||||||
|
@ -55,12 +120,6 @@ typedef enum {
|
||||||
ESP_HF_CALL_HELD_STATUS_HELD = 2, /*!< call on hold, no active call*/
|
ESP_HF_CALL_HELD_STATUS_HELD = 2, /*!< call on hold, no active call*/
|
||||||
} esp_hf_call_held_status_t;
|
} esp_hf_call_held_status_t;
|
||||||
|
|
||||||
/// +CIND network service availability status
|
|
||||||
typedef enum {
|
|
||||||
ESP_HF_SERVICE_AVAILABILITY_STATUS_UNAVAILABLE = 0, /*!< service not available */
|
|
||||||
ESP_HF_SERVICE_AVAILABILITY_STATUS_AVAILABLE, /*!< service available */
|
|
||||||
} esp_hf_service_availability_status_t;
|
|
||||||
|
|
||||||
/// +CLCC status of the call
|
/// +CLCC status of the call
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_HF_CURRENT_CALL_STATUS_ACTIVE = 0, /*!< active */
|
ESP_HF_CURRENT_CALL_STATUS_ACTIVE = 0, /*!< active */
|
||||||
|
@ -118,23 +177,35 @@ typedef enum {
|
||||||
ESP_HF_BTRH_CMD_REJECT = 2, /*!< reject a held incoming call */
|
ESP_HF_BTRH_CMD_REJECT = 2, /*!< reject a held incoming call */
|
||||||
} esp_hf_btrh_cmd_t;
|
} esp_hf_btrh_cmd_t;
|
||||||
|
|
||||||
/// response indication codes for AT commands
|
/* +NREC */
|
||||||
typedef enum {
|
typedef enum
|
||||||
ESP_HF_AT_RESPONSE_CODE_OK = 0, /*!< acknowledges execution of a command line */
|
{
|
||||||
ESP_HF_AT_RESPONSE_CODE_ERR, /*!< command not accepted */
|
ESP_HF_NREC_STOP = 0,
|
||||||
ESP_HF_AT_RESPONSE_CODE_NO_CARRIER, /*!< connection terminated */
|
ESP_HF_NREC_START
|
||||||
ESP_HF_AT_RESPONSE_CODE_BUSY, /*!< busy signal detected */
|
} esp_hf_nrec_t;
|
||||||
ESP_HF_AT_RESPONSE_CODE_NO_ANSWER, /*!< connection completion timeout */
|
|
||||||
ESP_HF_AT_RESPONSE_CODE_DELAYED, /*!< delayed */
|
|
||||||
ESP_HF_AT_RESPONSE_CODE_BLACKLISTED, /*!< blacklisted */
|
|
||||||
ESP_HF_AT_RESPONSE_CODE_CME, /*!< CME error */
|
|
||||||
} esp_hf_at_response_code_t;
|
|
||||||
|
|
||||||
/// voice recognition state
|
///+CCWA resposne status
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_HF_VR_STATE_DISABLED = 0, /*!< voice recognition disabled */
|
ESP_HF_CALL_WAITING_INACTIVE,
|
||||||
ESP_HF_VR_STATE_ENABLED, /*!< voice recognition enabled */
|
ESP_HF_CALL_WAITING_ACTIVE,
|
||||||
} esp_hf_vr_state_t;
|
} esp_hf_call_waiting_status_t;
|
||||||
|
|
||||||
|
/* WBS codec setting */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ESP_HF_WBS_NONE,
|
||||||
|
ESP_HF_WBS_NO,
|
||||||
|
ESP_HF_WBS_YES
|
||||||
|
}esp_hf_wbs_config_t;
|
||||||
|
|
||||||
|
/// Bluetooth HFP RFCOMM connection and service level connection status
|
||||||
|
typedef enum {
|
||||||
|
ESP_HF_CONNECTION_STATE_DISCONNECTED = 0, /*!< RFCOMM data link channel released */
|
||||||
|
ESP_HF_CONNECTION_STATE_CONNECTING, /*!< connecting remote device on the RFCOMM data link*/
|
||||||
|
ESP_HF_CONNECTION_STATE_CONNECTED, /*!< RFCOMM connection established */
|
||||||
|
ESP_HF_CONNECTION_STATE_SLC_CONNECTED, /*!< service level connection established */
|
||||||
|
ESP_HF_CONNECTION_STATE_DISCONNECTING, /*!< disconnecting with remote device on the RFCOMM data link*/
|
||||||
|
} esp_hf_connection_state_t;
|
||||||
|
|
||||||
/// AT+CHLD command values
|
/// AT+CHLD command values
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -147,6 +218,24 @@ typedef enum {
|
||||||
ESP_HF_CHLD_TYPE_PRIV_X, /*!< <2x>, request private consultation mode with specified call */
|
ESP_HF_CHLD_TYPE_PRIV_X, /*!< <2x>, request private consultation mode with specified call */
|
||||||
} esp_hf_chld_type_t;
|
} esp_hf_chld_type_t;
|
||||||
|
|
||||||
|
/* AT response code - OK/Error */
|
||||||
|
typedef enum {
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_OK = 0, /*!< acknowledges execution of a command line */
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_ERR, /*!< command not accepted */
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_NO_CARRIER, /*!< connection terminated */
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_BUSY, /*!< busy signal detected */
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_NO_ANSWER, /*!< connection completion timeout */
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_DELAYED, /*!< delayed */
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_BLACKLISTED, /*!< blacklisted */
|
||||||
|
ESP_HF_AT_RESPONSE_CODE_CME, /*!< CME error */
|
||||||
|
} esp_hf_at_response_code_t;
|
||||||
|
|
||||||
|
/* AT response code - OK/Error */
|
||||||
|
typedef enum {
|
||||||
|
ESP_HF_AT_RESPONSE_ERROR = 0,
|
||||||
|
ESP_HF_AT_RESPONSE_OK
|
||||||
|
} esp_hf_at_response_t;
|
||||||
|
|
||||||
/// Extended Audio Gateway Error Result Code Response
|
/// Extended Audio Gateway Error Result Code Response
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_HF_CME_AG_FAILURE = 0, /*!< ag failure */
|
ESP_HF_CME_AG_FAILURE = 0, /*!< ag failure */
|
||||||
|
@ -174,6 +263,84 @@ typedef enum {
|
||||||
ESP_HF_CME_NETWORK_NOT_ALLOWED = 32, /*!< network not allowed --emergency calls only */
|
ESP_HF_CME_NETWORK_NOT_ALLOWED = 32, /*!< network not allowed --emergency calls only */
|
||||||
} esp_hf_cme_err_t;
|
} esp_hf_cme_err_t;
|
||||||
|
|
||||||
|
/** Callback for connection state change.
|
||||||
|
* state will have one of the values from BtHfConnectionState
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_connection_state_callback)(esp_hf_connection_state_t state, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for audio connection state change.
|
||||||
|
* state will have one of the values from BtHfAudioState
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_audio_state_callback)(esp_hf_audio_state_t state, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for VR connection state change.
|
||||||
|
* state will have one of the values from BtHfVRState
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_vr_cmd_callback)(esp_hf_vr_state_t state, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for answer incoming call (ATA)
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_answer_call_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for disconnect call (AT+CHUP)
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_hangup_call_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for disconnect call (AT+CHUP)
|
||||||
|
* type will denote Speaker/Mic gain (BtHfVolumeControl).
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_volume_cmd_callback)(esp_hf_volume_control_target_t type, int volume, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for dialing an outgoing call
|
||||||
|
* If number is NULL, redial
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_dial_call_cmd_callback)(char *number, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for sending DTMF tones
|
||||||
|
* tone contains the dtmf character to be sent
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_dtmf_cmd_callback)(char tone, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for enabling/disabling noise reduction/echo cancellation
|
||||||
|
* value will be 1 to enable, 0 to disable
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_nrec_cmd_callback)(esp_hf_nrec_t nrec, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for AT+BCS and event from BAC
|
||||||
|
* WBS enable, WBS disable
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_wbs_callback)(esp_hf_wbs_config_t wbs, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for call hold handling (AT+CHLD)
|
||||||
|
* value will contain the call hold command (0, 1, 2, 3)
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_chld_cmd_callback)(esp_hf_chld_type_t chld, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for CNUM (subscriber number)
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_cnum_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for indicators (CIND)
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_cind_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for operator selection (COPS)
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_cops_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for call list (AT+CLCC)
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_clcc_cmd_callback) (esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for unknown AT command recd from AG
|
||||||
|
* at_string will contain the unparsed AT string
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_unknown_at_cmd_callback)(char *at_string, esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
|
/** Callback for keypressed (HSP) event.
|
||||||
|
*/
|
||||||
|
typedef void (* esp_hf_key_pressed_cmd_callback)(esp_bd_addr_t *bd_addr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
818
components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c
Normal file
818
components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c
Normal file
|
@ -0,0 +1,818 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This file contains action functions for the audio gateway.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
#include <string.h>
|
||||||
|
#include "bta_ag_int.h"
|
||||||
|
#include "bta/bta_sys.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta/bta_ag_co.h"
|
||||||
|
#include "stack/port_api.h"
|
||||||
|
#include "stack/l2c_api.h"
|
||||||
|
#include "bta_dm_int.h"
|
||||||
|
#include "bta/bta_sdp_api.h"
|
||||||
|
#include "bta/utl.h"
|
||||||
|
#include "common/bt_trace.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
/*****************************************************************************
|
||||||
|
** Constants
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* maximum length of data to read from RFCOMM */
|
||||||
|
#define BTA_AG_RFC_READ_MAX 512
|
||||||
|
|
||||||
|
/* maximum AT command length */
|
||||||
|
#define BTA_AG_CMD_MAX 512
|
||||||
|
|
||||||
|
const UINT16 bta_ag_uuid[BTA_AG_NUM_IDX] =
|
||||||
|
{
|
||||||
|
UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,
|
||||||
|
UUID_SERVCLASS_AG_HANDSFREE
|
||||||
|
};
|
||||||
|
|
||||||
|
const UINT8 bta_ag_sec_id[BTA_AG_NUM_IDX] =
|
||||||
|
{
|
||||||
|
BTM_SEC_SERVICE_HEADSET_AG,
|
||||||
|
BTM_SEC_SERVICE_AG_HANDSFREE
|
||||||
|
};
|
||||||
|
|
||||||
|
const tBTA_SERVICE_ID bta_ag_svc_id[BTA_AG_NUM_IDX] =
|
||||||
|
{
|
||||||
|
BTA_HSP_SERVICE_ID,
|
||||||
|
BTA_HFP_SERVICE_ID
|
||||||
|
};
|
||||||
|
|
||||||
|
const tBTA_SERVICE_MASK bta_ag_svc_mask[BTA_AG_NUM_IDX] =
|
||||||
|
{
|
||||||
|
BTA_HSP_SERVICE_MASK,
|
||||||
|
BTA_HFP_SERVICE_MASK
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*tBTA_AG_ATCMD_CBACK)(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
|
||||||
|
char *p_arg, INT16 int_arg);
|
||||||
|
|
||||||
|
const tBTA_AG_ATCMD_CBACK bta_ag_at_cback_tbl[BTA_AG_NUM_IDX] =
|
||||||
|
{
|
||||||
|
bta_ag_at_hsp_cback,
|
||||||
|
bta_ag_at_hfp_cback
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_cback_open
|
||||||
|
**
|
||||||
|
** Description Send open callback event to application.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_cback_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data, tBTA_AG_STATUS status)
|
||||||
|
{
|
||||||
|
tBTA_AG_OPEN open;
|
||||||
|
/* call app callback with open event */
|
||||||
|
open.hdr.handle = bta_ag_scb_to_idx(p_scb);
|
||||||
|
open.hdr.app_id = p_scb->app_id;
|
||||||
|
open.status = status;
|
||||||
|
open.service_id = bta_ag_svc_id[p_scb->conn_service];
|
||||||
|
if (p_data) {
|
||||||
|
/* if p_data is provided then we need to pick the bd address from the open api structure */
|
||||||
|
bdcpy(open.bd_addr, p_data->api_open.bd_addr);
|
||||||
|
} else {
|
||||||
|
bdcpy(open.bd_addr, p_scb->peer_addr);
|
||||||
|
}
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_OPEN_EVT, (tBTA_AG *) &open);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_register
|
||||||
|
**
|
||||||
|
** Description This function initializes values of the AG cb and sets up
|
||||||
|
** the SDP record for the services.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_register(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_REGISTER reg;
|
||||||
|
/* initialize control block */
|
||||||
|
p_scb->reg_services = p_data->api_register.services;
|
||||||
|
p_scb->serv_sec_mask = p_data->api_register.sec_mask;
|
||||||
|
p_scb->features = p_data->api_register.features;
|
||||||
|
p_scb->app_id = p_data->api_register.app_id;
|
||||||
|
/* create SDP records */
|
||||||
|
bta_ag_create_records(p_scb, p_data);
|
||||||
|
/* start RFCOMM servers */
|
||||||
|
bta_ag_start_servers(p_scb, p_scb->reg_services);
|
||||||
|
/* call app callback with register event */
|
||||||
|
reg.hdr.handle = bta_ag_scb_to_idx(p_scb);
|
||||||
|
reg.hdr.app_id = p_scb->app_id;
|
||||||
|
reg.status = BTA_AG_SUCCESS;
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG *) ®);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_deregister
|
||||||
|
**
|
||||||
|
** Description This function removes the sdp records, closes the RFCOMM
|
||||||
|
** servers, and deallocates the service control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_deregister(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* set dealloc */
|
||||||
|
p_scb->dealloc = TRUE;
|
||||||
|
/* remove sdp records */
|
||||||
|
bta_ag_del_records(p_scb, p_data);
|
||||||
|
/* remove rfcomm servers */
|
||||||
|
bta_ag_close_servers(p_scb, p_scb->reg_services);
|
||||||
|
/* dealloc */
|
||||||
|
bta_ag_scb_dealloc(p_scb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_start_dereg
|
||||||
|
**
|
||||||
|
** Description Start a deregister event.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_start_dereg(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* set dealloc */
|
||||||
|
p_scb->dealloc = TRUE;
|
||||||
|
/* remove sdp records */
|
||||||
|
bta_ag_del_records(p_scb, p_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_start_open
|
||||||
|
**
|
||||||
|
** Description This starts an AG open.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_start_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
BD_ADDR pending_bd_addr;
|
||||||
|
/* store parameters */
|
||||||
|
if (p_data) {
|
||||||
|
bdcpy(p_scb->peer_addr, p_data->api_open.bd_addr);
|
||||||
|
p_scb->open_services = p_data->api_open.services;
|
||||||
|
p_scb->cli_sec_mask = p_data->api_open.sec_mask;
|
||||||
|
}
|
||||||
|
/* Check if RFCOMM has any incoming connection to avoid collision. */
|
||||||
|
if (PORT_IsOpening (pending_bd_addr)) {
|
||||||
|
/* Let the incoming connection goes through. */
|
||||||
|
/* Issue collision for this scb for now. */
|
||||||
|
/* We will decide what to do when we find incoming connetion later. */
|
||||||
|
bta_ag_collision_cback (0, BTA_ID_AG, 0, p_scb->peer_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* close servers */
|
||||||
|
bta_ag_close_servers(p_scb, p_scb->reg_services);
|
||||||
|
/* set role */
|
||||||
|
p_scb->role = BTA_AG_INT;
|
||||||
|
/* do service search */
|
||||||
|
bta_ag_do_disc(p_scb, p_scb->open_services);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_disc_int_res
|
||||||
|
**
|
||||||
|
** Description This function handles a discovery result when initiator.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_disc_int_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UINT16 event = BTA_AG_DISC_FAIL_EVT;
|
||||||
|
APPL_TRACE_DEBUG ("bta_ag_disc_int_res: Status: %d", p_data->disc_result.status);
|
||||||
|
|
||||||
|
/* if found service */
|
||||||
|
if (p_data->disc_result.status == SDP_SUCCESS ||
|
||||||
|
p_data->disc_result.status == SDP_DB_FULL) {
|
||||||
|
/* get attributes */
|
||||||
|
if (bta_ag_sdp_find_attr(p_scb, p_scb->open_services)) {
|
||||||
|
/* set connected service */
|
||||||
|
p_scb->conn_service = bta_ag_service_to_idx(p_scb->open_services);
|
||||||
|
/* send ourselves sdp ok event */
|
||||||
|
event = BTA_AG_DISC_OK_EVT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* free discovery db */
|
||||||
|
bta_ag_free_db(p_scb, p_data);
|
||||||
|
/* if service not found check if we should search for other service */
|
||||||
|
if ((event == BTA_AG_DISC_FAIL_EVT) &&
|
||||||
|
(p_data->disc_result.status == SDP_SUCCESS ||
|
||||||
|
p_data->disc_result.status == SDP_DB_FULL ||
|
||||||
|
p_data->disc_result.status == SDP_NO_RECS_MATCH)) {
|
||||||
|
if ((p_scb->open_services & BTA_HFP_SERVICE_MASK) &&
|
||||||
|
(p_scb->open_services & BTA_HSP_SERVICE_MASK)) {
|
||||||
|
/* search for HSP */
|
||||||
|
p_scb->open_services &= ~BTA_HFP_SERVICE_MASK;
|
||||||
|
bta_ag_do_disc(p_scb, p_scb->open_services);
|
||||||
|
} else if ((p_scb->open_services & BTA_HSP_SERVICE_MASK) &&
|
||||||
|
(p_scb->hsp_version == HSP_VERSION_1_2)) {
|
||||||
|
/* search for UUID_SERVCLASS_HEADSET for HSP 1.0 device */
|
||||||
|
p_scb->hsp_version = HSP_VERSION_1_0;
|
||||||
|
bta_ag_do_disc(p_scb, p_scb->open_services);
|
||||||
|
} else {
|
||||||
|
/* send ourselves sdp ok/fail event */
|
||||||
|
bta_ag_sm_execute(p_scb, event, p_data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* send ourselves sdp ok/fail event */
|
||||||
|
bta_ag_sm_execute(p_scb, event, p_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_disc_acp_res
|
||||||
|
**
|
||||||
|
** Description This function handles a discovery result when acceptor.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_disc_acp_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* if found service */
|
||||||
|
if (p_data->disc_result.status == SDP_SUCCESS ||
|
||||||
|
p_data->disc_result.status == SDP_DB_FULL) {
|
||||||
|
/* get attributes */
|
||||||
|
bta_ag_sdp_find_attr(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
|
||||||
|
}
|
||||||
|
/* free discovery db */
|
||||||
|
bta_ag_free_db(p_scb, p_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_disc_fail
|
||||||
|
**
|
||||||
|
** Description This function handles a discovery failure.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_disc_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UNUSED(p_data);
|
||||||
|
/* reopen registered servers */
|
||||||
|
bta_ag_start_servers(p_scb, p_scb->reg_services);
|
||||||
|
/* reinitialize stuff */
|
||||||
|
/* call open cback w. failure */
|
||||||
|
bta_ag_cback_open(p_scb, NULL, BTA_AG_FAIL_SDP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_open_fail
|
||||||
|
**
|
||||||
|
** Description open connection failed.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_open_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* call open cback w. failure */
|
||||||
|
bta_ag_cback_open(p_scb, p_data, BTA_AG_FAIL_RESOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rfc_fail
|
||||||
|
**
|
||||||
|
** Description RFCOMM connection failed.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rfc_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UNUSED(p_data);
|
||||||
|
/* reinitialize stuff */
|
||||||
|
p_scb->conn_handle = 0;
|
||||||
|
p_scb->conn_service = 0;
|
||||||
|
p_scb->peer_features = 0;
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
p_scb->peer_codecs = BTA_AG_CODEC_NONE;
|
||||||
|
p_scb->sco_codec = BTA_AG_CODEC_NONE;
|
||||||
|
#endif
|
||||||
|
p_scb->role = 0;
|
||||||
|
p_scb->svc_conn = FALSE;
|
||||||
|
p_scb->hsp_version = HSP_VERSION_1_2;
|
||||||
|
/*Clear the BD address*/
|
||||||
|
bdcpy(p_scb->peer_addr, bd_addr_null);
|
||||||
|
/* reopen registered servers */
|
||||||
|
bta_ag_start_servers(p_scb, p_scb->reg_services);
|
||||||
|
/* call open cback w. failure */
|
||||||
|
bta_ag_cback_open(p_scb, NULL, BTA_AG_FAIL_RFCOMM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rfc_close
|
||||||
|
**
|
||||||
|
** Description RFCOMM connection closed.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rfc_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_CLOSE close;
|
||||||
|
tBTA_SERVICE_MASK services;
|
||||||
|
int i, num_active_conn = 0;
|
||||||
|
UNUSED(p_data);
|
||||||
|
/* reinitialize stuff */
|
||||||
|
p_scb->conn_service = 0;
|
||||||
|
p_scb->peer_features = 0;
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
p_scb->peer_codecs = BTA_AG_CODEC_NONE;
|
||||||
|
p_scb->sco_codec = BTA_AG_CODEC_NONE;
|
||||||
|
/* Clear these flags upon SLC teardown */
|
||||||
|
p_scb->codec_updated = FALSE;
|
||||||
|
p_scb->codec_fallback = FALSE;
|
||||||
|
p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
|
||||||
|
#endif
|
||||||
|
p_scb->role = 0;
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
p_scb->svc_conn = FALSE;
|
||||||
|
p_scb->hsp_version = HSP_VERSION_1_2;
|
||||||
|
bta_ag_at_reinit(&p_scb->at_cb);
|
||||||
|
/* stop timers */
|
||||||
|
bta_sys_stop_timer(&p_scb->act_timer);
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE)
|
||||||
|
bta_sys_stop_timer(&p_scb->cn_timer);
|
||||||
|
#endif
|
||||||
|
close.hdr.handle = bta_ag_scb_to_idx(p_scb);
|
||||||
|
close.hdr.app_id = p_scb->app_id;
|
||||||
|
bdcpy(close.bd_addr, p_scb->peer_addr);
|
||||||
|
|
||||||
|
bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
|
||||||
|
/* call close call-out */
|
||||||
|
// bta_ag_sco_co_close(close.hdr.handle);
|
||||||
|
bta_ag_sco_co_close();
|
||||||
|
/* call close cback */
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG *) &close);
|
||||||
|
|
||||||
|
/* if not deregistering (deallocating) reopen registered servers */
|
||||||
|
if (p_scb->dealloc == FALSE) {
|
||||||
|
/* Clear peer bd_addr so instance can be reused */
|
||||||
|
bdcpy(p_scb->peer_addr, bd_addr_null);
|
||||||
|
|
||||||
|
/* start only unopened server */
|
||||||
|
services = p_scb->reg_services;
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++) {
|
||||||
|
if (p_scb->serv_handle[i]) {
|
||||||
|
services &= ~((tBTA_SERVICE_MASK)1 << (BTA_HSP_SERVICE_ID + i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bta_ag_start_servers(p_scb, services);
|
||||||
|
p_scb->conn_handle = 0;
|
||||||
|
/* Make sure SCO state is BTA_AG_SCO_SHUTDOWN_ST */
|
||||||
|
bta_ag_sco_shutdown(p_scb, NULL);
|
||||||
|
/* Check if all the SLCs are down */
|
||||||
|
for (i = 0; i < BTA_AG_NUM_SCB; i++) {
|
||||||
|
if (bta_ag_cb.scb[i].in_use && bta_ag_cb.scb[i].svc_conn) {
|
||||||
|
num_active_conn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!num_active_conn) {
|
||||||
|
bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* else close port and deallocate scb */
|
||||||
|
RFCOMM_RemoveServer(p_scb->conn_handle);
|
||||||
|
bta_ag_scb_dealloc(p_scb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rfc_open
|
||||||
|
**
|
||||||
|
** Description Handle RFCOMM channel open.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rfc_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* initialize AT feature variables */
|
||||||
|
p_scb->clip_enabled = FALSE;
|
||||||
|
p_scb->ccwa_enabled = FALSE;
|
||||||
|
p_scb->cmer_enabled = FALSE;
|
||||||
|
p_scb->cmee_enabled = FALSE;
|
||||||
|
p_scb->inband_enabled = ((p_scb->features & BTA_AG_FEAT_INBAND) == BTA_AG_FEAT_INBAND);
|
||||||
|
|
||||||
|
/* set up AT command interpreter */
|
||||||
|
p_scb->at_cb.p_at_tbl = (tBTA_AG_AT_CMD *) bta_ag_at_tbl[p_scb->conn_service];
|
||||||
|
p_scb->at_cb.p_cmd_cback = (tBTA_AG_AT_CMD_CBACK *) bta_ag_at_cback_tbl[p_scb->conn_service];
|
||||||
|
p_scb->at_cb.p_err_cback = (tBTA_AG_AT_ERR_CBACK *) bta_ag_at_err_cback;
|
||||||
|
p_scb->at_cb.p_user = p_scb;
|
||||||
|
p_scb->at_cb.cmd_max_len = BTA_AG_CMD_MAX;
|
||||||
|
bta_ag_at_init(&p_scb->at_cb);
|
||||||
|
|
||||||
|
/* call app open call-out */
|
||||||
|
bta_ag_sco_co_open(bta_ag_scb_to_idx(p_scb), p_scb->air_mode, BTA_HFP_SCO_OUT_PKT_SIZE, bta_ag_svc_id[p_scb->conn_service]);
|
||||||
|
bta_sys_conn_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
bta_ag_cback_open(p_scb, NULL, BTA_AG_SUCCESS);
|
||||||
|
|
||||||
|
if (p_scb->conn_service == BTA_AG_HFP) {
|
||||||
|
/* if hfp start timer for service level conn */
|
||||||
|
bta_sys_start_timer(&p_scb->act_timer, BTA_AG_SVC_TOUT_EVT, p_bta_ag_cfg->conn_tout);
|
||||||
|
} else {
|
||||||
|
/* else service level conn is open */
|
||||||
|
bta_ag_svc_conn_open(p_scb, p_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rfc_acp_open
|
||||||
|
**
|
||||||
|
** Description Handle RFCOMM channel open when accepting connection.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rfc_acp_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UINT16 lcid;
|
||||||
|
int i;
|
||||||
|
tBTA_AG_SCB *ag_scb, *other_scb;
|
||||||
|
BD_ADDR dev_addr;
|
||||||
|
int status;
|
||||||
|
/* set role */
|
||||||
|
p_scb->role = BTA_AG_ACP;
|
||||||
|
APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d",
|
||||||
|
p_scb->serv_handle[0], p_scb->serv_handle[1]);
|
||||||
|
/* get bd addr of peer */
|
||||||
|
if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) {
|
||||||
|
APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", status);
|
||||||
|
}
|
||||||
|
/* Collision Handling */
|
||||||
|
for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, ag_scb++) {
|
||||||
|
if ((ag_scb->in_use) && (ag_scb->colli_tmr_on)) {
|
||||||
|
/* stop collision timer */
|
||||||
|
ag_scb->colli_tmr_on = FALSE;
|
||||||
|
bta_sys_stop_timer (&ag_scb->colli_timer);
|
||||||
|
|
||||||
|
if (bdcmp (dev_addr, ag_scb->peer_addr) == 0) {
|
||||||
|
/* If incoming and outgoing device are same, nothing more to do. */
|
||||||
|
/* Outgoing conn will be aborted because we have successful incoming conn. */
|
||||||
|
} else {
|
||||||
|
/* Resume outgoing connection. */
|
||||||
|
other_scb = bta_ag_get_other_idle_scb (p_scb);
|
||||||
|
if (other_scb) {
|
||||||
|
bdcpy(other_scb->peer_addr, ag_scb->peer_addr);
|
||||||
|
other_scb->open_services = ag_scb->open_services;
|
||||||
|
other_scb->cli_sec_mask = ag_scb->cli_sec_mask;
|
||||||
|
bta_ag_resume_open (other_scb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bdcpy (p_scb->peer_addr, dev_addr);
|
||||||
|
/* determine connected service from port handle */
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX; i++) {
|
||||||
|
APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d",
|
||||||
|
i, p_scb->serv_handle[i], p_data->rfc.port_handle);
|
||||||
|
if (p_scb->serv_handle[i] == p_data->rfc.port_handle) {
|
||||||
|
p_scb->conn_service = i;
|
||||||
|
p_scb->conn_handle = p_data->rfc.port_handle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d",
|
||||||
|
p_scb->conn_service, p_scb->conn_handle);
|
||||||
|
/* close any unopened server */
|
||||||
|
bta_ag_close_servers(p_scb, (p_scb->reg_services & ~bta_ag_svc_mask[p_scb->conn_service]));
|
||||||
|
/* do service discovery to get features */
|
||||||
|
bta_ag_do_disc(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
|
||||||
|
/* continue with common open processing */
|
||||||
|
bta_ag_rfc_open(p_scb, p_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rfc_data
|
||||||
|
**
|
||||||
|
** Description Read and process data from RFCOMM.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rfc_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UINT16 len;
|
||||||
|
char buf[BTA_AG_RFC_READ_MAX];
|
||||||
|
UNUSED(p_data);
|
||||||
|
memset(buf, 0, BTA_AG_RFC_READ_MAX);
|
||||||
|
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_rfc_data");
|
||||||
|
/* do the following */
|
||||||
|
for (;;) {
|
||||||
|
/* read data from rfcomm; if bad status, we're done */
|
||||||
|
if (PORT_ReadData(p_scb->conn_handle, buf, BTA_AG_RFC_READ_MAX, &len) != PORT_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* if no data, we're done */
|
||||||
|
if (len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* run AT command interpreter on data */
|
||||||
|
bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
bta_ag_at_parse(&p_scb->at_cb, buf, len);
|
||||||
|
bta_sys_idle(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
/* no more data to read, we're done */
|
||||||
|
if (len < BTA_AG_RFC_READ_MAX) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_start_close
|
||||||
|
**
|
||||||
|
** Description Start the process of closing SCO and RFCOMM connection.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_start_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* Take the link out of sniff and set L2C idle time to 0 */
|
||||||
|
bta_dm_pm_active(p_scb->peer_addr);
|
||||||
|
L2CA_SetIdleTimeoutByBdAddr(p_scb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
|
||||||
|
/* if SCO is open close SCO and wait on RFCOMM close */
|
||||||
|
if (bta_ag_sco_is_open(p_scb)) {
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_CLOSE_RFC;
|
||||||
|
} else {
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
bta_ag_rfc_do_close(p_scb, p_data);
|
||||||
|
}
|
||||||
|
/* Always do SCO shutdown to handle all SCO corner cases */
|
||||||
|
bta_ag_sco_shutdown(p_scb, p_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_post_sco_open
|
||||||
|
**
|
||||||
|
** Description Perform post-SCO open action, if any
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_post_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
switch (p_scb->post_sco) {
|
||||||
|
case BTA_AG_POST_SCO_RING:
|
||||||
|
bta_ag_send_ring(p_scb, p_data);
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BTA_AG_POST_SCO_CALL_CONN:
|
||||||
|
bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_post_sco_close
|
||||||
|
**
|
||||||
|
** Description Perform post-SCO close action, if any
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_post_sco_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
switch (p_scb->post_sco) {
|
||||||
|
case BTA_AG_POST_SCO_CLOSE_RFC:
|
||||||
|
bta_ag_rfc_do_close(p_scb, p_data);
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BTA_AG_POST_SCO_CALL_CONN:
|
||||||
|
bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BTA_AG_POST_SCO_CALL_ORIG:
|
||||||
|
bta_ag_send_call_inds(p_scb, BTA_AG_OUT_CALL_ORIG_RES);
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BTA_AG_POST_SCO_CALL_END:
|
||||||
|
bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BTA_AG_POST_SCO_CALL_END_INCALL:
|
||||||
|
{
|
||||||
|
bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
|
||||||
|
/* Sending callsetup IND and Ring were defered to after SCO close. */
|
||||||
|
bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_RES);
|
||||||
|
|
||||||
|
if (bta_ag_inband_enabled(p_scb) && !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_RING;
|
||||||
|
bta_ag_sco_open(p_scb, p_data);
|
||||||
|
} else {
|
||||||
|
p_scb->post_sco = BTA_AG_POST_SCO_NONE;
|
||||||
|
bta_ag_send_ring(p_scb, p_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_svc_conn_open
|
||||||
|
**
|
||||||
|
** Description Service level connection opened
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_svc_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_CONN evt;
|
||||||
|
UNUSED(p_data);
|
||||||
|
|
||||||
|
if (!p_scb->svc_conn) {
|
||||||
|
/* set state variable */
|
||||||
|
p_scb->svc_conn = TRUE;
|
||||||
|
/* Clear AT+BIA mask from previous SLC if any. */
|
||||||
|
p_scb->bia_masked_out = 0;
|
||||||
|
/* stop timer */
|
||||||
|
bta_sys_stop_timer(&p_scb->act_timer);
|
||||||
|
/* call callback */
|
||||||
|
evt.hdr.handle = bta_ag_scb_to_idx(p_scb);
|
||||||
|
evt.hdr.app_id = p_scb->app_id;
|
||||||
|
evt.peer_feat = p_scb->peer_features;
|
||||||
|
bdcpy(evt.bd_addr, p_scb->peer_addr);
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
evt.peer_codec = p_scb->peer_codecs;
|
||||||
|
#endif
|
||||||
|
if ((p_scb->call_ind != BTA_AG_CALL_INACTIVE) ||
|
||||||
|
(p_scb->callsetup_ind != BTA_AG_CALLSETUP_NONE)) {
|
||||||
|
bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
}
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_CONN_EVT, (tBTA_AG *) &evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_ci_rx_data
|
||||||
|
**
|
||||||
|
** Description Send result code to RFCOMM
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_ci_rx_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UINT16 len;
|
||||||
|
tBTA_AG_CI_RX_WRITE *p_rx_write_msg = (tBTA_AG_CI_RX_WRITE *)p_data;
|
||||||
|
char *p_data_area = (char *)(p_rx_write_msg+1); /* Point to data area after header */
|
||||||
|
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_ci_rx_data:");
|
||||||
|
/* send to RFCOMM */
|
||||||
|
bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
PORT_WriteData(p_scb->conn_handle, p_data_area, strlen(p_data_area), &len);
|
||||||
|
bta_sys_idle(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rcvd_slc_ready
|
||||||
|
**
|
||||||
|
** Description Handles SLC ready call-in in case of pass-through mode.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rcvd_slc_ready(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UNUSED(p_data);
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_rcvd_slc_ready: handle = %d", bta_ag_scb_to_idx(p_scb));
|
||||||
|
|
||||||
|
if (bta_ag_cb.parse_mode == BTA_AG_PASS_THROUGH) {
|
||||||
|
/* In pass-through mode, BTA knows that SLC is ready only through call-in. */
|
||||||
|
bta_ag_svc_conn_open(p_scb, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_setcodec
|
||||||
|
**
|
||||||
|
** Description Handle API SetCodec
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
tBTA_AG_PEER_CODEC codec_type = p_data->api_setcodec.codec;
|
||||||
|
tBTA_AG_VAL val;
|
||||||
|
|
||||||
|
/* Check if the requested codec type is valid */
|
||||||
|
if((codec_type != BTA_AG_CODEC_NONE) &&
|
||||||
|
(codec_type != BTA_AG_CODEC_CVSD) &&
|
||||||
|
(codec_type != BTA_AG_CODEC_MSBC)) {
|
||||||
|
val.num = codec_type;
|
||||||
|
val.hdr.status = BTA_AG_FAIL_RESOURCES;
|
||||||
|
APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d", codec_type);
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG *) &val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((p_scb->peer_codecs & codec_type) || (codec_type == BTA_AG_CODEC_NONE) ||
|
||||||
|
(codec_type == BTA_AG_CODEC_CVSD)) {
|
||||||
|
p_scb->sco_codec = codec_type;
|
||||||
|
p_scb->codec_updated = TRUE;
|
||||||
|
val.num = codec_type;
|
||||||
|
val.hdr.status = BTA_AG_SUCCESS;
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_setcodec: Updated codec type %d", codec_type);
|
||||||
|
} else {
|
||||||
|
val.num = codec_type;
|
||||||
|
val.hdr.status = BTA_AG_FAIL_RESOURCES;
|
||||||
|
APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d", codec_type);
|
||||||
|
}
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG *) &val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
322
components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c
Normal file
322
components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This is the implementation of the API for the audio gateway (AG)
|
||||||
|
* subsystem of BTA, Broadcom's Bluetooth application layer for mobile
|
||||||
|
* phones.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "bta/bta_api.h"
|
||||||
|
#include "bta/bta_sys.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta_ag_int.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
/*****************************************************************************
|
||||||
|
** Constants
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static const tBTA_SYS_REG bta_ag_reg =
|
||||||
|
{
|
||||||
|
bta_ag_hdl_event,
|
||||||
|
BTA_AgDisable
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgEnable
|
||||||
|
**
|
||||||
|
** Description Enable the audio gateway service. When the enable
|
||||||
|
** operation is complete the callback function will be
|
||||||
|
** called with a BTA_AG_ENABLE_EVT. This function must
|
||||||
|
** be called before other function in the AG API are
|
||||||
|
** called.
|
||||||
|
**
|
||||||
|
** Returns BTA_SUCCESS if OK, BTA_FAILURE otherwise.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
tBTA_STATUS BTA_AgEnable(tBTA_AG_PARSE_MODE parse_mode, tBTA_AG_CBACK *p_cback)
|
||||||
|
{
|
||||||
|
tBTA_AG_API_ENABLE *p_buf;
|
||||||
|
UINT8 idx;
|
||||||
|
|
||||||
|
/* Error if AG is already enabled, or AG is in the middle of disabling. */
|
||||||
|
for (idx = 0; idx < BTA_AG_NUM_SCB; idx++) {
|
||||||
|
if (bta_ag_cb.scb[idx].in_use) {
|
||||||
|
APPL_TRACE_ERROR ("BTA_AgEnable: FAILED, AG already enabled.");
|
||||||
|
return BTA_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* register with BTA system manager */
|
||||||
|
bta_sys_register(BTA_ID_AG, &bta_ag_reg);
|
||||||
|
|
||||||
|
if ((p_buf = (tBTA_AG_API_ENABLE *) osi_malloc(sizeof(tBTA_AG_API_ENABLE))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_API_ENABLE_EVT;
|
||||||
|
p_buf->parse_mode = parse_mode;
|
||||||
|
p_buf->p_cback = p_cback;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
return BTA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgDisable
|
||||||
|
**
|
||||||
|
** Description Disable the audio gateway service
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgDisable(void)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = BTA_AG_API_DISABLE_EVT;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgRegister
|
||||||
|
**
|
||||||
|
** Description Register an Audio Gateway service.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgRegister(tBTA_SERVICE_MASK services, tBTA_SEC sec_mask,tBTA_AG_FEAT features,
|
||||||
|
char * p_service_names[], UINT8 app_id)
|
||||||
|
{
|
||||||
|
tBTA_AG_API_REGISTER *p_buf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ((p_buf = (tBTA_AG_API_REGISTER *) osi_malloc(sizeof(tBTA_AG_API_REGISTER))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_API_REGISTER_EVT;
|
||||||
|
p_buf->features = features;
|
||||||
|
p_buf->sec_mask = sec_mask;
|
||||||
|
p_buf->services = services;
|
||||||
|
p_buf->app_id = app_id;
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX; i++) {
|
||||||
|
if(p_service_names[i]) {
|
||||||
|
BCM_STRNCPY_S(p_buf->p_name[i], BTA_SERVICE_NAME_LEN+1, p_service_names[i], BTA_SERVICE_NAME_LEN);
|
||||||
|
p_buf->p_name[i][BTA_SERVICE_NAME_LEN] = 0;
|
||||||
|
} else {
|
||||||
|
p_buf->p_name[i][0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgDeregister
|
||||||
|
**
|
||||||
|
** Description Deregister an audio gateway service.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgDeregister(UINT16 handle)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = BTA_AG_API_DEREGISTER_EVT;
|
||||||
|
p_buf->layer_specific = handle;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgOpen
|
||||||
|
**
|
||||||
|
** Description Opens a connection to a headset or hands-free device.
|
||||||
|
** When connection is open callback function is called
|
||||||
|
** with a BTA_AG_OPEN_EVT. Only the data connection is
|
||||||
|
** opened. The audio connection is not opened.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgOpen(UINT16 handle, BD_ADDR bd_addr, tBTA_SEC sec_mask, tBTA_SERVICE_MASK services)
|
||||||
|
{
|
||||||
|
tBTA_AG_API_OPEN *p_buf;
|
||||||
|
|
||||||
|
if ((p_buf = (tBTA_AG_API_OPEN *) osi_malloc(sizeof(tBTA_AG_API_OPEN))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_API_OPEN_EVT;
|
||||||
|
p_buf->hdr.layer_specific = handle;
|
||||||
|
bdcpy(p_buf->bd_addr, bd_addr);
|
||||||
|
p_buf->services = services;
|
||||||
|
p_buf->sec_mask = sec_mask;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgClose
|
||||||
|
**
|
||||||
|
** Description Close the current connection to a headset or a handsfree
|
||||||
|
** Any current audio connection will also be closed.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgClose(UINT16 handle)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = BTA_AG_API_CLOSE_EVT;
|
||||||
|
p_buf->layer_specific = handle;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgAudioOpen
|
||||||
|
**
|
||||||
|
** Description Opens an audio connection to the currently connected
|
||||||
|
** headset or handsfree.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgAudioOpen(UINT16 handle)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = BTA_AG_API_AUDIO_OPEN_EVT;
|
||||||
|
p_buf->layer_specific = handle;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgAudioClose
|
||||||
|
**
|
||||||
|
** Description Close the currently active audio connection to a headset
|
||||||
|
** or handsfree. The data connection remains open
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgAudioClose(UINT16 handle)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = BTA_AG_API_AUDIO_CLOSE_EVT;
|
||||||
|
p_buf->layer_specific = handle;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgResult
|
||||||
|
**
|
||||||
|
** Description Send an AT result code to a headset or hands-free device.
|
||||||
|
** This function is only used when the AG parse mode is set
|
||||||
|
** to BTA_AG_PARSE.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgResult(UINT16 handle, tBTA_AG_RES result, tBTA_AG_RES_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_API_RESULT *p_buf;
|
||||||
|
|
||||||
|
// printf("BTA_AgReslut: %d\n",result);
|
||||||
|
|
||||||
|
if ((p_buf = (tBTA_AG_API_RESULT *) osi_malloc(sizeof(tBTA_AG_API_RESULT))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_API_RESULT_EVT;
|
||||||
|
p_buf->hdr.layer_specific = handle;
|
||||||
|
p_buf->result = result;
|
||||||
|
if(p_data) {
|
||||||
|
memcpy(&p_buf->data, p_data, sizeof(p_buf->data));
|
||||||
|
}
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgSetCodec
|
||||||
|
**
|
||||||
|
** Description Specify the codec type to be used for the subsequent
|
||||||
|
** audio connection.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec)
|
||||||
|
{
|
||||||
|
tBTA_AG_API_SETCODEC *p_buf;
|
||||||
|
|
||||||
|
if ((p_buf = (tBTA_AG_API_SETCODEC *) osi_malloc(sizeof(tBTA_AG_API_SETCODEC))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_API_SETCODEC_EVT;
|
||||||
|
p_buf->hdr.layer_specific = handle;
|
||||||
|
p_buf->codec = codec;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||||
|
/************************************************************************************************
|
||||||
|
* Function BTA_AgCiData
|
||||||
|
*
|
||||||
|
* Description Trigger the lower-layer to fetch and send audio data. This function is only
|
||||||
|
* only used in the case that Voice Over HCI is enabled. Precondition is that
|
||||||
|
* the HFP audio connection is connected. After this function is called, lower
|
||||||
|
* layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
|
||||||
|
*
|
||||||
|
***********************************************************************************************/
|
||||||
|
void BTA_AgCiData(void)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = BTA_AG_CI_SCO_DATA_EVT;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE)*/
|
201
components/bt/host/bluedroid/bta/hf_ag/bta_ag_at.c
Normal file
201
components/bt/host/bluedroid/bta/hf_ag/bta_ag_at.c
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* BTA AG AT command interpreter.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
#include "bta_ag_at.h"
|
||||||
|
#include "bta/utl.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_at_init
|
||||||
|
**
|
||||||
|
** Description Initialize the AT command parser control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
void bta_ag_at_init(tBTA_AG_AT_CB *p_cb)
|
||||||
|
{
|
||||||
|
p_cb->p_cmd_buf = NULL;
|
||||||
|
p_cb->cmd_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_at_reinit
|
||||||
|
**
|
||||||
|
** Description Re-initialize the AT command parser control block. This
|
||||||
|
** function resets the AT command parser state and frees
|
||||||
|
** any GKI buffer.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
void bta_ag_at_reinit(tBTA_AG_AT_CB *p_cb)
|
||||||
|
{
|
||||||
|
if (p_cb->p_cmd_buf != NULL) {
|
||||||
|
osi_free(p_cb->p_cmd_buf);
|
||||||
|
p_cb->p_cmd_buf = NULL;
|
||||||
|
}
|
||||||
|
p_cb->cmd_pos = 0;
|
||||||
|
}
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_process_at
|
||||||
|
**
|
||||||
|
** Description Parse AT commands. This function will take the input
|
||||||
|
** character string and parse it for AT commands according to
|
||||||
|
** the AT command table passed in the control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
void bta_ag_process_at(tBTA_AG_AT_CB *p_cb)
|
||||||
|
{
|
||||||
|
UINT16 idx;
|
||||||
|
UINT8 arg_type;
|
||||||
|
char *p_arg;
|
||||||
|
INT16 int_arg = 0;
|
||||||
|
/* loop through at command table looking for match */
|
||||||
|
for (idx = 0; p_cb->p_at_tbl[idx].p_cmd[0] != 0; idx++) {
|
||||||
|
if (!utl_strucmp(p_cb->p_at_tbl[idx].p_cmd, p_cb->p_cmd_buf)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is a match; verify argument type */
|
||||||
|
if (p_cb->p_at_tbl[idx].p_cmd[0] != 0) {
|
||||||
|
/* start of argument is p + strlen matching command */
|
||||||
|
p_arg = p_cb->p_cmd_buf + strlen(p_cb->p_at_tbl[idx].p_cmd);
|
||||||
|
/* if no argument */
|
||||||
|
if (p_arg[0] == 0) {
|
||||||
|
arg_type = BTA_AG_AT_NONE;
|
||||||
|
}
|
||||||
|
/* else if arg is '?' and it is last character */
|
||||||
|
else if (p_arg[0] == '?' && p_arg[1] == 0) {
|
||||||
|
arg_type = BTA_AG_AT_READ; /* we have a read */
|
||||||
|
}
|
||||||
|
/* else if arg is '=' */
|
||||||
|
else if (p_arg[0] == '=' && p_arg[1] != 0) {
|
||||||
|
if (p_arg[1] == '?' && p_arg[2] == 0) {
|
||||||
|
arg_type = BTA_AG_AT_TEST; /* we have a test */
|
||||||
|
} else {
|
||||||
|
arg_type = BTA_AG_AT_SET; /* we have a set */
|
||||||
|
p_arg++; /* skip past '=' */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* else it is freeform argument */
|
||||||
|
else {
|
||||||
|
arg_type = BTA_AG_AT_FREE;
|
||||||
|
}
|
||||||
|
/* if arguments match command capabilities */
|
||||||
|
if ((arg_type & p_cb->p_at_tbl[idx].arg_type) != 0) {
|
||||||
|
/* if it's a set integer check max, min range */
|
||||||
|
if (arg_type == BTA_AG_AT_SET && p_cb->p_at_tbl[idx].fmt == BTA_AG_AT_INT) {
|
||||||
|
int_arg = utl_str2int(p_arg);
|
||||||
|
if (int_arg < (INT16) p_cb->p_at_tbl[idx].min ||
|
||||||
|
int_arg > (INT16) p_cb->p_at_tbl[idx].max) {
|
||||||
|
/* arg out of range; error */
|
||||||
|
(*p_cb->p_err_cback)(p_cb->p_user, FALSE, NULL);
|
||||||
|
} else {
|
||||||
|
(*p_cb->p_cmd_cback)(p_cb->p_user, idx, arg_type, p_arg, int_arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*p_cb->p_cmd_cback)(p_cb->p_user, idx, arg_type, p_arg, int_arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* else error */
|
||||||
|
(*p_cb->p_err_cback)(p_cb->p_user, FALSE, NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* else no match call error callback */
|
||||||
|
(*p_cb->p_err_cback)(p_cb->p_user, TRUE, p_cb->p_cmd_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_at_parse
|
||||||
|
**
|
||||||
|
** Description Parse AT commands. This function will take the input
|
||||||
|
** character string and parse it for AT commands according to
|
||||||
|
** the AT command table passed in the control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
void bta_ag_at_parse(tBTA_AG_AT_CB *p_cb, char *p_buf, UINT16 len)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
char* p_save;
|
||||||
|
|
||||||
|
if (p_cb->p_cmd_buf == NULL) {
|
||||||
|
if ((p_cb->p_cmd_buf = (char *) osi_malloc(p_cb->cmd_max_len)) == NULL) {
|
||||||
|
APPL_TRACE_ERROR("%s: osi_malloc() failed allocation", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p_cb->cmd_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len;) {
|
||||||
|
while (p_cb->cmd_pos < p_cb->cmd_max_len-1 && i < len) {
|
||||||
|
/* Skip null characters between AT commands. */
|
||||||
|
if ((p_cb->cmd_pos == 0) && (p_buf[i] == 0)) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p_cb->p_cmd_buf[p_cb->cmd_pos] = p_buf[i++];
|
||||||
|
if ( p_cb->p_cmd_buf[p_cb->cmd_pos] == '\r' || p_cb->p_cmd_buf[p_cb->cmd_pos] == '\n') {
|
||||||
|
p_cb->p_cmd_buf[p_cb->cmd_pos] = 0;
|
||||||
|
if ((p_cb->cmd_pos > 2) &&
|
||||||
|
(p_cb->p_cmd_buf[0] == 'A' || p_cb->p_cmd_buf[0] == 'a') &&
|
||||||
|
(p_cb->p_cmd_buf[1] == 'T' || p_cb->p_cmd_buf[1] == 't')) {
|
||||||
|
p_save = p_cb->p_cmd_buf;
|
||||||
|
p_cb->p_cmd_buf += 2;
|
||||||
|
bta_ag_process_at(p_cb);
|
||||||
|
p_cb->p_cmd_buf = p_save;
|
||||||
|
}
|
||||||
|
p_cb->cmd_pos = 0;
|
||||||
|
} else if( p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1A || p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1B) {
|
||||||
|
p_cb->p_cmd_buf[++p_cb->cmd_pos] = 0;
|
||||||
|
(*p_cb->p_err_cback)(p_cb->p_user, TRUE, p_cb->p_cmd_buf);
|
||||||
|
p_cb->cmd_pos = 0;
|
||||||
|
} else {
|
||||||
|
++p_cb->cmd_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < len) {
|
||||||
|
p_cb->cmd_pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
60
components/bt/host/bluedroid/bta/hf_ag/bta_ag_cfg.c
Normal file
60
components/bt/host/bluedroid/bta/hf_ag/bta_ag_cfg.c
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This file contains compile-time configurable constants for the audio
|
||||||
|
* gateway.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
#include "bta/bta_api.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "common/bt_target.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
#ifndef BTA_AG_CIND_INFO
|
||||||
|
#define BTA_AG_CIND_INFO "(\"call\",(0,1)),(\"callsetup\",(0-3)),(\"service\",(0-3)),(\"signal\",(0-6)),(\"roam\",(0,1)),(\"battchg\",(0-5)),(\"callheld\",(0-2))"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BTA_AG_CONN_TIMEOUT
|
||||||
|
#define BTA_AG_CONN_TIMEOUT 5000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BTA_AG_SCO_PKT_TYPES
|
||||||
|
/* S1 packet type setting from HFP 1.5 spec */
|
||||||
|
#define BTA_AG_SCO_PKT_TYPES /* BTM_SCO_LINK_ALL_PKT_MASK */ (BTM_SCO_LINK_ONLY_MASK | \
|
||||||
|
BTM_SCO_PKT_TYPES_MASK_EV3 | \
|
||||||
|
BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | \
|
||||||
|
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | \
|
||||||
|
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5)
|
||||||
|
#endif /* BTA_AG_SCO_PKT_TYPES */
|
||||||
|
|
||||||
|
const tBTA_AG_CFG bta_ag_cfg =
|
||||||
|
{
|
||||||
|
BTA_AG_CIND_INFO,
|
||||||
|
BTA_AG_CONN_TIMEOUT,
|
||||||
|
BTA_AG_SCO_PKT_TYPES,
|
||||||
|
BTA_AG_CHLD_VAL_ECC,
|
||||||
|
BTA_AG_CHLD_VAL
|
||||||
|
};
|
||||||
|
tBTA_AG_CFG *p_bta_ag_cfg = (tBTA_AG_CFG *) &bta_ag_cfg;
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
1661
components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c
Normal file
1661
components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c
Normal file
File diff suppressed because it is too large
Load diff
972
components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c
Normal file
972
components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c
Normal file
|
@ -0,0 +1,972 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This is the main implementation file for the BTA audio gateway.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "bta/bta_api.h"
|
||||||
|
#include "bta/bta_sys.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta/bta_ag_co.h"
|
||||||
|
#include "bta/utl.h"
|
||||||
|
#include "common/bt_defs.h"
|
||||||
|
#include "common/bt_trace.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
#include "bta_ag_int.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
/*****************************************************************************
|
||||||
|
** Constants and types
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef BTA_AG_DEBUG
|
||||||
|
#define BTA_AG_DEBUG TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BTA_AG_DEBUG == TRUE
|
||||||
|
static char *bta_ag_evt_str(UINT16 event, tBTA_AG_RES result);
|
||||||
|
static char *bta_ag_state_str(UINT8 state);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* state machine states */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BTA_AG_INIT_ST,
|
||||||
|
BTA_AG_OPENING_ST,
|
||||||
|
BTA_AG_OPEN_ST,
|
||||||
|
BTA_AG_CLOSING_ST
|
||||||
|
};
|
||||||
|
|
||||||
|
/* state machine action enumeration list */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BTA_AG_REGISTER,
|
||||||
|
BTA_AG_DEREGISTER,
|
||||||
|
BTA_AG_START_OPEN,
|
||||||
|
BTA_AG_RFC_DO_OPEN,
|
||||||
|
BTA_AG_RFC_DO_CLOSE,
|
||||||
|
BTA_AG_START_DEREG,
|
||||||
|
BTA_AG_START_CLOSE,
|
||||||
|
BTA_AG_RFC_OPEN,
|
||||||
|
BTA_AG_OPEN_FAIL,
|
||||||
|
BTA_AG_RFC_ACP_OPEN,
|
||||||
|
BTA_AG_RFC_CLOSE,
|
||||||
|
BTA_AG_RFC_FAIL,
|
||||||
|
BTA_AG_RFC_DATA,
|
||||||
|
BTA_AG_DISC_INT_RES,
|
||||||
|
BTA_AG_DISC_FAIL,
|
||||||
|
BTA_AG_DISC_ACP_RES,
|
||||||
|
BTA_AG_FREE_DB,
|
||||||
|
BTA_AG_SCO_CONN_OPEN,
|
||||||
|
BTA_AG_SCO_CONN_CLOSE,
|
||||||
|
BTA_AG_SCO_LISTEN,
|
||||||
|
BTA_AG_SCO_OPEN,
|
||||||
|
BTA_AG_SCO_CLOSE,
|
||||||
|
BTA_AG_SCO_SHUTDOWN,
|
||||||
|
BTA_AG_POST_SCO_OPEN,
|
||||||
|
BTA_AG_POST_SCO_CLOSE,
|
||||||
|
BTA_AG_SVC_CONN_OPEN,
|
||||||
|
BTA_AG_RESULT,
|
||||||
|
BTA_AG_SETCODEC,
|
||||||
|
BTA_AG_SEND_RING,
|
||||||
|
BTA_AG_CI_SCO_DATA,
|
||||||
|
BTA_AG_CI_RX_DATA,
|
||||||
|
BTA_AG_RCVD_SLC_READY,
|
||||||
|
BTA_AG_NUM_ACTIONS
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BTA_AG_IGNORE BTA_AG_NUM_ACTIONS
|
||||||
|
|
||||||
|
/* type for action functions */
|
||||||
|
typedef void (*tBTA_AG_ACTION) (tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
|
||||||
|
/* action functions */
|
||||||
|
const tBTA_AG_ACTION bta_ag_action[] =
|
||||||
|
{
|
||||||
|
bta_ag_register,
|
||||||
|
bta_ag_deregister,
|
||||||
|
bta_ag_start_open,
|
||||||
|
bta_ag_rfc_do_open,
|
||||||
|
bta_ag_rfc_do_close,
|
||||||
|
bta_ag_start_dereg,
|
||||||
|
bta_ag_start_close,
|
||||||
|
bta_ag_rfc_open,
|
||||||
|
bta_ag_open_fail,
|
||||||
|
bta_ag_rfc_acp_open,
|
||||||
|
bta_ag_rfc_close,
|
||||||
|
bta_ag_rfc_fail,
|
||||||
|
bta_ag_rfc_data,
|
||||||
|
bta_ag_disc_int_res,
|
||||||
|
bta_ag_disc_fail,
|
||||||
|
bta_ag_disc_acp_res,
|
||||||
|
bta_ag_free_db,
|
||||||
|
bta_ag_sco_conn_open,
|
||||||
|
bta_ag_sco_conn_close,
|
||||||
|
bta_ag_sco_listen,
|
||||||
|
bta_ag_sco_open,
|
||||||
|
bta_ag_sco_close,
|
||||||
|
bta_ag_sco_shutdown,
|
||||||
|
bta_ag_post_sco_open,
|
||||||
|
bta_ag_post_sco_close,
|
||||||
|
bta_ag_svc_conn_open,
|
||||||
|
bta_ag_result,
|
||||||
|
bta_ag_setcodec,
|
||||||
|
bta_ag_send_ring,
|
||||||
|
bta_ag_ci_sco_data,
|
||||||
|
bta_ag_ci_rx_data,
|
||||||
|
bta_ag_rcvd_slc_ready
|
||||||
|
};
|
||||||
|
|
||||||
|
/* state table information */
|
||||||
|
#define BTA_AG_ACTIONS 2 /* number of actions */
|
||||||
|
#define BTA_AG_NEXT_STATE 2 /* position of next state */
|
||||||
|
#define BTA_AG_NUM_COLS 3 /* number of columns in state tables */
|
||||||
|
|
||||||
|
/* state table for init state */
|
||||||
|
const UINT8 bta_ag_st_init[][BTA_AG_NUM_COLS] =
|
||||||
|
{
|
||||||
|
/* Event Action 1 Action 2 Next state */
|
||||||
|
/* API_REGISTER_EVT */ {BTA_AG_REGISTER, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* API_DEREGISTER_EVT */ {BTA_AG_DEREGISTER, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* API_OPEN_EVT */ {BTA_AG_START_OPEN, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* API_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* API_AUDIO_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* RFC_OPEN_EVT */ {BTA_AG_RFC_ACP_OPEN, BTA_AG_SCO_LISTEN, BTA_AG_OPEN_ST},
|
||||||
|
/* RFC_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* RFC_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* DISC_ACP_RES_EVT */ {BTA_AG_FREE_DB, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* DISC_INT_RES_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* DISC_OK_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* DISC_FAIL_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* CI_RX_WRITE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* state table for opening state */
|
||||||
|
const UINT8 bta_ag_st_opening[][BTA_AG_NUM_COLS] =
|
||||||
|
{
|
||||||
|
/* Event Action 1 Action 2 Next state */
|
||||||
|
/* API_REGISTER_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* API_DEREGISTER_EVT */ {BTA_AG_RFC_DO_CLOSE, BTA_AG_START_DEREG, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_OPEN_EVT */ {BTA_AG_OPEN_FAIL, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* API_CLOSE_EVT */ {BTA_AG_RFC_DO_CLOSE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_AUDIO_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* RFC_OPEN_EVT */ {BTA_AG_RFC_OPEN, BTA_AG_SCO_LISTEN, BTA_AG_OPEN_ST},
|
||||||
|
/* RFC_CLOSE_EVT */ {BTA_AG_RFC_FAIL, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* RFC_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* DISC_ACP_RES_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* DISC_INT_RES_EVT */ {BTA_AG_DISC_INT_RES, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* DISC_OK_EVT */ {BTA_AG_RFC_DO_OPEN, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* DISC_FAIL_EVT */ {BTA_AG_DISC_FAIL, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* CI_RX_WRITE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST},
|
||||||
|
/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* state table for open state */
|
||||||
|
const UINT8 bta_ag_st_open[][BTA_AG_NUM_COLS] =
|
||||||
|
{
|
||||||
|
/* Event Action 1 Action 2 Next state */
|
||||||
|
/* API_REGISTER_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* API_DEREGISTER_EVT */ {BTA_AG_START_CLOSE, BTA_AG_START_DEREG, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_OPEN_EVT */ {BTA_AG_OPEN_FAIL, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* API_CLOSE_EVT */ {BTA_AG_START_CLOSE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_AUDIO_OPEN_EVT */ {BTA_AG_SCO_OPEN, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_SCO_CLOSE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* API_RESULT_EVT */ {BTA_AG_RESULT, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* API_SETCODEC_EVT */ {BTA_AG_SETCODEC, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* RFC_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* RFC_CLOSE_EVT */ {BTA_AG_RFC_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* RFC_DATA_EVT */ {BTA_AG_RFC_DATA, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_POST_SCO_OPEN, BTA_AG_OPEN_ST},
|
||||||
|
/* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_POST_SCO_CLOSE, BTA_AG_OPEN_ST},
|
||||||
|
/* DISC_ACP_RES_EVT */ {BTA_AG_DISC_ACP_RES, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* DISC_INT_RES_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* DISC_OK_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* DISC_FAIL_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* CI_RX_WRITE_EVT */ {BTA_AG_CI_RX_DATA, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* RING_TOUT_EVT */ {BTA_AG_SEND_RING, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* SVC_TOUT_EVT */ {BTA_AG_START_CLOSE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* CI_SCO_DATA_EVT */ {BTA_AG_CI_SCO_DATA, BTA_AG_IGNORE, BTA_AG_OPEN_ST},
|
||||||
|
/* CI_SLC_READY_EVT */ {BTA_AG_RCVD_SLC_READY, BTA_AG_IGNORE, BTA_AG_OPEN_ST}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* state table for closing state */
|
||||||
|
const UINT8 bta_ag_st_closing[][BTA_AG_NUM_COLS] =
|
||||||
|
{
|
||||||
|
/* Event Action 1 Action 2 Next state */
|
||||||
|
/* API_REGISTER_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_DEREGISTER_EVT */ {BTA_AG_START_DEREG, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_OPEN_EVT */ {BTA_AG_OPEN_FAIL, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_AUDIO_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* RFC_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* RFC_CLOSE_EVT */ {BTA_AG_RFC_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* RFC_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_POST_SCO_CLOSE, BTA_AG_CLOSING_ST},
|
||||||
|
/* DISC_ACP_RES_EVT */ {BTA_AG_FREE_DB, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* DISC_INT_RES_EVT */ {BTA_AG_FREE_DB, BTA_AG_IGNORE, BTA_AG_INIT_ST},
|
||||||
|
/* DISC_OK_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* DISC_FAIL_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* CI_RX_WRITE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST},
|
||||||
|
/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* type for state table */
|
||||||
|
typedef const UINT8 (*tBTA_AG_ST_TBL)[BTA_AG_NUM_COLS];
|
||||||
|
|
||||||
|
/* state table */
|
||||||
|
const tBTA_AG_ST_TBL bta_ag_st_tbl[] =
|
||||||
|
{
|
||||||
|
bta_ag_st_init,
|
||||||
|
bta_ag_st_opening,
|
||||||
|
bta_ag_st_open,
|
||||||
|
bta_ag_st_closing
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Global data
|
||||||
|
*****************************************************************************/
|
||||||
|
const char *bta_ag_version = "1.5"; //"1.6"
|
||||||
|
/* AG control block */
|
||||||
|
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||||
|
tBTA_AG_CB bta_ag_cb;
|
||||||
|
#else
|
||||||
|
tBTA_AG_CB *bta_ag_cb_ptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BTA_AG_DEBUG == TRUE
|
||||||
|
static char *bta_ag_evt_str(UINT16 event, tBTA_AG_RES result)
|
||||||
|
{
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case BTA_AG_API_REGISTER_EVT:
|
||||||
|
return "Register Request";
|
||||||
|
case BTA_AG_API_DEREGISTER_EVT:
|
||||||
|
return "Deregister Request";
|
||||||
|
case BTA_AG_API_OPEN_EVT:
|
||||||
|
return "Open SLC Request";
|
||||||
|
case BTA_AG_API_CLOSE_EVT:
|
||||||
|
return "Close SLC Request";
|
||||||
|
case BTA_AG_API_AUDIO_OPEN_EVT:
|
||||||
|
return "Open Audio Request";
|
||||||
|
case BTA_AG_API_AUDIO_CLOSE_EVT:
|
||||||
|
return "Close Audio Request";
|
||||||
|
case BTA_AG_API_RESULT_EVT:
|
||||||
|
switch (result) {
|
||||||
|
case BTA_AG_SPK_RES: return ("AT Result BTA_AG_SPK_RES");
|
||||||
|
case BTA_AG_MIC_RES: return ("AT Result BTA_AG_MIC_RES");
|
||||||
|
case BTA_AG_INBAND_RING_RES: return ("AT Result BTA_AG_INBAND_RING_RES");
|
||||||
|
case BTA_AG_CIND_RES: return ("AT Result BTA_AG_CIND_RES");
|
||||||
|
case BTA_AG_BINP_RES: return ("AT Result BTA_AG_BINP_RES");
|
||||||
|
case BTA_AG_IND_RES: return ("AT Result BTA_AG_IND_RES");
|
||||||
|
case BTA_AG_BVRA_RES: return ("AT Result BTA_AG_BVRA_RES");
|
||||||
|
case BTA_AG_CNUM_RES: return ("AT Result BTA_AG_CNUM_RES");
|
||||||
|
case BTA_AG_BTRH_RES: return ("AT Result BTA_AG_BTRH_RES");
|
||||||
|
case BTA_AG_CLCC_RES: return ("AT Result BTA_AG_CLCC_RES");
|
||||||
|
case BTA_AG_COPS_RES: return ("AT Result BTA_AG_COPS_RES");
|
||||||
|
case BTA_AG_IN_CALL_RES: return ("AT Result BTA_AG_IN_CALL_RES");
|
||||||
|
case BTA_AG_IN_CALL_CONN_RES: return ("AT Result BTA_AG_IN_CALL_CONN_RES");
|
||||||
|
case BTA_AG_CALL_WAIT_RES: return ("AT Result BTA_AG_CALL_WAIT_RES");
|
||||||
|
case BTA_AG_OUT_CALL_ORIG_RES: return ("AT Result BTA_AG_OUT_CALL_ORIG_RES");
|
||||||
|
case BTA_AG_OUT_CALL_ALERT_RES: return ("AT Result BTA_AG_OUT_CALL_ALERT_RES");
|
||||||
|
case BTA_AG_OUT_CALL_CONN_RES: return ("AT Result BTA_AG_OUT_CALL_CONN_RES");
|
||||||
|
case BTA_AG_CALL_CANCEL_RES: return ("AT Result BTA_AG_CALL_CANCEL_RES");
|
||||||
|
case BTA_AG_END_CALL_RES: return ("AT Result BTA_AG_END_CALL_RES");
|
||||||
|
case BTA_AG_UNAT_RES: return ("AT Result BTA_AG_UNAT_RES");
|
||||||
|
default: return ("Unknown AG Result");
|
||||||
|
}
|
||||||
|
case BTA_AG_API_SETCODEC_EVT:
|
||||||
|
return "Set Codec Request";
|
||||||
|
case BTA_AG_RFC_OPEN_EVT:
|
||||||
|
return "RFC Opened";
|
||||||
|
case BTA_AG_RFC_CLOSE_EVT:
|
||||||
|
return "RFC Closed";
|
||||||
|
case BTA_AG_RFC_SRV_CLOSE_EVT:
|
||||||
|
return "RFC SRV Closed";
|
||||||
|
case BTA_AG_RFC_DATA_EVT:
|
||||||
|
return "RFC Data";
|
||||||
|
case BTA_AG_SCO_OPEN_EVT:
|
||||||
|
return "Audio Opened";
|
||||||
|
case BTA_AG_SCO_CLOSE_EVT:
|
||||||
|
return "Audio Closed";
|
||||||
|
case BTA_AG_DISC_ACP_RES_EVT:
|
||||||
|
return "Discovery ACP Result";
|
||||||
|
case BTA_AG_DISC_INT_RES_EVT:
|
||||||
|
return "Discovery INT Result";
|
||||||
|
case BTA_AG_DISC_OK_EVT:
|
||||||
|
return "Discovery OK";
|
||||||
|
case BTA_AG_DISC_FAIL_EVT:
|
||||||
|
return "Discovery Failed";
|
||||||
|
case BTA_AG_CI_RX_WRITE_EVT:
|
||||||
|
return "CI RX Write";
|
||||||
|
case BTA_AG_RING_TOUT_EVT:
|
||||||
|
return "Ring Timeout";
|
||||||
|
case BTA_AG_SVC_TOUT_EVT:
|
||||||
|
return "Service Timeout";
|
||||||
|
case BTA_AG_API_ENABLE_EVT:
|
||||||
|
return "Enable AG";
|
||||||
|
case BTA_AG_API_DISABLE_EVT:
|
||||||
|
return "Disable AG";
|
||||||
|
case BTA_AG_CI_SCO_DATA_EVT:
|
||||||
|
return "SCO data Callin";
|
||||||
|
case BTA_AG_CI_SLC_READY_EVT:
|
||||||
|
return "SLC Ready Callin";
|
||||||
|
default:
|
||||||
|
return "Unknown AG Event";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *bta_ag_state_str(UINT8 state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case BTA_AG_INIT_ST:
|
||||||
|
return "Initial";
|
||||||
|
case BTA_AG_OPENING_ST:
|
||||||
|
return "Opening";
|
||||||
|
case BTA_AG_OPEN_ST:
|
||||||
|
return "Open";
|
||||||
|
case BTA_AG_CLOSING_ST:
|
||||||
|
return "Closing";
|
||||||
|
default:
|
||||||
|
return "Unknown AG State";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_timer_cback
|
||||||
|
**
|
||||||
|
** Description AG timer callback.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_timer_cback(void *p)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *) p;
|
||||||
|
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = p_tle->event;
|
||||||
|
p_buf->layer_specific = bta_ag_scb_to_idx((tBTA_AG_SCB *) p_tle->param);
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_scb_alloc
|
||||||
|
**
|
||||||
|
** Description Allocate an AG service control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns pointer to the scb, or NULL if none could be allocated.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static tBTA_AG_SCB *bta_ag_scb_alloc(void)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb = &bta_ag_cb.scb[0];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
|
||||||
|
if (!p_scb->in_use) {
|
||||||
|
/* initialize variables */
|
||||||
|
p_scb->in_use = TRUE;
|
||||||
|
p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
p_scb->codec_updated = FALSE;
|
||||||
|
#endif
|
||||||
|
/* set up timers */
|
||||||
|
p_scb->act_timer.param = (UINT32) p_scb;
|
||||||
|
p_scb->act_timer.p_cback = bta_ag_timer_cback;
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE)
|
||||||
|
/* set eSCO mSBC setting to T2 as the preferred */
|
||||||
|
p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
|
||||||
|
#endif
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == BTA_AG_NUM_SCB) {
|
||||||
|
p_scb = NULL; /* out of scbs */
|
||||||
|
APPL_TRACE_WARNING("Out of ag scbs");
|
||||||
|
}
|
||||||
|
return p_scb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_scb_dealloc
|
||||||
|
**
|
||||||
|
** Description Deallocate a service control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_scb_dealloc(tBTA_AG_SCB *p_scb)
|
||||||
|
{
|
||||||
|
UINT8 idx;
|
||||||
|
BOOLEAN allocated = FALSE;
|
||||||
|
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb));
|
||||||
|
/* stop timers */
|
||||||
|
bta_sys_stop_timer(&p_scb->act_timer);
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE)
|
||||||
|
bta_sys_stop_timer(&p_scb->cn_timer);
|
||||||
|
#endif
|
||||||
|
bta_sys_stop_timer(&p_scb->colli_timer);
|
||||||
|
|
||||||
|
/* initialize control block */
|
||||||
|
memset(p_scb, 0, sizeof(tBTA_AG_SCB));
|
||||||
|
p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
|
||||||
|
/* If all scbs are deallocated, callback with disable event */
|
||||||
|
if (!bta_sys_is_register (BTA_ID_AG)) {
|
||||||
|
for (idx = 0; idx < BTA_AG_NUM_SCB; idx++) {
|
||||||
|
if (bta_ag_cb.scb[idx].in_use) {
|
||||||
|
allocated = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!allocated) {
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_scb_to_idx
|
||||||
|
**
|
||||||
|
** Description Given a pointer to an scb, return its index.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns Index of scb.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
UINT16 bta_ag_scb_to_idx(tBTA_AG_SCB *p_scb)
|
||||||
|
{
|
||||||
|
/* use array arithmetic to determine index */
|
||||||
|
return ((UINT16) (p_scb - bta_ag_cb.scb)) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_scb_by_idx
|
||||||
|
**
|
||||||
|
** Description Given an scb index return pointer to scb.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns Pointer to scb or NULL if not allocated.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
tBTA_AG_SCB *bta_ag_scb_by_idx(UINT16 idx)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
/* verify index */
|
||||||
|
if (idx > 0 && idx <= BTA_AG_NUM_SCB) {
|
||||||
|
p_scb = &bta_ag_cb.scb[idx - 1];
|
||||||
|
if (!p_scb->in_use) {
|
||||||
|
p_scb = NULL;
|
||||||
|
APPL_TRACE_WARNING("ag scb idx %d not allocated", idx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p_scb = NULL;
|
||||||
|
APPL_TRACE_DEBUG("ag scb idx %d out of range", idx);
|
||||||
|
}
|
||||||
|
return p_scb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_service_to_idx
|
||||||
|
**
|
||||||
|
** Description Given a BTA service mask convert to profile index.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns Profile ndex of scb.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
UINT8 bta_ag_service_to_idx(tBTA_SERVICE_MASK services)
|
||||||
|
{
|
||||||
|
if (services & BTA_HFP_SERVICE_MASK) {
|
||||||
|
return BTA_AG_HFP;
|
||||||
|
} else {
|
||||||
|
return BTA_AG_HSP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_idx_by_bdaddr
|
||||||
|
**
|
||||||
|
** Description Find SCB associated with peer BD address.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns Index of SCB or zero if none found.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
UINT16 bta_ag_idx_by_bdaddr(BD_ADDR peer_addr)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb = &bta_ag_cb.scb[0];
|
||||||
|
UINT16 i;
|
||||||
|
|
||||||
|
if (peer_addr != NULL) {
|
||||||
|
for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
|
||||||
|
if (p_scb->in_use && !bdcmp(peer_addr, p_scb->peer_addr)) {
|
||||||
|
return (i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* no scb found */
|
||||||
|
APPL_TRACE_WARNING("No ag scb for peer addr");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_other_scb_open
|
||||||
|
**
|
||||||
|
** Description Check whether any other scb is in open state.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns TRUE if another scb is in open state, FALSE otherwise.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
BOOLEAN bta_ag_other_scb_open(tBTA_AG_SCB *p_curr_scb)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb = &bta_ag_cb.scb[0];
|
||||||
|
|
||||||
|
for (int i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
|
||||||
|
if (p_scb->in_use && p_scb != p_curr_scb && p_scb->state == BTA_AG_OPEN_ST) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* no other scb found */
|
||||||
|
APPL_TRACE_DEBUG("No other ag scb open");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_scb_open
|
||||||
|
**
|
||||||
|
** Description Check whether given scb is in open state.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns TRUE if scb is in open state, FALSE otherwise.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
BOOLEAN bta_ag_scb_open(tBTA_AG_SCB *p_curr_scb)
|
||||||
|
{
|
||||||
|
if (p_curr_scb && p_curr_scb->in_use && p_curr_scb->state == BTA_AG_OPEN_ST) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_get_other_idle_scb
|
||||||
|
**
|
||||||
|
** Description Return other scb if it is in INIT st.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns Pointer to other scb if INIT st, NULL otherwise.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
tBTA_AG_SCB *bta_ag_get_other_idle_scb (tBTA_AG_SCB *p_curr_scb)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb = &bta_ag_cb.scb[0];
|
||||||
|
UINT8 xx;
|
||||||
|
|
||||||
|
for (xx = 0; xx < BTA_AG_NUM_SCB; xx++, p_scb++) {
|
||||||
|
if (p_scb->in_use && (p_scb != p_curr_scb) && (p_scb->state == BTA_AG_INIT_ST)) {
|
||||||
|
return p_scb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* no other scb found */
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_get_other_idle_scb: No idle AG scb");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_colli_timer_cback
|
||||||
|
**
|
||||||
|
** Description AG connection collision timer callback
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_colli_timer_cback (TIMER_LIST_ENT *p_tle)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
|
||||||
|
APPL_TRACE_DEBUG ("bta_ag_colli_timer_cback");
|
||||||
|
if (p_tle) {
|
||||||
|
p_scb = (tBTA_AG_SCB *)p_tle->param;
|
||||||
|
if (p_scb) {
|
||||||
|
p_scb->colli_tmr_on = FALSE;
|
||||||
|
/* If the peer haven't opened AG connection */
|
||||||
|
/* we will restart opening process. */
|
||||||
|
bta_ag_resume_open (p_scb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_collision_cback
|
||||||
|
**
|
||||||
|
** Description Get notified about collision.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||||
|
{
|
||||||
|
UINT16 handle;
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
UNUSED(status);
|
||||||
|
UNUSED(app_id);
|
||||||
|
|
||||||
|
/* Check if we have opening scb for the peer device. */
|
||||||
|
handle = bta_ag_idx_by_bdaddr (peer_addr);
|
||||||
|
p_scb = bta_ag_scb_by_idx (handle);
|
||||||
|
|
||||||
|
if (p_scb && (p_scb->state == BTA_AG_OPENING_ST)) {
|
||||||
|
if (id == BTA_ID_SYS) {
|
||||||
|
/* ACL collision */
|
||||||
|
APPL_TRACE_WARNING ("AG found collision (ACL) ...");
|
||||||
|
} else if (id == BTA_ID_AG) {
|
||||||
|
/* RFCOMM collision */
|
||||||
|
APPL_TRACE_WARNING ("AG found collision (RFCOMM) ...");
|
||||||
|
} else {
|
||||||
|
APPL_TRACE_WARNING ("AG found collision (\?\?\?) ...");
|
||||||
|
}
|
||||||
|
p_scb->state = BTA_AG_INIT_ST;
|
||||||
|
/* Cancel SDP if it had been started. */
|
||||||
|
if(p_scb->p_disc_db) {
|
||||||
|
(void)SDP_CancelServiceSearch (p_scb->p_disc_db);
|
||||||
|
bta_ag_free_db(p_scb, NULL);
|
||||||
|
}
|
||||||
|
/* reopen registered servers */
|
||||||
|
/* Collision may be detected before or after we close servers. */
|
||||||
|
if (bta_ag_is_server_closed (p_scb)) {
|
||||||
|
bta_ag_start_servers(p_scb, p_scb->reg_services);
|
||||||
|
}
|
||||||
|
/* Start timer to han */
|
||||||
|
p_scb->colli_timer.p_cback = (TIMER_CBACK*)&bta_ag_colli_timer_cback;
|
||||||
|
p_scb->colli_timer.param = (INT32)p_scb;
|
||||||
|
bta_sys_start_timer(&p_scb->colli_timer, 0, BTA_AG_COLLISION_TIMER);
|
||||||
|
p_scb->colli_tmr_on = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_resume_open
|
||||||
|
**
|
||||||
|
** Description Resume opening process.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_resume_open (tBTA_AG_SCB *p_scb)
|
||||||
|
{
|
||||||
|
if (p_scb) {
|
||||||
|
APPL_TRACE_DEBUG ("bta_ag_resume_open, Handle(%d)", bta_ag_scb_to_idx(p_scb));
|
||||||
|
/* resume opening process. */
|
||||||
|
if (p_scb->state == BTA_AG_INIT_ST) {
|
||||||
|
p_scb->state = BTA_AG_OPENING_ST;
|
||||||
|
bta_ag_start_open (p_scb, NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
APPL_TRACE_ERROR ("bta_ag_resume_open, Null p_scb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_api_enable
|
||||||
|
**
|
||||||
|
** Description Handle an API enable event.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_api_enable(tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* initialize control block */
|
||||||
|
memset(&bta_ag_cb, 0, sizeof(tBTA_AG_CB));
|
||||||
|
/* store callback function */
|
||||||
|
bta_ag_cb.p_cback = p_data->api_enable.p_cback;
|
||||||
|
bta_ag_cb.parse_mode = p_data->api_enable.parse_mode;
|
||||||
|
/* check if mSBC support enabled */
|
||||||
|
if (strcmp(bta_ag_version, "1.6") == 0) {
|
||||||
|
bta_ag_cb.msbc_enabled = TRUE;
|
||||||
|
bta_ag_cb.scb->negotiated_codec = BTM_SCO_CODEC_MSBC;
|
||||||
|
} else{
|
||||||
|
bta_ag_cb.msbc_enabled = FALSE;
|
||||||
|
bta_ag_cb.scb->negotiated_codec = BTM_SCO_CODEC_CVSD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set deault setting for eSCO/SCO */
|
||||||
|
BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
|
||||||
|
bta_sys_collision_register (BTA_ID_AG, bta_ag_collision_cback);
|
||||||
|
/* call callback with enable event */
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_ENABLE_EVT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_api_disable
|
||||||
|
**
|
||||||
|
** Description Handle an API disable event.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_api_disable(tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
/* deregister all scbs in use */
|
||||||
|
tBTA_AG_SCB *p_scb = &bta_ag_cb.scb[0];
|
||||||
|
BOOLEAN do_dereg = FALSE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!bta_sys_is_register (BTA_ID_AG)) {
|
||||||
|
APPL_TRACE_ERROR("BTA AG is already disabled, ignoring ...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* De-register with BTA system manager */
|
||||||
|
bta_sys_deregister(BTA_ID_AG);
|
||||||
|
|
||||||
|
for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
|
||||||
|
if (p_scb->in_use) {
|
||||||
|
bta_ag_sm_execute(p_scb, BTA_AG_API_DEREGISTER_EVT, p_data);
|
||||||
|
do_dereg = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!do_dereg) {
|
||||||
|
/* Done, send callback evt to app */
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL);
|
||||||
|
}
|
||||||
|
bta_sys_collision_register (BTA_ID_AG, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_api_register
|
||||||
|
**
|
||||||
|
** Description Handle an API event registers a new service.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_api_register(tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
tBTA_AG_REGISTER reg;
|
||||||
|
|
||||||
|
/* allocate an scb */
|
||||||
|
if ((p_scb = bta_ag_scb_alloc()) != NULL) {
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_api_register: p_scb 0x%08x ", (unsigned int)p_scb);
|
||||||
|
bta_ag_sm_execute(p_scb, p_data->hdr.event, p_data);
|
||||||
|
} else {
|
||||||
|
reg.status = BTA_AG_FAIL_RESOURCES;
|
||||||
|
(*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG *) ®);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_api_result
|
||||||
|
**
|
||||||
|
** Description Handle an API result event.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_api_result(tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (p_data->hdr.layer_specific != BTA_AG_HANDLE_ALL) {
|
||||||
|
if ((p_scb = bta_ag_scb_by_idx(p_data->hdr.layer_specific)) != NULL) {
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_api_result: p_scb 0x%08x ", (unsigned int)p_scb);
|
||||||
|
bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, p_scb++) {
|
||||||
|
if (p_scb->in_use && p_scb->svc_conn) {
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_api_result p_scb 0x%08x ", (unsigned int)p_scb);
|
||||||
|
bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sm_execute
|
||||||
|
**
|
||||||
|
** Description State machine event handling function for AG
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sm_execute(tBTA_AG_SCB *p_scb, UINT16 event, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_ST_TBL state_table;
|
||||||
|
UINT8 action;
|
||||||
|
|
||||||
|
#if BTA_AG_DEBUG == TRUE
|
||||||
|
UINT16 in_event = event;
|
||||||
|
UINT8 in_state = p_scb->state;
|
||||||
|
/* Ignore displaying of AT results when not connected (Ignored in state machine) */
|
||||||
|
if (in_event != BTA_AG_API_RESULT_EVT || p_scb->state == BTA_AG_OPEN_ST) {
|
||||||
|
APPL_TRACE_EVENT("AG evt (hdl 0x%04x): State %d (%s), Event 0x%04x (%s)",
|
||||||
|
bta_ag_scb_to_idx(p_scb),
|
||||||
|
p_scb->state, bta_ag_state_str(p_scb->state),
|
||||||
|
event, bta_ag_evt_str(event, p_data->api_result.result));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
APPL_TRACE_EVENT("AG evt (hdl 0x%04x): State %d, Event 0x%04x",
|
||||||
|
bta_ag_scb_to_idx(p_scb), p_scb->state, event);
|
||||||
|
#endif
|
||||||
|
event &= 0x00FF;
|
||||||
|
if (event >= (BTA_AG_MAX_EVT & 0x00FF)) {
|
||||||
|
APPL_TRACE_ERROR("AG evt out of range, ignoring...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* look up the state table for the current state */
|
||||||
|
state_table = bta_ag_st_tbl[p_scb->state];
|
||||||
|
/* set next state */
|
||||||
|
p_scb->state = state_table[event][BTA_AG_NEXT_STATE];
|
||||||
|
/* execute action functions */
|
||||||
|
for (int i = 0; i < BTA_AG_ACTIONS; i++) {
|
||||||
|
if ((action = state_table[event][i]) != BTA_AG_IGNORE) {
|
||||||
|
(*bta_ag_action[action])(p_scb, p_data);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if BTA_AG_DEBUG == TRUE
|
||||||
|
if (p_scb->state != in_state) {
|
||||||
|
APPL_TRACE_EVENT("BTA AG State Change: [%s] -> [%s] after Event [%s]",
|
||||||
|
bta_ag_state_str(in_state),
|
||||||
|
bta_ag_state_str(p_scb->state),
|
||||||
|
bta_ag_evt_str(in_event, p_data->api_result.result));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_hdl_event
|
||||||
|
**
|
||||||
|
** Description Data gateway main event handling function.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns BOOLEAN
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
BOOLEAN bta_ag_hdl_event(BT_HDR *p_msg)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_hdl_event: Event 0x%04x ", p_msg->event);
|
||||||
|
|
||||||
|
switch (p_msg->event) {
|
||||||
|
/* handle enable event */
|
||||||
|
case BTA_AG_API_ENABLE_EVT:
|
||||||
|
bta_ag_api_enable((tBTA_AG_DATA *) p_msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* handle disable event */
|
||||||
|
case BTA_AG_API_DISABLE_EVT:
|
||||||
|
bta_ag_api_disable((tBTA_AG_DATA *) p_msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* handle register event */
|
||||||
|
case BTA_AG_API_REGISTER_EVT:
|
||||||
|
bta_ag_api_register((tBTA_AG_DATA *) p_msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* handle result event */
|
||||||
|
case BTA_AG_API_RESULT_EVT:
|
||||||
|
bta_ag_api_result((tBTA_AG_DATA *) p_msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* all others reference scb by handle */
|
||||||
|
default:
|
||||||
|
if ((p_scb = bta_ag_scb_by_idx(p_msg->layer_specific)) != NULL) {
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_hdl_event: p_scb 0x%08x ", (unsigned int)p_scb);
|
||||||
|
bta_ag_sm_execute(p_scb, p_msg->event, (tBTA_AG_DATA *) p_msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
403
components/bt/host/bluedroid/bta/hf_ag/bta_ag_rfc.c
Normal file
403
components/bt/host/bluedroid/bta/hf_ag/bta_ag_rfc.c
Normal file
|
@ -0,0 +1,403 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This file contains the audio gateway functions controlling the RFCOMM
|
||||||
|
* connections.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "bta_ag_int.h"
|
||||||
|
#include "bta/bta_api.h"
|
||||||
|
#include "bta/bta_sys.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta/bta_ag_co.h"
|
||||||
|
#include "bta/utl.h"
|
||||||
|
#include "stack/btm_api.h"
|
||||||
|
#include "stack/port_api.h"
|
||||||
|
#include "stack/rfcdefs.h"
|
||||||
|
#include "common/bt_trace.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
/* Event mask for RfCOMM port callback */
|
||||||
|
#define BTA_AG_PORT_EV_MASK PORT_EV_RXCHAR
|
||||||
|
|
||||||
|
/* each scb has its own rfcomm callbacks */
|
||||||
|
void bta_ag_port_cback_1(UINT32 code, UINT16 port_handle);
|
||||||
|
void bta_ag_port_cback_2(UINT32 code, UINT16 port_handle);
|
||||||
|
void bta_ag_port_cback_3(UINT32 code, UINT16 port_handle);
|
||||||
|
|
||||||
|
void bta_ag_mgmt_cback_1(UINT32 code, UINT16 port_handle);
|
||||||
|
void bta_ag_mgmt_cback_2(UINT32 code, UINT16 port_handle);
|
||||||
|
void bta_ag_mgmt_cback_3(UINT32 code, UINT16 port_handle);
|
||||||
|
|
||||||
|
int bta_ag_data_cback_1(UINT16 port_handle, void *p_data, UINT16 len);
|
||||||
|
int bta_ag_data_cback_2(UINT16 port_handle, void *p_data, UINT16 len);
|
||||||
|
int bta_ag_data_cback_3(UINT16 port_handle, void *p_data, UINT16 len);
|
||||||
|
|
||||||
|
/* rfcomm callback function tables */
|
||||||
|
typedef tPORT_CALLBACK *tBTA_AG_PORT_CBACK;
|
||||||
|
const tBTA_AG_PORT_CBACK bta_ag_port_cback_tbl[] =
|
||||||
|
{
|
||||||
|
bta_ag_port_cback_1,
|
||||||
|
bta_ag_port_cback_2,
|
||||||
|
bta_ag_port_cback_3
|
||||||
|
};
|
||||||
|
|
||||||
|
const tBTA_AG_PORT_CBACK bta_ag_mgmt_cback_tbl[] =
|
||||||
|
{
|
||||||
|
bta_ag_mgmt_cback_1,
|
||||||
|
bta_ag_mgmt_cback_2,
|
||||||
|
bta_ag_mgmt_cback_3
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef tPORT_DATA_CALLBACK *tBTA_AG_DATA_CBACK;
|
||||||
|
const tBTA_AG_DATA_CBACK bta_ag_data_cback_tbl[] =
|
||||||
|
{
|
||||||
|
bta_ag_data_cback_1,
|
||||||
|
bta_ag_data_cback_2,
|
||||||
|
bta_ag_data_cback_3
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_port_cback
|
||||||
|
**
|
||||||
|
** Description RFCOMM Port callback
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_port_cback(UINT32 code, UINT16 port_handle, UINT16 handle)
|
||||||
|
{
|
||||||
|
BT_HDR *p_buf;
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
UNUSED(code);
|
||||||
|
|
||||||
|
if ((p_scb = bta_ag_scb_by_idx(handle)) != NULL) {
|
||||||
|
/* ignore port events for port handles other than connected handle */
|
||||||
|
if (port_handle != p_scb->conn_handle) {
|
||||||
|
APPL_TRACE_DEBUG("ag_port_cback ignoring handle:%d conn_handle = %d other handle = %d",
|
||||||
|
port_handle, p_scb->conn_handle, handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
|
p_buf->event = BTA_AG_RFC_DATA_EVT;
|
||||||
|
p_buf->layer_specific = handle;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_mgmt_cback
|
||||||
|
**
|
||||||
|
** Description RFCOMM management callback
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_mgmt_cback(UINT32 code, UINT16 port_handle, UINT16 handle)
|
||||||
|
{
|
||||||
|
tBTA_AG_RFC *p_buf;
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
UINT16 event;
|
||||||
|
UINT8 i;
|
||||||
|
BOOLEAN found_handle = FALSE;
|
||||||
|
|
||||||
|
APPL_TRACE_DEBUG("ag_mgmt_cback : code = %d, port_handle = %d, handle = %d",
|
||||||
|
code, port_handle, handle);
|
||||||
|
|
||||||
|
if ((p_scb = bta_ag_scb_by_idx(handle)) != NULL) {
|
||||||
|
/* ignore close event for port handles other than connected handle */
|
||||||
|
if ((code != PORT_SUCCESS) && (port_handle != p_scb->conn_handle)) {
|
||||||
|
APPL_TRACE_DEBUG("ag_mgmt_cback ignoring handle:%d", port_handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == PORT_SUCCESS) {
|
||||||
|
if (p_scb->conn_handle) {
|
||||||
|
/* Outgoing connection */
|
||||||
|
if (port_handle == p_scb->conn_handle)
|
||||||
|
found_handle = TRUE;
|
||||||
|
} else {
|
||||||
|
/* Incoming connection */
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX; i++) {
|
||||||
|
if (port_handle == p_scb->serv_handle[i])
|
||||||
|
found_handle = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_handle) {
|
||||||
|
APPL_TRACE_ERROR ("bta_ag_mgmt_cback: PORT_SUCCESS, ignoring handle = %d", port_handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event = BTA_AG_RFC_OPEN_EVT;
|
||||||
|
} else if (port_handle == p_scb->conn_handle) {
|
||||||
|
/* distinguish server close events */
|
||||||
|
event = BTA_AG_RFC_CLOSE_EVT;
|
||||||
|
} else {
|
||||||
|
event = BTA_AG_RFC_SRV_CLOSE_EVT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p_buf = (tBTA_AG_RFC *) osi_malloc(sizeof(tBTA_AG_RFC))) != NULL) {
|
||||||
|
p_buf->hdr.event = event;
|
||||||
|
p_buf->hdr.layer_specific = handle;
|
||||||
|
p_buf->port_handle = port_handle;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_data_cback
|
||||||
|
**
|
||||||
|
** Description RFCOMM data callback
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static int bta_ag_data_cback(UINT16 port_handle, void *p_data, UINT16 len, UINT16 handle)
|
||||||
|
{
|
||||||
|
UNUSED(port_handle);
|
||||||
|
|
||||||
|
/* call data call-out directly */
|
||||||
|
bta_ag_co_tx_write(handle, (UINT8 *) p_data, len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_port_cback_1 to 3
|
||||||
|
** bta_ag_mgmt_cback_1 to 3
|
||||||
|
**
|
||||||
|
** Description RFCOMM callback functions. This is an easy way to
|
||||||
|
** distinguish scb from the callback.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_mgmt_cback_1(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 1);}
|
||||||
|
void bta_ag_mgmt_cback_2(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 2);}
|
||||||
|
void bta_ag_mgmt_cback_3(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 3);}
|
||||||
|
void bta_ag_port_cback_1(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 1);}
|
||||||
|
void bta_ag_port_cback_2(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 2);}
|
||||||
|
void bta_ag_port_cback_3(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 3);}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_data_cback_1 to 3
|
||||||
|
**
|
||||||
|
** Description RFCOMM data callback functions. This is an easy way to
|
||||||
|
** distinguish scb from the callback.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
int bta_ag_data_cback_1(UINT16 port_handle, void *p_data, UINT16 len)
|
||||||
|
{
|
||||||
|
return bta_ag_data_cback(port_handle, p_data, len, 1);
|
||||||
|
}
|
||||||
|
int bta_ag_data_cback_2(UINT16 port_handle, void *p_data, UINT16 len)
|
||||||
|
{
|
||||||
|
return bta_ag_data_cback(port_handle, p_data, len, 2);
|
||||||
|
}
|
||||||
|
int bta_ag_data_cback_3(UINT16 port_handle, void *p_data, UINT16 len)
|
||||||
|
{
|
||||||
|
return bta_ag_data_cback(port_handle, p_data, len, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_setup_port
|
||||||
|
**
|
||||||
|
** Description Setup RFCOMM port for use by AG.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_setup_port(tBTA_AG_SCB *p_scb, UINT16 handle)
|
||||||
|
{
|
||||||
|
UINT16 i = bta_ag_scb_to_idx(p_scb) - 1;
|
||||||
|
|
||||||
|
/* set up data callback if using pass through mode */
|
||||||
|
if (bta_ag_cb.parse_mode == BTA_AG_PASS_THROUGH) {
|
||||||
|
PORT_SetDataCallback(handle, bta_ag_data_cback_tbl[i]);
|
||||||
|
}
|
||||||
|
PORT_SetEventMask(handle, BTA_AG_PORT_EV_MASK);
|
||||||
|
PORT_SetEventCallback(handle, bta_ag_port_cback_tbl[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_start_servers
|
||||||
|
**
|
||||||
|
** Description Setup RFCOMM servers for use by AG.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_start_servers(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK services)
|
||||||
|
{
|
||||||
|
int bta_ag_port_status;
|
||||||
|
|
||||||
|
services >>= BTA_HSP_SERVICE_ID;
|
||||||
|
for (int i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
|
||||||
|
/* if service is set in mask */
|
||||||
|
if (services & 1) {
|
||||||
|
BTM_SetSecurityLevel(FALSE, "", bta_ag_sec_id[i], p_scb->serv_sec_mask,
|
||||||
|
BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, bta_ag_cb.profile[i].scn);
|
||||||
|
|
||||||
|
bta_ag_port_status = RFCOMM_CreateConnection(bta_ag_uuid[i], bta_ag_cb.profile[i].scn,
|
||||||
|
TRUE, BTA_AG_MTU, (UINT8 *) bd_addr_any, &(p_scb->serv_handle[i]),
|
||||||
|
bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]);
|
||||||
|
|
||||||
|
if( bta_ag_port_status == PORT_SUCCESS ) {
|
||||||
|
bta_ag_setup_port(p_scb, p_scb->serv_handle[i]);
|
||||||
|
} else {
|
||||||
|
/* TODO: CR#137125 to handle to error properly */
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_start_servers: RFCOMM_CreateConnection returned error:%d", bta_ag_port_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_close_servers
|
||||||
|
**
|
||||||
|
** Description Close RFCOMM servers port for use by AG.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_close_servers(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK services)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
services >>= BTA_HSP_SERVICE_ID;
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
|
||||||
|
/* if service is set in mask */
|
||||||
|
if (services & 1) {
|
||||||
|
RFCOMM_RemoveServer(p_scb->serv_handle[i]);
|
||||||
|
p_scb->serv_handle[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_is_server_closed
|
||||||
|
**
|
||||||
|
** Description Returns TRUE if all servers are closed.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns TRUE if all servers are closed, FALSE otherwise
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
BOOLEAN bta_ag_is_server_closed (tBTA_AG_SCB *p_scb)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
BOOLEAN is_closed = TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX; i++) {
|
||||||
|
if (p_scb->serv_handle[i] != 0)
|
||||||
|
is_closed = FALSE;
|
||||||
|
}
|
||||||
|
return is_closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rfc_do_open
|
||||||
|
**
|
||||||
|
** Description Open an RFCOMM connection to the peer device.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rfc_do_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
BTM_SetSecurityLevel(TRUE, "", bta_ag_sec_id[p_scb->conn_service],
|
||||||
|
p_scb->cli_sec_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, p_scb->peer_scn);
|
||||||
|
|
||||||
|
if (RFCOMM_CreateConnection(bta_ag_uuid[p_scb->conn_service], p_scb->peer_scn,
|
||||||
|
FALSE, BTA_AG_MTU, p_scb->peer_addr, &(p_scb->conn_handle),
|
||||||
|
bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]) == PORT_SUCCESS) {
|
||||||
|
bta_ag_setup_port(p_scb, p_scb->conn_handle);
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_rfc_do_open : conn_handle = %d", p_scb->conn_handle);
|
||||||
|
} else {
|
||||||
|
/* RFCOMM create connection failed; send ourselves RFCOMM close event */
|
||||||
|
bta_ag_sm_execute(p_scb, BTA_AG_RFC_CLOSE_EVT, p_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_rfc_do_close
|
||||||
|
**
|
||||||
|
** Description Close RFCOMM connection.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_rfc_do_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_RFC *p_buf;
|
||||||
|
UNUSED(p_data);
|
||||||
|
|
||||||
|
if (p_scb->conn_handle) {
|
||||||
|
RFCOMM_RemoveConnection(p_scb->conn_handle);
|
||||||
|
} else {
|
||||||
|
/* Close API was called while AG is in Opening state. */
|
||||||
|
/* Need to trigger the state machine to send callback to the app */
|
||||||
|
/* and move back to INIT state. */
|
||||||
|
if ((p_buf = (tBTA_AG_RFC *) osi_malloc(sizeof(tBTA_AG_RFC))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_RFC_CLOSE_EVT;
|
||||||
|
p_buf->hdr.layer_specific = bta_ag_scb_to_idx(p_scb);
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
/* Cancel SDP if it had been started. */
|
||||||
|
/*
|
||||||
|
if(p_scb->p_disc_db)
|
||||||
|
{
|
||||||
|
(void)SDP_CancelServiceSearch (p_scb->p_disc_db);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
1767
components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c
Normal file
1767
components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c
Normal file
File diff suppressed because it is too large
Load diff
446
components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c
Normal file
446
components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This file contains the audio gateway functions performing SDP
|
||||||
|
* operations.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "bta_ag_int.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta/bta_sys.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta/utl.h"
|
||||||
|
#include "stack/sdp_api.h"
|
||||||
|
#include "stack/btm_api.h"
|
||||||
|
#include "common/bt_trace.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
/* Number of protocol elements in protocol element list. */
|
||||||
|
#define BTA_AG_NUM_PROTO_ELEMS 2
|
||||||
|
|
||||||
|
/* Number of elements in service class id list. */
|
||||||
|
#define BTA_AG_NUM_SVC_ELEMS 2
|
||||||
|
|
||||||
|
/* size of database for service discovery */
|
||||||
|
#ifndef BTA_AG_DISC_BUF_SIZE
|
||||||
|
#define BTA_AG_DISC_BUF_SIZE (4096+16)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* declare sdp callback functions */
|
||||||
|
void bta_ag_sdp_cback_1(UINT16 status);
|
||||||
|
void bta_ag_sdp_cback_2(UINT16 status);
|
||||||
|
void bta_ag_sdp_cback_3(UINT16 status);
|
||||||
|
|
||||||
|
/* SDP callback function table */
|
||||||
|
typedef tSDP_DISC_CMPL_CB *tBTA_AG_SDP_CBACK;
|
||||||
|
const tBTA_AG_SDP_CBACK bta_ag_sdp_cback_tbl[] =
|
||||||
|
{
|
||||||
|
bta_ag_sdp_cback_1,
|
||||||
|
bta_ag_sdp_cback_2,
|
||||||
|
bta_ag_sdp_cback_3
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sdp_cback
|
||||||
|
**
|
||||||
|
** Description SDP callback function.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_sdp_cback(UINT16 status, UINT8 idx)
|
||||||
|
{
|
||||||
|
tBTA_AG_DISC_RESULT *p_buf;
|
||||||
|
UINT16 event;
|
||||||
|
tBTA_AG_SCB *p_scb;
|
||||||
|
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_sdp_cback status:0x%x", status);
|
||||||
|
|
||||||
|
if ((p_scb = bta_ag_scb_by_idx(idx)) != NULL) {
|
||||||
|
/* set event according to int/acp */
|
||||||
|
if (p_scb->role == BTA_AG_ACP) {
|
||||||
|
event = BTA_AG_DISC_ACP_RES_EVT;
|
||||||
|
} else {
|
||||||
|
event = BTA_AG_DISC_INT_RES_EVT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p_buf = (tBTA_AG_DISC_RESULT *) osi_malloc(sizeof(tBTA_AG_DISC_RESULT))) != NULL) {
|
||||||
|
p_buf->hdr.event = event;
|
||||||
|
p_buf->hdr.layer_specific = idx;
|
||||||
|
p_buf->status = status;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sdp_cback_1 to 3
|
||||||
|
**
|
||||||
|
** Description SDP callback functions. Since there is no way to
|
||||||
|
** distinguish scb from the callback we need separate
|
||||||
|
** callbacks for each scb.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sdp_cback_1(UINT16 status) {bta_ag_sdp_cback(status, 1);}
|
||||||
|
void bta_ag_sdp_cback_2(UINT16 status) {bta_ag_sdp_cback(status, 2);}
|
||||||
|
void bta_ag_sdp_cback_3(UINT16 status) {bta_ag_sdp_cback(status, 3);}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_add_record
|
||||||
|
**
|
||||||
|
** Description This function is called by a server application to add
|
||||||
|
** HSP or HFP information to an SDP record. Prior to
|
||||||
|
** calling this function the application must call
|
||||||
|
** SDP_CreateRecord() to create an SDP record.
|
||||||
|
**
|
||||||
|
** Returns TRUE if function execution succeeded,
|
||||||
|
** FALSE if function execution failed.
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
BOOLEAN bta_ag_add_record(UINT16 service_uuid, char *p_service_name, UINT8 scn,
|
||||||
|
tBTA_AG_FEAT features, UINT32 sdp_handle)
|
||||||
|
{
|
||||||
|
tSDP_PROTOCOL_ELEM proto_elem_list[BTA_AG_NUM_PROTO_ELEMS];
|
||||||
|
UINT16 svc_class_id_list[BTA_AG_NUM_SVC_ELEMS];
|
||||||
|
UINT16 browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
|
||||||
|
UINT16 version;
|
||||||
|
UINT16 profile_uuid;
|
||||||
|
UINT8 network;
|
||||||
|
BOOLEAN result = TRUE;
|
||||||
|
BOOLEAN codec_supported = FALSE;
|
||||||
|
UINT8 buf[2];
|
||||||
|
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_add_record uuid: %x", service_uuid);
|
||||||
|
|
||||||
|
memset( proto_elem_list, 0 , BTA_AG_NUM_PROTO_ELEMS*sizeof(tSDP_PROTOCOL_ELEM));
|
||||||
|
/* add the protocol element sequence */
|
||||||
|
proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
|
||||||
|
proto_elem_list[0].num_params = 0;
|
||||||
|
proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
|
||||||
|
proto_elem_list[1].num_params = 1;
|
||||||
|
proto_elem_list[1].params[0] = scn;
|
||||||
|
result &= SDP_AddProtocolList(sdp_handle, BTA_AG_NUM_PROTO_ELEMS, proto_elem_list);
|
||||||
|
|
||||||
|
/* add service class id list */
|
||||||
|
svc_class_id_list[0] = service_uuid;
|
||||||
|
svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
|
||||||
|
result &= SDP_AddServiceClassIdList(sdp_handle, BTA_AG_NUM_SVC_ELEMS, svc_class_id_list);
|
||||||
|
|
||||||
|
/* add profile descriptor list */
|
||||||
|
if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) {
|
||||||
|
profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
|
||||||
|
version = HFP_VERSION_1_6;
|
||||||
|
} else {
|
||||||
|
profile_uuid = UUID_SERVCLASS_HEADSET;
|
||||||
|
version = HSP_VERSION_1_2;
|
||||||
|
}
|
||||||
|
result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
|
||||||
|
|
||||||
|
/* add service name */
|
||||||
|
if (p_service_name != NULL && p_service_name[0] != 0) {
|
||||||
|
result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
|
||||||
|
(UINT32)(strlen(p_service_name)+1), (UINT8 *) p_service_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add features and network */
|
||||||
|
if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) {
|
||||||
|
network = (features & BTA_AG_FEAT_REJECT) ? 1 : 0;
|
||||||
|
result &= SDP_AddAttribute(sdp_handle, ATTR_ID_DATA_STORES_OR_NETWORK,
|
||||||
|
UINT_DESC_TYPE, 1, &network);
|
||||||
|
|
||||||
|
if (features & BTA_AG_FEAT_CODEC) {
|
||||||
|
codec_supported = TRUE;
|
||||||
|
}
|
||||||
|
features &= BTA_AG_SDP_FEAT_SPEC;
|
||||||
|
/* Codec bit position is different in SDP and in BRSF */
|
||||||
|
if (codec_supported) {
|
||||||
|
features |= 0x0020;
|
||||||
|
}
|
||||||
|
UINT16_TO_BE_FIELD(buf, features);
|
||||||
|
result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 2, buf);
|
||||||
|
}
|
||||||
|
/* add browse group list */
|
||||||
|
result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_create_records
|
||||||
|
**
|
||||||
|
** Description Create SDP records for registered services.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_create_records(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_SERVICE_MASK services;
|
||||||
|
services = p_scb->reg_services >> BTA_HSP_SERVICE_ID;
|
||||||
|
|
||||||
|
for (int i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1) {
|
||||||
|
/* if service is set in mask */
|
||||||
|
if (services & 1) {
|
||||||
|
/* add sdp record if not already registered */
|
||||||
|
if (bta_ag_cb.profile[i].sdp_handle == 0) {
|
||||||
|
bta_ag_cb.profile[i].sdp_handle = SDP_CreateRecord();
|
||||||
|
bta_ag_cb.profile[i].scn = BTM_AllocateSCN();
|
||||||
|
bta_ag_add_record(bta_ag_uuid[i], p_data->api_register.p_name[i],
|
||||||
|
bta_ag_cb.profile[i].scn, p_data->api_register.features,
|
||||||
|
bta_ag_cb.profile[i].sdp_handle);
|
||||||
|
bta_sys_add_uuid(bta_ag_uuid[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p_scb->hsp_version = HSP_VERSION_1_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_del_records
|
||||||
|
**
|
||||||
|
** Description Delete SDP records for any registered services.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_del_records(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB *p = &bta_ag_cb.scb[0];
|
||||||
|
tBTA_SERVICE_MASK services;
|
||||||
|
tBTA_SERVICE_MASK others = 0;
|
||||||
|
int i;
|
||||||
|
UNUSED(p_data);
|
||||||
|
|
||||||
|
/* get services of all other registered servers */
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX; i++, p++) {
|
||||||
|
if (p_scb == p) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (p->in_use && p->dealloc == FALSE) {
|
||||||
|
others |= p->reg_services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
others >>= BTA_HSP_SERVICE_ID;
|
||||||
|
services = p_scb->reg_services >> BTA_HSP_SERVICE_ID;
|
||||||
|
for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1, others >>= 1)
|
||||||
|
{
|
||||||
|
/* if service registered for this scb and not registered for any other scb */
|
||||||
|
if (((services & 1) == 1) && ((others & 1) == 0)) {
|
||||||
|
APPL_TRACE_DEBUG("bta_ag_del_records %d", i);
|
||||||
|
if (bta_ag_cb.profile[i].sdp_handle != 0) {
|
||||||
|
SDP_DeleteRecord(bta_ag_cb.profile[i].sdp_handle);
|
||||||
|
bta_ag_cb.profile[i].sdp_handle = 0;
|
||||||
|
}
|
||||||
|
BTM_FreeSCN(bta_ag_cb.profile[i].scn);
|
||||||
|
BTM_SecClrService(bta_ag_sec_id[i]);
|
||||||
|
bta_sys_remove_uuid(bta_ag_uuid[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sdp_find_attr
|
||||||
|
**
|
||||||
|
** Description Process SDP discovery results to find requested attributes
|
||||||
|
** for requested service.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns TRUE if results found, FALSE otherwise.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
BOOLEAN bta_ag_sdp_find_attr(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service)
|
||||||
|
{
|
||||||
|
tSDP_DISC_REC *p_rec = NULL;
|
||||||
|
tSDP_DISC_ATTR *p_attr;
|
||||||
|
tSDP_PROTOCOL_ELEM pe;
|
||||||
|
UINT16 uuid;
|
||||||
|
BOOLEAN result = FALSE;
|
||||||
|
|
||||||
|
if (service & BTA_HFP_SERVICE_MASK) {
|
||||||
|
uuid = UUID_SERVCLASS_HF_HANDSFREE;
|
||||||
|
p_scb->peer_version = HFP_VERSION_1_1; /* Default version */
|
||||||
|
} else if (service & BTA_HSP_SERVICE_MASK && p_scb->role == BTA_AG_INT) {
|
||||||
|
uuid = UUID_SERVCLASS_HEADSET_HS;
|
||||||
|
p_scb->peer_version = 0x0100; /* Default version */
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* loop through all records we found */
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
/* get next record; if none found, we're done */
|
||||||
|
if ((p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec)) == NULL) {
|
||||||
|
if (uuid == UUID_SERVCLASS_HEADSET_HS) {
|
||||||
|
/* Search again in case the peer device is HSP v1.0 */
|
||||||
|
uuid = UUID_SERVCLASS_HEADSET;
|
||||||
|
if ((p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec)) == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get scn from proto desc list if initiator */
|
||||||
|
if (p_scb->role == BTA_AG_INT) {
|
||||||
|
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||||
|
p_scb->peer_scn = (UINT8) pe.params[0];
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* get profile version (if failure, version parameter is not updated) */
|
||||||
|
SDP_FindProfileVersionInRec(p_rec, uuid, &p_scb->peer_version);
|
||||||
|
/* get features if HFP */
|
||||||
|
if (service & BTA_HFP_SERVICE_MASK) {
|
||||||
|
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES)) != NULL) {
|
||||||
|
/* Found attribute. Get value. */
|
||||||
|
/* There might be race condition between SDP and BRSF. */
|
||||||
|
/* Do not update if we already received BRSF. */
|
||||||
|
if (p_scb->peer_features == 0)
|
||||||
|
p_scb->peer_features = p_attr->attr_value.v.u16;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* HSP */
|
||||||
|
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL)) != NULL) {
|
||||||
|
/* Remote volume control of HSP */
|
||||||
|
if (p_attr->attr_value.v.u8) {
|
||||||
|
p_scb->peer_features |= BTA_AG_PEER_FEAT_VOL;
|
||||||
|
} else {
|
||||||
|
p_scb->peer_features &= ~BTA_AG_PEER_FEAT_VOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* found what we needed */
|
||||||
|
result = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_do_disc
|
||||||
|
**
|
||||||
|
** Description Do service discovery.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_do_disc(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service)
|
||||||
|
{
|
||||||
|
tSDP_UUID uuid_list[2];
|
||||||
|
UINT16 num_uuid = 1;
|
||||||
|
UINT16 attr_list[4];
|
||||||
|
UINT8 num_attr;
|
||||||
|
BOOLEAN db_inited = FALSE;
|
||||||
|
|
||||||
|
/* HFP initiator; get proto list and features */
|
||||||
|
if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_INT) {
|
||||||
|
attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
|
||||||
|
attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
|
||||||
|
attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
|
||||||
|
attr_list[3] = ATTR_ID_SUPPORTED_FEATURES;
|
||||||
|
num_attr = 4;
|
||||||
|
uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HF_HANDSFREE;
|
||||||
|
} else if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_ACP) {
|
||||||
|
/* HFP acceptor; get features */
|
||||||
|
attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
|
||||||
|
attr_list[1] = ATTR_ID_BT_PROFILE_DESC_LIST;
|
||||||
|
attr_list[2] = ATTR_ID_SUPPORTED_FEATURES;
|
||||||
|
num_attr = 3;
|
||||||
|
uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HF_HANDSFREE;
|
||||||
|
} else if (service & BTA_HSP_SERVICE_MASK && p_scb->role == BTA_AG_INT) {
|
||||||
|
/* HSP initiator; get proto list */
|
||||||
|
attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
|
||||||
|
attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
|
||||||
|
attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
|
||||||
|
attr_list[3] = ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL;
|
||||||
|
num_attr = 4;
|
||||||
|
uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HEADSET; /* Legacy from HSP v1.0 */
|
||||||
|
if (p_scb->hsp_version >= HSP_VERSION_1_2) {
|
||||||
|
uuid_list[1].uu.uuid16 = UUID_SERVCLASS_HEADSET_HS;
|
||||||
|
num_uuid = 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* HSP acceptor; no discovery */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate buffer for sdp database */
|
||||||
|
p_scb->p_disc_db = (tSDP_DISCOVERY_DB *) osi_malloc(BTA_AG_DISC_BUF_SIZE);
|
||||||
|
if(p_scb->p_disc_db) {
|
||||||
|
/* set up service discovery database; attr happens to be attr_list len */
|
||||||
|
uuid_list[0].len = LEN_UUID_16;
|
||||||
|
uuid_list[1].len = LEN_UUID_16;
|
||||||
|
db_inited = SDP_InitDiscoveryDb(p_scb->p_disc_db, BTA_AG_DISC_BUF_SIZE, num_uuid,
|
||||||
|
uuid_list, num_attr, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(db_inited) {
|
||||||
|
/*Service discovery not initiated */
|
||||||
|
db_inited = SDP_ServiceSearchAttributeRequest(p_scb->peer_addr, p_scb->p_disc_db,
|
||||||
|
bta_ag_sdp_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]);
|
||||||
|
}
|
||||||
|
if(!db_inited) {
|
||||||
|
/*free discover db */
|
||||||
|
bta_ag_free_db(p_scb, NULL);
|
||||||
|
/* sent failed event */
|
||||||
|
bta_ag_sm_execute(p_scb, BTA_AG_DISC_FAIL_EVT, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_free_db
|
||||||
|
**
|
||||||
|
** Description Free discovery database.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_free_db(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||||
|
{
|
||||||
|
UNUSED(p_data);
|
||||||
|
if (p_scb->p_disc_db != NULL) {
|
||||||
|
osi_free(p_scb->p_disc_db);
|
||||||
|
p_scb->p_disc_db = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
126
components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_at.h
Normal file
126
components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_at.h
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Interface file for BTA AG AT command interpreter.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef BTA_AG_AT_H
|
||||||
|
#define BTA_AG_AT_H
|
||||||
|
|
||||||
|
#include "stack/bt_types.h"
|
||||||
|
#include "common/bt_target.h"
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Constants
|
||||||
|
*****************************************************************************/
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
/* AT command argument capabilities */
|
||||||
|
#define BTA_AG_AT_NONE 0x01 /* no argument */
|
||||||
|
#define BTA_AG_AT_SET 0x02 /* set value */
|
||||||
|
#define BTA_AG_AT_READ 0x04 /* read value */
|
||||||
|
#define BTA_AG_AT_TEST 0x08 /* test value range */
|
||||||
|
#define BTA_AG_AT_FREE 0x10 /* freeform argument */
|
||||||
|
|
||||||
|
/* AT command argument format */
|
||||||
|
#define BTA_AG_AT_STR 0 /* string */
|
||||||
|
#define BTA_AG_AT_INT 1 /* integer */
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Data types
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* AT command table element */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *p_cmd; /* AT command string */
|
||||||
|
UINT8 arg_type; /* allowable argument type syntax */
|
||||||
|
UINT8 fmt; /* whether arg is int or string */
|
||||||
|
UINT8 min; /* minimum value for int arg */
|
||||||
|
INT16 max; /* maximum value for int arg */
|
||||||
|
} tBTA_AG_AT_CMD;
|
||||||
|
|
||||||
|
/* callback function executed when command is parsed */
|
||||||
|
typedef void (tBTA_AG_AT_CMD_CBACK)(void *p_user, UINT16 cmd, UINT8 arg_type,
|
||||||
|
char *p_arg, INT16 int_arg);
|
||||||
|
|
||||||
|
/* callback function executed to send "ERROR" result code */
|
||||||
|
typedef void (tBTA_AG_AT_ERR_CBACK)(void *p_user, BOOLEAN unknown, char *p_arg);
|
||||||
|
|
||||||
|
/* AT command parsing control block */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_AT_CMD *p_at_tbl; /* AT command table */
|
||||||
|
tBTA_AG_AT_CMD_CBACK *p_cmd_cback; /* command callback */
|
||||||
|
tBTA_AG_AT_ERR_CBACK *p_err_cback; /* error callback */
|
||||||
|
void *p_user; /* user-defined data */
|
||||||
|
char *p_cmd_buf; /* temp parsing buffer */
|
||||||
|
UINT16 cmd_pos; /* position in temp buffer */
|
||||||
|
UINT16 cmd_max_len; /* length of temp buffer to allocate */
|
||||||
|
UINT8 state; /* parsing state */
|
||||||
|
} tBTA_AG_AT_CB;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Function prototypes
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_at_init
|
||||||
|
**
|
||||||
|
** Description Initialize the AT command parser control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*****************************************************************************/
|
||||||
|
extern void bta_ag_at_init(tBTA_AG_AT_CB *p_cb);
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_at_reinit
|
||||||
|
**
|
||||||
|
** Description Re-initialize the AT command parser control block. This
|
||||||
|
** function resets the AT command parser state and frees
|
||||||
|
** any GKI buffer.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*****************************************************************************/
|
||||||
|
extern void bta_ag_at_reinit(tBTA_AG_AT_CB *p_cb);
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_at_parse
|
||||||
|
**
|
||||||
|
** Description Parse AT commands. This function will take the input
|
||||||
|
** character string and parse it for AT commands according to
|
||||||
|
** the AT command table passed in the control block.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*****************************************************************************/
|
||||||
|
extern void bta_ag_at_parse(tBTA_AG_AT_CB *p_cb, char *p_buf, UINT16 len);
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
||||||
|
|
||||||
|
#endif /* BTA_AG_AT_H */
|
446
components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h
Normal file
446
components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This is the private interface file for the BTA audio gateway.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef BTA_AG_INT_H
|
||||||
|
#define BTA_AG_INT_H
|
||||||
|
|
||||||
|
#include "bta_ag_at.h"
|
||||||
|
#include "bta/bta_sys.h"
|
||||||
|
#include "bta/bta_api.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "stack/sdp_api.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
/* Send RING & CLIP in one AT cmd */
|
||||||
|
#ifndef BTA_AG_MULTI_RESULT_INCLUDED
|
||||||
|
#define BTA_AG_MULTI_RESULT_INCLUDED FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Replace : in VGS and VGM for HSP */
|
||||||
|
#ifndef BTA_HSP_RESULT_REPLACE_COLON
|
||||||
|
#define BTA_HSP_RESULT_REPLACE_COLON TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Constants
|
||||||
|
*****************************************************************************/
|
||||||
|
#define HFP_VERSION_1_1 0x0101
|
||||||
|
#define HFP_VERSION_1_5 0x0105
|
||||||
|
#define HFP_VERSION_1_6 0x0106
|
||||||
|
|
||||||
|
#define HSP_VERSION_1_0 0x0100
|
||||||
|
#define HSP_VERSION_1_2 0x0102
|
||||||
|
|
||||||
|
/* Number of SCBs (AG service instances that can be registered) */
|
||||||
|
#ifndef BTA_AG_NUM_SCB
|
||||||
|
#define BTA_AG_NUM_SCB 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Timer to wait for retry in case of collision */
|
||||||
|
#ifndef BTA_AG_COLLISION_TIMER
|
||||||
|
#define BTA_AG_COLLISION_TIMER 2000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* RFCOMM MTU SIZE */
|
||||||
|
#define BTA_AG_MTU 256
|
||||||
|
|
||||||
|
/* Internal profile indexes */
|
||||||
|
#define BTA_AG_HSP 0 /* index for HSP */
|
||||||
|
#define BTA_AG_HFP 1 /* index for HFP */
|
||||||
|
#define BTA_AG_NUM_IDX 2 /* number of profile indexes */
|
||||||
|
|
||||||
|
/* profile role for connection */
|
||||||
|
#define BTA_AG_ACP 0 /* accepted connection */
|
||||||
|
#define BTA_AG_INT 1 /* initiating connection */
|
||||||
|
|
||||||
|
/* feature mask that matches spec */
|
||||||
|
#define BTA_AG_BSRF_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \
|
||||||
|
BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \
|
||||||
|
BTA_AG_FEAT_VTAG | BTA_AG_FEAT_REJECT | \
|
||||||
|
BTA_AG_FEAT_ECS | BTA_AG_FEAT_ECC | \
|
||||||
|
BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_CODEC | \
|
||||||
|
BTA_AG_FEAT_VOIP)
|
||||||
|
|
||||||
|
#define BTA_AG_SDP_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \
|
||||||
|
BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \
|
||||||
|
BTA_AG_FEAT_VTAG)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/* these events are handled by the state machine */
|
||||||
|
BTA_AG_API_REGISTER_EVT = BTA_SYS_EVT_START(BTA_ID_AG),
|
||||||
|
BTA_AG_API_DEREGISTER_EVT,
|
||||||
|
BTA_AG_API_OPEN_EVT,
|
||||||
|
BTA_AG_API_CLOSE_EVT,
|
||||||
|
BTA_AG_API_AUDIO_OPEN_EVT,
|
||||||
|
BTA_AG_API_AUDIO_CLOSE_EVT,
|
||||||
|
BTA_AG_API_RESULT_EVT,
|
||||||
|
BTA_AG_API_SETCODEC_EVT,
|
||||||
|
BTA_AG_RFC_OPEN_EVT,
|
||||||
|
BTA_AG_RFC_CLOSE_EVT,
|
||||||
|
BTA_AG_RFC_SRV_CLOSE_EVT,
|
||||||
|
BTA_AG_RFC_DATA_EVT,
|
||||||
|
BTA_AG_SCO_OPEN_EVT,
|
||||||
|
BTA_AG_SCO_CLOSE_EVT,
|
||||||
|
BTA_AG_DISC_ACP_RES_EVT,
|
||||||
|
BTA_AG_DISC_INT_RES_EVT,
|
||||||
|
BTA_AG_DISC_OK_EVT,
|
||||||
|
BTA_AG_DISC_FAIL_EVT,
|
||||||
|
BTA_AG_CI_RX_WRITE_EVT,
|
||||||
|
BTA_AG_RING_TOUT_EVT,
|
||||||
|
BTA_AG_SVC_TOUT_EVT,
|
||||||
|
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||||
|
BTA_AG_CI_SCO_DATA_EVT,
|
||||||
|
#endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */
|
||||||
|
BTA_AG_CI_SLC_READY_EVT,
|
||||||
|
BTA_AG_MAX_EVT,
|
||||||
|
|
||||||
|
/* these events are handled outside of the state machine */
|
||||||
|
BTA_AG_API_ENABLE_EVT,
|
||||||
|
BTA_AG_API_DISABLE_EVT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Actions to perform after a SCO event */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BTA_AG_POST_SCO_NONE, /* no action */
|
||||||
|
BTA_AG_POST_SCO_CLOSE_RFC, /* close RFCOMM channel after SCO closes */
|
||||||
|
BTA_AG_POST_SCO_RING, /* send RING result code after SCO opens */
|
||||||
|
BTA_AG_POST_SCO_CALL_CONN, /* send call indicators after SCO opens/closes */
|
||||||
|
BTA_AG_POST_SCO_CALL_ORIG, /* send call indicators after SCO closes */
|
||||||
|
BTA_AG_POST_SCO_CALL_END, /* send call indicators after SCO closes */
|
||||||
|
BTA_AG_POST_SCO_CALL_END_INCALL /* send call indicators for end call & incoming call after SCO closes */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* sco states */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BTA_AG_SCO_SHUTDOWN_ST, /* no sco listening, all sco connections closed */
|
||||||
|
BTA_AG_SCO_LISTEN_ST, /* sco listening */
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
BTA_AG_SCO_CODEC_ST, /* sco codec negotiation */
|
||||||
|
#endif
|
||||||
|
BTA_AG_SCO_OPENING_ST, /* sco connection opening */
|
||||||
|
BTA_AG_SCO_OPEN_CL_ST, /* opening sco connection being closed */
|
||||||
|
BTA_AG_SCO_OPEN_XFER_ST, /* opening sco connection being transferred */
|
||||||
|
BTA_AG_SCO_OPEN_ST, /* sco open */
|
||||||
|
BTA_AG_SCO_CLOSING_ST, /* sco closing */
|
||||||
|
BTA_AG_SCO_CLOSE_OP_ST, /* closing sco being opened */
|
||||||
|
BTA_AG_SCO_CLOSE_XFER_ST, /* closing sco being transferred */
|
||||||
|
BTA_AG_SCO_SHUTTING_ST /* sco shutting down */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Data types
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* data type for BTA_AG_API_ENABLE_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
tBTA_AG_PARSE_MODE parse_mode;
|
||||||
|
tBTA_AG_CBACK *p_cback;
|
||||||
|
} tBTA_AG_API_ENABLE;
|
||||||
|
|
||||||
|
/* data type for BTA_AG_API_REGISTER_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
char p_name[2][BTA_SERVICE_NAME_LEN+1];
|
||||||
|
tBTA_SERVICE_MASK services;
|
||||||
|
tBTA_SEC sec_mask;
|
||||||
|
tBTA_AG_FEAT features;
|
||||||
|
UINT8 app_id;
|
||||||
|
} tBTA_AG_API_REGISTER;
|
||||||
|
|
||||||
|
/* data type for BTA_AG_API_OPEN_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
BD_ADDR bd_addr;
|
||||||
|
tBTA_SERVICE_MASK services;
|
||||||
|
tBTA_SEC sec_mask;
|
||||||
|
} tBTA_AG_API_OPEN;
|
||||||
|
|
||||||
|
/* data type for BTA_AG_API_RESULT_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
tBTA_AG_RES result;
|
||||||
|
tBTA_AG_RES_DATA data;
|
||||||
|
} tBTA_AG_API_RESULT;
|
||||||
|
|
||||||
|
/* data type for BTA_AG_API_SETCODEC_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
tBTA_AG_PEER_CODEC codec;
|
||||||
|
} tBTA_AG_API_SETCODEC;
|
||||||
|
|
||||||
|
/* data type for BTA_AG_DISC_RESULT_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
UINT16 status;
|
||||||
|
} tBTA_AG_DISC_RESULT;
|
||||||
|
|
||||||
|
/* data type for RFCOMM events */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
UINT16 port_handle;
|
||||||
|
} tBTA_AG_RFC;
|
||||||
|
|
||||||
|
/* data type for BTA_AG_CI_RX_WRITE_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
char p_data[BTA_AG_MTU+1];
|
||||||
|
} tBTA_AG_CI_RX_WRITE;
|
||||||
|
|
||||||
|
/* union of all event datatypes */
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
BT_HDR hdr;
|
||||||
|
tBTA_AG_API_ENABLE api_enable;
|
||||||
|
tBTA_AG_API_REGISTER api_register;
|
||||||
|
tBTA_AG_API_OPEN api_open;
|
||||||
|
tBTA_AG_API_RESULT api_result;
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
tBTA_AG_API_SETCODEC api_setcodec;
|
||||||
|
#endif
|
||||||
|
tBTA_AG_DISC_RESULT disc_result;
|
||||||
|
tBTA_AG_RFC rfc;
|
||||||
|
tBTA_AG_CI_RX_WRITE ci_rx_write;
|
||||||
|
} tBTA_AG_DATA;
|
||||||
|
|
||||||
|
/* type for each profile */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UINT32 sdp_handle;
|
||||||
|
UINT8 scn;
|
||||||
|
} tBTA_AG_PROFILE;
|
||||||
|
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE)
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
BTA_AG_SCO_MSBC_SETTINGS_T2 = 0, /* preferred/default when codec is mSBC */
|
||||||
|
BTA_AG_SCO_MSBC_SETTINGS_T1,
|
||||||
|
} tBTA_AG_SCO_MSBC_SETTINGS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* type for each service control block */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char clip[BTA_AG_AT_MAX_LEN+10]; /* number string used for CLIP */
|
||||||
|
UINT16 serv_handle[BTA_AG_NUM_IDX]; /* RFCOMM server handles */
|
||||||
|
tBTA_AG_AT_CB at_cb; /* AT command interpreter */
|
||||||
|
TIMER_LIST_ENT act_timer; /* ring timer */
|
||||||
|
BD_ADDR peer_addr; /* peer bd address */
|
||||||
|
tSDP_DISCOVERY_DB *p_disc_db; /* pointer to discovery database */
|
||||||
|
tBTA_SERVICE_MASK reg_services; /* services specified in register API */
|
||||||
|
tBTA_SERVICE_MASK open_services; /* services specified in open API */
|
||||||
|
UINT16 conn_handle; /* RFCOMM handle of connected service */
|
||||||
|
tBTA_SEC serv_sec_mask; /* server security mask */
|
||||||
|
tBTA_SEC cli_sec_mask; /* client security mask */
|
||||||
|
tBTA_AG_FEAT features; /* features registered by application */
|
||||||
|
tBTA_AG_PEER_FEAT peer_features; /* peer device features */
|
||||||
|
UINT16 peer_version; /* profile version of peer device */
|
||||||
|
UINT16 hsp_version; /* HSP profile version */
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE)
|
||||||
|
tBTA_AG_PEER_CODEC peer_codecs; /* codecs for eSCO supported by the peer */
|
||||||
|
tBTA_AG_PEER_CODEC sco_codec; /* codec to be used for eSCO connection */
|
||||||
|
tBTA_AG_PEER_CODEC inuse_codec; /* codec being used for the current SCO connection */
|
||||||
|
BOOLEAN codec_updated; /* set to TRUE whenever the app updates codec type */
|
||||||
|
BOOLEAN codec_fallback; /* If sco nego fails for mSBC, fallback to CVSD */
|
||||||
|
tBTA_AG_SCO_MSBC_SETTINGS codec_msbc_settings; /* settings to be used for the impending eSCO */
|
||||||
|
TIMER_LIST_ENT cn_timer; /* codec negotiation timer */
|
||||||
|
#endif
|
||||||
|
UINT16 sco_idx; /* SCO handle */
|
||||||
|
BOOLEAN in_use; /* scb in use */
|
||||||
|
BOOLEAN dealloc; /* TRUE if service shutting down */
|
||||||
|
BOOLEAN clip_enabled; /* set to TRUE if HF enables CLIP reporting */
|
||||||
|
BOOLEAN ccwa_enabled; /* set to TRUE if HF enables CCWA reporting */
|
||||||
|
BOOLEAN cmer_enabled; /* set to TRUE if HF enables CMER reporting */
|
||||||
|
BOOLEAN cmee_enabled; /* set to TRUE if HF enables CME ERROR reporting */
|
||||||
|
BOOLEAN inband_enabled; /* set to TRUE if inband ring enabled */
|
||||||
|
BOOLEAN svc_conn; /* set to TRUE when service level connection up */
|
||||||
|
TIMER_LIST_ENT colli_timer; /* Collision timer */
|
||||||
|
BOOLEAN colli_tmr_on; /* TRUE if collision timer is active */
|
||||||
|
UINT8 state; /* state machine state */
|
||||||
|
UINT8 conn_service; /* connected service */
|
||||||
|
UINT8 peer_scn; /* peer scn */
|
||||||
|
UINT8 app_id; /* application id */
|
||||||
|
UINT8 role; /* initiator/acceptor role */
|
||||||
|
tBTM_SCO_CODEC_TYPE negotiated_codec; /* negotiated codec */
|
||||||
|
UINT8 post_sco; /* action to perform after sco event */
|
||||||
|
UINT8 call_ind; /* CIEV call indicator value */
|
||||||
|
UINT8 callsetup_ind; /* CIEV callsetup indicator value */
|
||||||
|
UINT8 service_ind; /* CIEV service indicator value */
|
||||||
|
UINT8 signal_ind; /* CIEV signal indicator value */
|
||||||
|
UINT8 roam_ind; /* CIEV roam indicator value */
|
||||||
|
UINT8 battchg_ind; /* CIEV battery charge indicator value */
|
||||||
|
UINT8 callheld_ind; /* CIEV call held indicator value */
|
||||||
|
BOOLEAN retry_with_sco_only; /* indicator to try with SCO only when eSCO fails */
|
||||||
|
UINT32 bia_masked_out; /* indicators HF does not want us to send */
|
||||||
|
/* add */
|
||||||
|
UINT16 in_pkt_len;
|
||||||
|
UINT16 out_pkt_len;
|
||||||
|
UINT8 link_type; /* BTM_LINK_TYPE_SCO or BTM_LINK_TYPE_ESCO */
|
||||||
|
UINT8 tx_interval;
|
||||||
|
UINT8 retrans_window;
|
||||||
|
UINT8 air_mode;
|
||||||
|
} tBTA_AG_SCB;
|
||||||
|
|
||||||
|
/* type for sco data */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTM_ESCO_CONN_REQ_EVT_DATA conn_data; /* CO data for pending conn requestS */
|
||||||
|
tBTA_AG_SCB *p_curr_scb; /* SCB associated with SCO connection */
|
||||||
|
tBTA_AG_SCB *p_xfer_scb; /* SCB associated with SCO transfer */
|
||||||
|
UINT16 cur_idx; /* SCO handle */
|
||||||
|
UINT8 state; /* SCO state variable */
|
||||||
|
BOOLEAN param_updated; /* if params were updated to non-default */
|
||||||
|
tBTM_ESCO_PARAMS params; /* ESCO parameters */
|
||||||
|
tBTA_AG_DATA *p_data;
|
||||||
|
} tBTA_AG_SCO_CB;
|
||||||
|
|
||||||
|
/* type for AG control block */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_SCB scb[BTA_AG_NUM_SCB]; /* service control blocks */
|
||||||
|
tBTA_AG_PROFILE profile[BTA_AG_NUM_IDX]; /* profile-specific data */
|
||||||
|
tBTA_AG_SCO_CB sco; /* SCO data */
|
||||||
|
tBTA_AG_CBACK *p_cback; /* application callback */
|
||||||
|
tBTA_AG_PARSE_MODE parse_mode; /* parse/pass-through mode */
|
||||||
|
BOOLEAN msbc_enabled;
|
||||||
|
} tBTA_AG_CB;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Global data
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* constant lookup tables */
|
||||||
|
extern const UINT16 bta_ag_uuid[BTA_AG_NUM_IDX];
|
||||||
|
extern const UINT8 bta_ag_sec_id[BTA_AG_NUM_IDX];
|
||||||
|
extern const tBTA_AG_AT_CMD *bta_ag_at_tbl[BTA_AG_NUM_IDX];
|
||||||
|
|
||||||
|
/* control block declaration */
|
||||||
|
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||||
|
extern tBTA_AG_CB bta_ag_cb;
|
||||||
|
#else
|
||||||
|
extern tBTA_AG_CB *bta_ag_cb_ptr;
|
||||||
|
#define bta_ag_cb (*bta_ag_cb_ptr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* config struct */
|
||||||
|
extern tBTA_AG_CFG *p_bta_ag_cfg;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Function prototypes
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* main functions */
|
||||||
|
extern void bta_ag_scb_dealloc(tBTA_AG_SCB *p_scb);
|
||||||
|
extern UINT16 bta_ag_scb_to_idx(tBTA_AG_SCB *p_scb);
|
||||||
|
extern tBTA_AG_SCB *bta_ag_scb_by_idx(UINT16 idx);
|
||||||
|
extern UINT8 bta_ag_service_to_idx(tBTA_SERVICE_MASK services);
|
||||||
|
extern UINT16 bta_ag_idx_by_bdaddr(BD_ADDR peer_addr);
|
||||||
|
extern BOOLEAN bta_ag_other_scb_open(tBTA_AG_SCB *p_curr_scb);
|
||||||
|
extern BOOLEAN bta_ag_scb_open(tBTA_AG_SCB *p_curr_scb);
|
||||||
|
extern tBTA_AG_SCB *bta_ag_get_other_idle_scb (tBTA_AG_SCB *p_curr_scb);
|
||||||
|
extern void bta_ag_sm_execute(tBTA_AG_SCB *p_scb, UINT16 event, tBTA_AG_DATA *p_data);
|
||||||
|
extern BOOLEAN bta_ag_hdl_event(BT_HDR *p_msg);
|
||||||
|
extern void bta_ag_collision_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||||
|
extern void bta_ag_resume_open(tBTA_AG_SCB *p_scb);
|
||||||
|
|
||||||
|
/* SDP functions */
|
||||||
|
extern BOOLEAN bta_ag_add_record(UINT16 service_uuid, char *p_service_name, UINT8 scn, tBTA_AG_FEAT features, UINT32 sdp_handle);
|
||||||
|
extern void bta_ag_create_records(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_del_records(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern BOOLEAN bta_ag_sdp_find_attr(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service);
|
||||||
|
extern void bta_ag_do_disc(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service);
|
||||||
|
extern void bta_ag_free_db(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
|
||||||
|
/* RFCOMM functions */
|
||||||
|
extern void bta_ag_start_servers(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK services);
|
||||||
|
extern void bta_ag_close_servers(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK services);
|
||||||
|
extern BOOLEAN bta_ag_is_server_closed (tBTA_AG_SCB *p_scb);
|
||||||
|
extern void bta_ag_rfc_do_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_rfc_do_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
|
||||||
|
/* SCO functions */
|
||||||
|
extern BOOLEAN bta_ag_sco_is_open(tBTA_AG_SCB *p_scb);
|
||||||
|
extern BOOLEAN bta_ag_sco_is_opening(tBTA_AG_SCB *p_scb);
|
||||||
|
extern void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data);
|
||||||
|
|
||||||
|
/* AT command functions */
|
||||||
|
extern void bta_ag_at_hsp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type, char *p_arg, INT16 int_arg);
|
||||||
|
extern void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type, char *p_arg, INT16 int_arg);
|
||||||
|
extern void bta_ag_at_err_cback(tBTA_AG_SCB *p_scb, BOOLEAN unknown, char *p_arg);
|
||||||
|
extern BOOLEAN bta_ag_inband_enabled(tBTA_AG_SCB *p_scb);
|
||||||
|
extern void bta_ag_send_call_inds(tBTA_AG_SCB *p_scb, tBTA_AG_RES result);
|
||||||
|
|
||||||
|
/* Action functions */
|
||||||
|
extern void bta_ag_register(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_deregister(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_start_dereg(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_start_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_start_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_disc_int_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_disc_acp_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_disc_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_open_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_rfc_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_rfc_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_rfc_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_rfc_acp_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_rfc_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_sco_listen(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_sco_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE)
|
||||||
|
extern void bta_ag_sco_codec_nego(tBTA_AG_SCB *p_scb, BOOLEAN result);
|
||||||
|
extern void bta_ag_codec_negotiate (tBTA_AG_SCB *p_scb);
|
||||||
|
#endif
|
||||||
|
extern void bta_ag_sco_shutdown(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_sco_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_sco_conn_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_post_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_post_sco_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_svc_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_result(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE)
|
||||||
|
extern void bta_ag_send_bcs(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
#endif
|
||||||
|
extern void bta_ag_send_ring(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param);
|
||||||
|
extern void bta_ag_ci_rx_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
extern void bta_ag_rcvd_slc_ready(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
||||||
|
|
||||||
|
#endif /* BTA_AG_INT_H */
|
594
components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h
Normal file
594
components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h
Normal file
|
@ -0,0 +1,594 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This is the public interface file for the audio gateway (AG) subsystem
|
||||||
|
* of BTA, Broadcom's Bluetooth application layer for mobile phones.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef BTA_AG_API_H
|
||||||
|
#define BTA_AG_API_H
|
||||||
|
|
||||||
|
#include "bta_api.h"
|
||||||
|
#include "bta_hfp_defs.h"
|
||||||
|
#include "esp_hf_defs.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
/*****************************************************************************
|
||||||
|
** Constants and data types
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* AG feature masks */
|
||||||
|
#define BTA_AG_FEAT_3WAY 0x00000001 /* Three-way calling */
|
||||||
|
#define BTA_AG_FEAT_ECNR 0x00000002 /* Echo cancellation and/or noise reduction */
|
||||||
|
#define BTA_AG_FEAT_VREC 0x00000004 /* Voice recognition */
|
||||||
|
#define BTA_AG_FEAT_INBAND 0x00000008 /* In-band ring tone */
|
||||||
|
#define BTA_AG_FEAT_VTAG 0x00000010 /* Attach a phone number to a voice tag */
|
||||||
|
#define BTA_AG_FEAT_REJECT 0x00000020 /* Ability to reject incoming call */
|
||||||
|
#define BTA_AG_FEAT_ECS 0x00000040 /* Enhanced Call Status */
|
||||||
|
#define BTA_AG_FEAT_ECC 0x00000080 /* Enhanced Call Control */
|
||||||
|
#define BTA_AG_FEAT_EXTERR 0x00000100 /* Extended error codes */
|
||||||
|
#define BTA_AG_FEAT_CODEC 0x00000200 /* Codec Negotiation */
|
||||||
|
#define BTA_AG_FEAT_VOIP 0x00000400 /* VoIP call */
|
||||||
|
/* Proprietary features: using 31 ~ 16 bits */
|
||||||
|
#define BTA_AG_FEAT_BTRH 0x00010000 /* CCAP incoming call hold */
|
||||||
|
#define BTA_AG_FEAT_UNAT 0x00020000 /* Pass unknown AT commands to application */
|
||||||
|
#define BTA_AG_FEAT_NOSCO 0x00040000 /* No SCO control performed by BTA AG */
|
||||||
|
#define BTA_AG_FEAT_NO_ESCO 0x00080000 /* Do not allow or use eSCO */
|
||||||
|
typedef UINT32 tBTA_AG_FEAT;
|
||||||
|
|
||||||
|
/* HFP peer features */
|
||||||
|
#define BTA_AG_PEER_FEAT_ECNR 0x0001 /* Echo cancellation and/or noise reduction */
|
||||||
|
#define BTA_AG_PEER_FEAT_3WAY 0x0002 /* Call waiting and three-way calling */
|
||||||
|
#define BTA_AG_PEER_FEAT_CLI 0x0004 /* Caller ID presentation capability */
|
||||||
|
#define BTA_AG_PEER_FEAT_VREC 0x0008 /* Voice recognition activation */
|
||||||
|
#define BTA_AG_PEER_FEAT_VOL 0x0010 /* Remote volume control */
|
||||||
|
#define BTA_AG_PEER_FEAT_ECS 0x0020 /* Enhanced Call Status */
|
||||||
|
#define BTA_AG_PEER_FEAT_ECC 0x0040 /* Enhanced Call Control */
|
||||||
|
#define BTA_AG_PEER_FEAT_CODEC 0x0080 /* Codec Negotiation */
|
||||||
|
#define BTA_AG_PEER_FEAT_VOIP 0x0100 /* VoIP call */
|
||||||
|
typedef UINT16 tBTA_AG_PEER_FEAT;
|
||||||
|
|
||||||
|
/* AG extended call handling - masks not related to any spec */
|
||||||
|
#define BTA_AG_CLIENT_CHLD_REL 0x00000001 /* 0 Release waiting call or held calls */
|
||||||
|
#define BTA_AG_CLIENT_CHLD_REL_ACC 0x00000002 /* 1 Release active calls and accept other (waiting or held) cal */
|
||||||
|
#define BTA_AG_CLIENT_CHLD_REL_X 0x00000004 /* 1x Release x call*/
|
||||||
|
#define BTA_AG_CLIENT_CHLD_HOLD_ACC 0x00000008 /* 2 Active calls on hold and accept other call */
|
||||||
|
#define BTA_AG_CLIENT_CHLD_PRIV_X 0x00000010 /* 2x Active multiparty call on hold except call x */
|
||||||
|
#define BTA_AG_CLIENT_CHLD_MERGE 0x00000020 /* 3 Add held call to multiparty */
|
||||||
|
#define BTA_AG_CLIENT_CHLD_MERGE_DETACH 0x00000040 /* 4 Add held call to multiparty */
|
||||||
|
typedef UINT16 tBTA_AG_CHLD_FEAT;
|
||||||
|
|
||||||
|
/* HFP peer supported codec masks */
|
||||||
|
// TODO(google) This should use common definitions
|
||||||
|
// in hci/include/hci_audio.h
|
||||||
|
#define BTA_AG_CODEC_NONE BTM_SCO_CODEC_NONE
|
||||||
|
#define BTA_AG_CODEC_CVSD BTM_SCO_CODEC_CVSD /* CVSD */
|
||||||
|
#define BTA_AG_CODEC_MSBC BTM_SCO_CODEC_MSBC /* mSBC */
|
||||||
|
typedef UINT16 tBTA_AG_PEER_CODEC;
|
||||||
|
|
||||||
|
/* AG parse mode */
|
||||||
|
#define BTA_AG_PARSE 0 /* Perform AT command parsing in AG */
|
||||||
|
#define BTA_AG_PASS_THROUGH 1 /* Pass data directly to phones AT command interpreter */
|
||||||
|
typedef UINT8 tBTA_AG_PARSE_MODE;
|
||||||
|
|
||||||
|
/* AG open status */
|
||||||
|
#define BTA_AG_SUCCESS 0 /* Connection successfully opened */
|
||||||
|
#define BTA_AG_FAIL_SDP 1 /* Open failed due to SDP */
|
||||||
|
#define BTA_AG_FAIL_RFCOMM 2 /* Open failed due to RFCOMM */
|
||||||
|
#define BTA_AG_FAIL_RESOURCES 3 /* out of resources failure */
|
||||||
|
typedef UINT8 tBTA_AG_STATUS;
|
||||||
|
|
||||||
|
/* handle values used with BTA_AgResult */
|
||||||
|
#define BTA_AG_HANDLE_NONE 0
|
||||||
|
#define BTA_AG_HANDLE_ALL 0xFFFF
|
||||||
|
/* It is safe to use the same value as BTA_AG_HANDLE_ALL
|
||||||
|
* HANDLE_ALL is used for delivering indication
|
||||||
|
* SCO_NO_CHANGE is used for changing sco behavior
|
||||||
|
* They donot interfere with each other
|
||||||
|
*/
|
||||||
|
#define BTA_AG_HANDLE_SCO_NO_CHANGE 0xFFFF
|
||||||
|
|
||||||
|
/* AG result codes used with BTA_AgResult */
|
||||||
|
#define BTA_AG_SPK_RES 0 /* Update speaker volume */
|
||||||
|
#define BTA_AG_MIC_RES 1 /* Update microphone volume */
|
||||||
|
#define BTA_AG_INBAND_RING_RES 2 /* Update inband ring state AT+BSIR */
|
||||||
|
#define BTA_AG_CIND_RES 3 /* Send indicator response for AT+CIND */
|
||||||
|
#define BTA_AG_BINP_RES 4 /* Send phone number for voice tag for AT+BINP */
|
||||||
|
#define BTA_AG_IND_RES 5 /* Update an indicator value +CIEV<...> */
|
||||||
|
#define BTA_AG_BVRA_RES 6 /* Update voice recognition state for AT+BVRA */
|
||||||
|
#define BTA_AG_CNUM_RES 7 /* Send subscriber number response for AT+CNUM */
|
||||||
|
#define BTA_AG_BTRH_RES 8 /* Send CCAP incoming call hold */
|
||||||
|
#define BTA_AG_CLCC_RES 9 /* Query list of calls AT+CLCC */
|
||||||
|
#define BTA_AG_COPS_RES 10 /* Read network operator for AT+COPS */
|
||||||
|
#define BTA_AG_IN_CALL_RES 11 /* Indicate incoming phone call */
|
||||||
|
#define BTA_AG_IN_CALL_CONN_RES 12 /* Incoming phone call connected*/
|
||||||
|
#define BTA_AG_CALL_WAIT_RES 13 /* Call waiting notification for AT+CCWA */
|
||||||
|
#define BTA_AG_OUT_CALL_ORIG_RES 14 /* Outgoing phone call origination AT+ATD*/
|
||||||
|
#define BTA_AG_OUT_CALL_ALERT_RES 15 /* Outgoing phone call alerting remote party */
|
||||||
|
#define BTA_AG_OUT_CALL_CONN_RES 16 /* Outgoing phone call connected */
|
||||||
|
#define BTA_AG_CALL_CANCEL_RES 17 /* Incoming/outgoing 3-way canceled before connected */
|
||||||
|
#define BTA_AG_END_CALL_RES 18 /* End call AT+CHUP */
|
||||||
|
#define BTA_AG_IN_CALL_HELD_RES 19 /* Incoming call held AT+CHLD */
|
||||||
|
#define BTA_AG_UNAT_RES 20 /* Response to unknown AT command event AT+UNAT */
|
||||||
|
#define BTA_AG_MULTI_CALL_RES 21 /* SLC at three way call */
|
||||||
|
typedef UINT8 tBTA_AG_RES;
|
||||||
|
|
||||||
|
/* AG callback events */
|
||||||
|
#define BTA_AG_ENABLE_EVT 0 /* AG enabled */
|
||||||
|
#define BTA_AG_REGISTER_EVT 1 /* AG registered */
|
||||||
|
#define BTA_AG_OPEN_EVT 2 /* AG connection open */
|
||||||
|
#define BTA_AG_CLOSE_EVT 3 /* AG connection closed */
|
||||||
|
#define BTA_AG_CONN_EVT 4 /* Service level connection opened */
|
||||||
|
#define BTA_AG_AUDIO_OPEN_EVT 5 /* Audio connection open */
|
||||||
|
#define BTA_AG_AUDIO_CLOSE_EVT 6 /* Audio connection closed */
|
||||||
|
#define BTA_AG_SPK_EVT 7 /* Speaker volume changed */
|
||||||
|
#define BTA_AG_MIC_EVT 8 /* Microphone volume changed */
|
||||||
|
#define BTA_AG_AT_CKPD_EVT 9 /* CKPD from the HS */
|
||||||
|
#define BTA_AG_DISABLE_EVT 30 /* AG disabled */
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
#define BTA_AG_WBS_EVT 31 /* SCO codec nego */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Values below are for HFP only */
|
||||||
|
#define BTA_AG_AT_A_EVT 10 /* Answer a incoming call */
|
||||||
|
#define BTA_AG_AT_D_EVT 11 /* Place a call using number or memory dial */
|
||||||
|
#define BTA_AG_AT_CHLD_EVT 12 /* Call hold */
|
||||||
|
#define BTA_AG_AT_CHUP_EVT 13 /* Hang up a call */
|
||||||
|
#define BTA_AG_AT_CIND_EVT 14 /* Read indicator settings */
|
||||||
|
#define BTA_AG_AT_VTS_EVT 15 /* Transmit DTMF tone */
|
||||||
|
#define BTA_AG_AT_BINP_EVT 16 /* Retrieve number from voice tag */
|
||||||
|
#define BTA_AG_AT_BLDN_EVT 17 /* Place call to last dialed number */
|
||||||
|
#define BTA_AG_AT_BVRA_EVT 18 /* Enable/disable voice recognition */
|
||||||
|
#define BTA_AG_AT_NREC_EVT 19 /* Disable echo canceling */
|
||||||
|
#define BTA_AG_AT_CNUM_EVT 20 /* Retrieve subscriber number */
|
||||||
|
#define BTA_AG_AT_BTRH_EVT 21 /* CCAP-style incoming call hold */
|
||||||
|
#define BTA_AG_AT_CLCC_EVT 22 /* Query list of current calls */
|
||||||
|
#define BTA_AG_AT_COPS_EVT 23 /* Query Current Operator Name on AG */
|
||||||
|
#define BTA_AG_AT_UNAT_EVT 24 /* Unknown AT command */
|
||||||
|
#define BTA_AG_AT_CBC_EVT 25 /* Indicator Update */
|
||||||
|
#define BTA_AG_AT_BAC_EVT 26 /* avablable codec */
|
||||||
|
#define BTA_AG_AT_BCS_EVT 27 /* Codec select */
|
||||||
|
typedef UINT8 tBTA_AG_EVT;
|
||||||
|
|
||||||
|
/* HFP errcode - Set when BTA_AG_OK_ERROR is returned in 'ok_flag' */
|
||||||
|
#define BTA_AG_ERR_PHONE_FAILURE 0 /* Phone Failure */
|
||||||
|
#define BTA_AG_ERR_NO_CONN_PHONE 1 /* No connection to phone */
|
||||||
|
#define BTA_AG_ERR_OP_NOT_ALLOWED 3 /* Operation not allowed */
|
||||||
|
#define BTA_AG_ERR_OP_NOT_SUPPORTED 4 /* Operation not supported */
|
||||||
|
#define BTA_AG_ERR_PHSIM_PIN_REQ 5 /* PH-SIM PIN required */
|
||||||
|
#define BTA_AG_ERR_SIM_NOT_INSERTED 10 /* SIM not inserted */
|
||||||
|
#define BTA_AG_ERR_SIM_PIN_REQ 11 /* SIM PIN required */
|
||||||
|
#define BTA_AG_ERR_SIM_PUK_REQ 12 /* SIM PUK required */
|
||||||
|
#define BTA_AG_ERR_SIM_FAILURE 13 /* SIM failure */
|
||||||
|
#define BTA_AG_ERR_SIM_BUSY 14 /* SIM busy */
|
||||||
|
#define BTA_AG_ERR_INCORRECT_PWD 16 /* Incorrect password */
|
||||||
|
#define BTA_AG_ERR_SIM_PIN2_REQ 17 /* SIM PIN2 required */
|
||||||
|
#define BTA_AG_ERR_SIM_PUK2_REQ 18 /* SIM PUK2 required */
|
||||||
|
#define BTA_AG_ERR_MEMORY_FULL 20 /* Memory full */
|
||||||
|
#define BTA_AG_ERR_INVALID_INDEX 21 /* Invalid index */
|
||||||
|
#define BTA_AG_ERR_MEMORY_FAILURE 23 /* Memory failure */
|
||||||
|
#define BTA_AG_ERR_TEXT_TOO_LONG 24 /* Text string too long */
|
||||||
|
#define BTA_AG_ERR_INV_CHAR_IN_TSTR 25 /* Invalid characters in text string */
|
||||||
|
#define BTA_AG_ERR_DSTR_TOO_LONG 26 /* Dial string too long */
|
||||||
|
#define BTA_AG_ERR_INV_CHAR_IN_DSTR 27 /* Invalid characters in dial string */
|
||||||
|
#define BTA_AG_ERR_NO_NETWORK_SERV 30 /* No network service */
|
||||||
|
#define BTA_AG_ERR_NETWORK_TIME_OUT 31 /* Network timeout */
|
||||||
|
#define BTA_AG_ERR_NO_NET_EMG_ONLY 32 /* Network not allowed - emergency service only */
|
||||||
|
#define BTA_AG_ERR_VOIP_CS_CALLS 33 /* AG cannot create simultaneous VoIP and CS calls */
|
||||||
|
#define BTA_AG_ERR_NOT_FOR_VOIP 34 /* Not supported on this call type(VoIP) */
|
||||||
|
#define BTA_AG_ERR_SIP_RESP_CODE 35 /* SIP 3 digit response code */
|
||||||
|
typedef UINT8 tBTA_AG_ERR_TYPE;
|
||||||
|
|
||||||
|
#if 0 /* Not Used in Bluetooth HFP 1.5 Specification */
|
||||||
|
#define BTA_AG_ERR_PHADAP_LNK_RES 2 /* Phone-adapter link reserved */
|
||||||
|
#define BTA_AG_ERR_PHFSIM_PIN_REQ 6 /* PH-FSIM PIN required */
|
||||||
|
#define BTA_AG_ERR_PHFSIM_PUK_REQ 7 /* PH-FSIM PUK required */
|
||||||
|
#define BTA_AG_ERR_SIM_WRONG 15 /* SIM wrong */
|
||||||
|
#define BTA_AG_ERR_NOT_FOUND 22 /* Not found */
|
||||||
|
#define BTA_AG_ERR_NETWORK_TIMEOUT 31 /* Network timeout */
|
||||||
|
#define BTA_AG_ERR_NET_PIN_REQ 40 /* Network personalization PIN required */
|
||||||
|
#define BTA_AG_ERR_NET_PUK_REQ 41 /* Network personalization PUK required */
|
||||||
|
#define BTA_AG_ERR_SUBSET_PIN_REQ 42 /* Network subset personalization PIN required */
|
||||||
|
#define BTA_AG_ERR_SUBSET_PUK_REQ 43 /* Network subset personalization PUK required */
|
||||||
|
#define BTA_AG_ERR_SERVPRO_PIN_REQ 44 /* Service provider personalization PIN required */
|
||||||
|
#define BTA_AG_ERR_SERVPRO_PUK_REQ 45 /* Service provider personalization PUK required */
|
||||||
|
#define BTA_AG_ERR_CORP_PIN_REQ 46 /* Corporate personalization PIN required */
|
||||||
|
#define BTA_AG_ERR_CORP_PUK_REQ 47 /* Corporate personalization PUK required */
|
||||||
|
#define BTA_AG_ERR_UNKNOWN 100 /* Unknown error */
|
||||||
|
/* GPRS-related errors */
|
||||||
|
#define BTA_AG_ERR_ILL_MS 103 /* Illegal MS (#3) */
|
||||||
|
#define BTA_AG_ERR_ILL_ME 106 /* Illegal ME (#6) */
|
||||||
|
#define BTA_AG_ERR_GPRS_NOT_ALLOWED 107 /* GPRS services not allowed (#7) */
|
||||||
|
#define BTA_AG_ERR_PLMN_NOT_ALLOWED 111 /* PLMN services not allowed (#11) */
|
||||||
|
#define BTA_AG_ERR_LOC_NOT_ALLOWED 112 /* Location area not allowed (#12) */
|
||||||
|
#define BTA_AG_ERR_ROAM_NOT_ALLOWED 113 /* Roaming not allowed in this location area (#13) */
|
||||||
|
/* Errors related to a failure to Activate a Context */
|
||||||
|
#define BTA_AG_ERR_OPT_NOT_SUPP 132 /* Service option not supported (#32) */
|
||||||
|
#define BTA_AG_ERR_OPT_NOT_SUBSCR 133 /* Requested service option not subscribed (#33) */
|
||||||
|
#define BTA_AG_ERR_OPT_OUT_OF_ORDER 134 /* Service option temporarily out of order (#34) */
|
||||||
|
#define BTA_AG_ERR_PDP_AUTH_FAILURE 149 /* PDP authentication failure */
|
||||||
|
/* Other GPRS errors */
|
||||||
|
#define BTA_AG_ERR_INV_MOBILE_CLASS 150 /* Invalid mobile class */
|
||||||
|
#define BTA_AG_ERR_UNSPEC_GPRS_ERR 148 /* Unspecified GPRS error */
|
||||||
|
#endif /* Unused error codes */
|
||||||
|
|
||||||
|
/* HFP result data 'ok_flag' */
|
||||||
|
#define BTA_AG_OK_CONTINUE 0 /* Send out response (more responses coming) */
|
||||||
|
#define BTA_AG_OK_DONE 1 /* Send out response followed by OK (finished) */
|
||||||
|
#define BTA_AG_OK_ERROR 2 /* Error response */
|
||||||
|
typedef UINT8 tBTA_AG_AT_RESULT_TYPE;
|
||||||
|
|
||||||
|
/* BTRH values */
|
||||||
|
#define BTA_AG_BTRH_SET_HOLD 0 /* Put incoming call on hold */
|
||||||
|
#define BTA_AG_BTRH_SET_ACC 1 /* Accept incoming call on hold */
|
||||||
|
#define BTA_AG_BTRH_SET_REJ 2 /* Reject incoming call on hold */
|
||||||
|
#define BTA_AG_BTRH_READ 3 /* Read the current value */
|
||||||
|
#define BTA_AG_BTRH_NO_RESP 4 /* Not in RH States (reply to read) */
|
||||||
|
typedef UINT8 tBTA_AG_BTRH_TYPE;
|
||||||
|
|
||||||
|
/* ASCII character string of arguments to the AT command or result */
|
||||||
|
#ifndef BTA_AG_AT_MAX_LEN
|
||||||
|
#define BTA_AG_AT_MAX_LEN 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* indicator constants HFP 1.1 and later */
|
||||||
|
#define BTA_AG_IND_CALL 0 /* position of call indicator */
|
||||||
|
#define BTA_AG_IND_CALLSETUP 1 /* position of callsetup indicator */
|
||||||
|
#define BTA_AG_IND_SERVICE 2 /* position of service indicator */
|
||||||
|
/* indicator constants HFP 1.5 and later */
|
||||||
|
#define BTA_AG_IND_SIGNAL 3 /* position of signal strength indicator */
|
||||||
|
#define BTA_AG_IND_ROAM 4 /* position of roaming indicator */
|
||||||
|
#define BTA_AG_IND_BATTCHG 5 /* position of battery charge indicator */
|
||||||
|
#define BTA_AG_IND_CALLHELD 6 /* position of callheld indicator */
|
||||||
|
#define BTA_AG_IND_BEARER 7 /* position of bearer indicator */
|
||||||
|
typedef UINT16 tBTA_AG_IND_TYPE;
|
||||||
|
|
||||||
|
/* call indicator values */
|
||||||
|
#define BTA_AG_CALL_INACTIVE 0 /* Phone call inactive */
|
||||||
|
#define BTA_AG_CALL_ACTIVE 1 /* Phone call active */
|
||||||
|
/* callsetup indicator values */
|
||||||
|
#define BTA_AG_CALLSETUP_NONE 0 /* Not currently in call set up */
|
||||||
|
#define BTA_AG_CALLSETUP_INCOMING 1 /* Incoming call process ongoing */
|
||||||
|
#define BTA_AG_CALLSETUP_OUTGOING 2 /* Outgoing call set up is ongoing */
|
||||||
|
#define BTA_AG_CALLSETUP_ALERTING 3 /* Remote party being alerted in an outgoing call */
|
||||||
|
/* service indicator values */
|
||||||
|
#define BTA_AG_SERVICE_NONE 0 /* Neither CS nor VoIP service is available */
|
||||||
|
#define BTA_AG_SERVICE_CS 1 /* Only CS service is available */
|
||||||
|
#define BTA_AG_SERVICE_VOIP 2 /* Only VoIP service is available */
|
||||||
|
#define BTA_AG_SERVICE_CS_VOIP 3 /* Both CS and VoIP services available */
|
||||||
|
/* callheld indicator values */
|
||||||
|
#define BTA_AG_CALLHELD_INACTIVE 0 /* No held calls */
|
||||||
|
#define BTA_AG_CALLHELD_ACTIVE 1 /* Call held and call active */
|
||||||
|
#define BTA_AG_CALLHELD_NOACTIVE 2 /* Call held and no call active */
|
||||||
|
/* signal strength indicator values */
|
||||||
|
#define BTA_AG_ROAMING_INACTIVE 0 /* Phone call inactive */
|
||||||
|
#define BTA_AG_ROAMING_ACTIVE 1 /* Phone call active */
|
||||||
|
/* bearer indicator values */
|
||||||
|
#define BTA_AG_BEARER_WLAN 0 /* WLAN */
|
||||||
|
#define BTA_AG_BEARER_BLUETOOTH 1 /* Bluetooth */
|
||||||
|
#define BTA_AG_BEARER_WIRED 2 /* Wired */
|
||||||
|
#define BTA_AG_BEARER_2G3G 3 /* 2G 3G */
|
||||||
|
#define BTA_AG_BEARER_WIMAX 4 /* WIMAX */
|
||||||
|
#define BTA_AG_BEARER_RES1 5 /* Reserved */
|
||||||
|
#define BTA_AG_BEARER_RES2 6 /* Reserved */
|
||||||
|
#define BTA_AG_BEARER_RES3 7 /* Reserved */
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_IND_RES */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_IND_TYPE type;
|
||||||
|
UINT16 value;
|
||||||
|
} tBTA_AG_IND;
|
||||||
|
|
||||||
|
/* data type for BTA_AgResult() */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char str[BTA_AG_AT_MAX_LEN+1]; /* used for cops,clcc,cnum... */
|
||||||
|
tBTA_AG_IND ind; /* used for indicator type */
|
||||||
|
UINT16 num; /* used for codec state */
|
||||||
|
UINT16 audio_handle; /* used for audio path */
|
||||||
|
UINT16 errcode; /* Valid only if 'ok_flag' is set to BTA_AG_OK_ERROR */
|
||||||
|
UINT8 ok_flag; /* Indicates if response is finished, and if error occurred */
|
||||||
|
BOOLEAN state;
|
||||||
|
} tBTA_AG_RES_DATA;
|
||||||
|
|
||||||
|
/* data associated with most non-AT events */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UINT16 handle;
|
||||||
|
UINT8 app_id;
|
||||||
|
tBTA_AG_STATUS status;
|
||||||
|
} tBTA_AG_HDR;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_REGISTER_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_HDR hdr;
|
||||||
|
UINT16 handle;
|
||||||
|
tBTA_AG_STATUS status;
|
||||||
|
} tBTA_AG_REGISTER;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_OPEN_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_HDR hdr;
|
||||||
|
BD_ADDR bd_addr;
|
||||||
|
tBTA_SERVICE_ID service_id;
|
||||||
|
tBTA_AG_STATUS status;
|
||||||
|
} tBTA_AG_OPEN;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_CLOSE_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_HDR hdr;
|
||||||
|
BD_ADDR bd_addr;
|
||||||
|
} tBTA_AG_CLOSE;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_CONN_EVT */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_HDR hdr;
|
||||||
|
tBTA_AG_PEER_FEAT peer_feat;
|
||||||
|
BD_ADDR bd_addr;
|
||||||
|
tBTA_AG_PEER_CODEC peer_codec;
|
||||||
|
tBTA_AG_CHLD_FEAT chld_feat;
|
||||||
|
} tBTA_AG_CONN;
|
||||||
|
|
||||||
|
/* data associated with AT command event */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tBTA_AG_HDR hdr;
|
||||||
|
BD_ADDR bd_addr;
|
||||||
|
char str[BTA_AG_AT_MAX_LEN+1];
|
||||||
|
UINT16 num; /* voice recognition state*/
|
||||||
|
UINT8 idx; /* call number used by CLCC and CHLD */
|
||||||
|
UINT16 value;
|
||||||
|
} tBTA_AG_VAL;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_CLIP_EVT and BTA_AG_CCWA_EVT*/
|
||||||
|
#define BTA_AG_NUMBER_LEN 32
|
||||||
|
typedef struct {
|
||||||
|
char number[BTA_AG_NUMBER_LEN + 1];
|
||||||
|
} tBTA_AG_NUMBER;
|
||||||
|
|
||||||
|
/* data associated with BTA_HF_CLIENT_OPERATOR_NAME_EVT */
|
||||||
|
#define BTA_AG_COPS_LEN 16
|
||||||
|
typedef struct {
|
||||||
|
char name[BTA_AG_COPS_LEN + 1];
|
||||||
|
} tBTA_AG_COPS;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_AT_RESULT_EVT event */
|
||||||
|
typedef struct {
|
||||||
|
tBTA_AG_AT_RESULT_TYPE type;
|
||||||
|
UINT16 cme;
|
||||||
|
} tBTA_AG_AT_RESULT;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_CLCC_EVT event */
|
||||||
|
typedef struct {
|
||||||
|
UINT32 idx;
|
||||||
|
BOOLEAN inc;
|
||||||
|
UINT8 status;
|
||||||
|
BOOLEAN mpty;
|
||||||
|
BOOLEAN number_present;
|
||||||
|
char number[BTA_AG_NUMBER_LEN + 1];
|
||||||
|
} tBTA_AG_CLCC;
|
||||||
|
|
||||||
|
/* data associated with BTA_AG_CNUM_EVT event */
|
||||||
|
typedef struct {
|
||||||
|
UINT16 service;
|
||||||
|
char number[BTA_AG_NUMBER_LEN + 1];
|
||||||
|
} tBTA_AG_CNUM;
|
||||||
|
|
||||||
|
/* union of data associated with AG callback */
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
tBTA_AG_HDR hdr;
|
||||||
|
tBTA_AG_REGISTER reg;
|
||||||
|
tBTA_AG_OPEN open;
|
||||||
|
tBTA_AG_CLOSE close;
|
||||||
|
tBTA_AG_CONN conn;
|
||||||
|
tBTA_AG_IND ind;
|
||||||
|
tBTA_AG_VAL val;
|
||||||
|
//add
|
||||||
|
tBTA_AG_COPS operator;
|
||||||
|
tBTA_AG_NUMBER number;
|
||||||
|
tBTA_AG_AT_RESULT result;
|
||||||
|
tBTA_AG_CLCC clcc;
|
||||||
|
tBTA_AG_CNUM cnum;
|
||||||
|
} tBTA_AG;
|
||||||
|
|
||||||
|
/* AG callback */
|
||||||
|
typedef void (tBTA_AG_CBACK)(tBTA_AG_EVT event, tBTA_AG *p_data);
|
||||||
|
|
||||||
|
/* AG configuration structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *cind_info;
|
||||||
|
INT32 conn_tout;
|
||||||
|
UINT16 sco_pkt_types;
|
||||||
|
char *chld_val_ecc;
|
||||||
|
char *chld_val;
|
||||||
|
} tBTA_AG_CFG;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** External Function Declarations
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgEnable
|
||||||
|
**
|
||||||
|
** Description Enable the audio gateway service. When the enable
|
||||||
|
** operation is complete the callback function will be
|
||||||
|
** called with a BTA_AG_ENABLE_EVT. This function must
|
||||||
|
** be called before other function in the AG API are
|
||||||
|
** called.
|
||||||
|
**
|
||||||
|
** Returns BTA_SUCCESS if OK, BTA_FAILURE otherwise.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
tBTA_STATUS BTA_AgEnable(tBTA_AG_PARSE_MODE parse_mode, tBTA_AG_CBACK *p_cback);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgDisable
|
||||||
|
**
|
||||||
|
** Description Disable the audio gateway service
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgDisable(void);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgRegister
|
||||||
|
**
|
||||||
|
** Description Register an Audio Gateway service.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgRegister(tBTA_SERVICE_MASK services, tBTA_SEC sec_mask,
|
||||||
|
tBTA_AG_FEAT features, char *p_service_names[], UINT8 app_id);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgDeregister
|
||||||
|
**
|
||||||
|
** Description Deregister an audio gateway service.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgDeregister(UINT16 handle);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgOpen
|
||||||
|
**
|
||||||
|
** Description Opens a connection to a headset or hands-free device.
|
||||||
|
** When connection is open callback function is called
|
||||||
|
** with a BTA_AG_OPEN_EVT. Only the data connection is
|
||||||
|
** opened. The audio connection is not opened.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgOpen(UINT16 handle, BD_ADDR bd_addr, tBTA_SEC sec_mask, tBTA_SERVICE_MASK services);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgClose
|
||||||
|
**
|
||||||
|
** Description Close the current connection to a headset or a handsfree
|
||||||
|
** Any current audio connection will also be closed
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgClose(UINT16 handle);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgAudioOpen
|
||||||
|
**
|
||||||
|
** Description Opens an audio connection to the currently connected
|
||||||
|
** headset or hnadsfree
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgAudioOpen(UINT16 handle);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgAudioClose
|
||||||
|
**
|
||||||
|
** Description Close the currently active audio connection to a headset
|
||||||
|
** or hnadsfree. The data connection remains open
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgAudioClose(UINT16 handle);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgResult
|
||||||
|
**
|
||||||
|
** Description Send an AT result code to a headset or hands-free device.
|
||||||
|
** This function is only used when the AG parse mode is set
|
||||||
|
** to BTA_AG_PARSE.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgResult(UINT16 handle, tBTA_AG_RES result, tBTA_AG_RES_DATA *p_data);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgSetCodec
|
||||||
|
**
|
||||||
|
** Description Specify the codec type to be used for the subsequent
|
||||||
|
** audio connection.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec);
|
||||||
|
|
||||||
|
|
||||||
|
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function BTA_AgCiData
|
||||||
|
**
|
||||||
|
** Description Give an EVT to BTA that tell outgoing data is ready.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void BTA_AgCiData(void);
|
||||||
|
#endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE ) */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
||||||
|
|
||||||
|
#endif /* BTA_HF_API_H */
|
160
components/bt/host/bluedroid/bta/include/bta/bta_ag_co.h
Normal file
160
components/bt/host/bluedroid/bta/include/bta/bta_ag_co.h
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This is the interface file for audio gateway call-out and call-in functions.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef BTA_AG_CIO_H
|
||||||
|
#define BTA_AG_CIO_H
|
||||||
|
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "hci/hci_audio.h"
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_audio_state
|
||||||
|
**
|
||||||
|
** Description This function is called by the AG before the audio connection
|
||||||
|
** is brought up, after it comes up, and after it goes down.
|
||||||
|
**
|
||||||
|
** Parameters handle - handle of the AG instance
|
||||||
|
** state - Audio state
|
||||||
|
** codec - if WBS support is compiled in, codec to going to be used is provided
|
||||||
|
** and when in SCO_STATE_SETUP, BTM_I2SPCMConfig() must be called with
|
||||||
|
** the correct platform parameters.
|
||||||
|
** in the other states codec type should not be ignored
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
void bta_ag_sco_audio_state(UINT16 handle, UINT8 app_id, UINT8 state, tBTA_AG_PEER_CODEC codec);
|
||||||
|
#else
|
||||||
|
void bta_ag_sco_audio_state(UINT16 handle, UINT8 app_id, UINT8 state);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_init
|
||||||
|
**
|
||||||
|
** Description Set default data path for SCO/eSCO.
|
||||||
|
** This callout function is executed by AG when it is
|
||||||
|
** started by calling BTA_AgEnable(). This function can be
|
||||||
|
** used by the phone to initialize audio paths or for other
|
||||||
|
** initialization purposes.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns Void.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
tBTA_HFP_SCO_ROUTE_TYPE bta_ag_sco_co_init(UINT32 rx_bw, UINT32 tx_bw, tBTA_HFP_CODEC_INFO *p_codec_info, UINT8 app_id);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_open
|
||||||
|
**
|
||||||
|
** Description This function is executed by AG when a service level connection
|
||||||
|
** is opened.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sco_co_open(UINT16 handle, tBTM_SCO_AIR_MODE_TYPE air_mode, UINT8 inout_pkt_size, UINT16 event);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_close
|
||||||
|
**
|
||||||
|
** Description This function is called by AG when a service level
|
||||||
|
** connection is closed.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sco_co_close(void);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_out_data
|
||||||
|
**
|
||||||
|
** Description This function is called to send SCO data over HCI.
|
||||||
|
**
|
||||||
|
** Returns number of bytes got from application
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
uint32_t bta_ag_sco_co_out_data(UINT8 *p_buf);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_hf_client_sco_co_in_data
|
||||||
|
**
|
||||||
|
** Description This function is called to send incoming SCO data to application.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_co_tx_write
|
||||||
|
**
|
||||||
|
** Description This function is called by the AG to send data to the
|
||||||
|
** phone when the AG is configured for AT command pass-through.
|
||||||
|
** The implementation of this function must copy the data to
|
||||||
|
** the phones memory.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_co_tx_write(UINT16 handle, UINT8 *p_data, UINT16 len);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_ci_rx_write
|
||||||
|
**
|
||||||
|
** Description This function is called to send data to the AG when the AG
|
||||||
|
** is configured for AT command pass-through. The function
|
||||||
|
** copies data to an event buffer and sends it.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
extern void bta_ag_ci_rx_write(UINT16 handle, char *p_data, UINT16 len);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_ci_slc_ready
|
||||||
|
**
|
||||||
|
** Description This function is called to notify AG that SLC is up at
|
||||||
|
** the application. This funcion is only used when the app
|
||||||
|
** is running in pass-through mode.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
extern void bta_ag_ci_slc_ready(UINT16 handle);
|
||||||
|
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
||||||
|
|
||||||
|
#endif /* BTA_AG_CIO_H */
|
|
@ -57,6 +57,9 @@ btc_dm_cb_t *btc_dm_cb_ptr;
|
||||||
extern bt_status_t btc_av_source_execute_service(BOOLEAN b_enable);
|
extern bt_status_t btc_av_source_execute_service(BOOLEAN b_enable);
|
||||||
extern bt_status_t btc_av_sink_execute_service(BOOLEAN b_enable);
|
extern bt_status_t btc_av_sink_execute_service(BOOLEAN b_enable);
|
||||||
#endif
|
#endif
|
||||||
|
#if BTC_HF_INCLUDED
|
||||||
|
extern bt_status_t btc_hf_execute_service(BOOLEAN b_enable);
|
||||||
|
#endif
|
||||||
#if BTC_HF_CLIENT_INCLUDED
|
#if BTC_HF_CLIENT_INCLUDED
|
||||||
extern bt_status_t btc_hf_client_execute_service(BOOLEAN b_enable);
|
extern bt_status_t btc_hf_client_execute_service(BOOLEAN b_enable);
|
||||||
#endif
|
#endif
|
||||||
|
@ -510,6 +513,11 @@ static bt_status_t btc_in_execute_service_request(tBTA_SERVICE_ID service_id,
|
||||||
btc_av_sink_execute_service(b_enable);
|
btc_av_sink_execute_service(b_enable);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if BTC_HF_INCLUDED
|
||||||
|
case BTA_HFP_SERVICE_ID:
|
||||||
|
btc_hf_execute_service(b_enable);
|
||||||
|
break;
|
||||||
|
#endif /* #if BTC_HF_INCLUDED */
|
||||||
#if BTC_HF_CLIENT_INCLUDED
|
#if BTC_HF_CLIENT_INCLUDED
|
||||||
case BTA_HFP_HS_SERVICE_ID:
|
case BTA_HFP_HS_SERVICE_ID:
|
||||||
btc_hf_client_execute_service(b_enable);
|
btc_hf_client_execute_service(b_enable);
|
||||||
|
|
|
@ -30,6 +30,11 @@
|
||||||
#if (BTA_AV_INCLUDED == TRUE)
|
#if (BTA_AV_INCLUDED == TRUE)
|
||||||
#include "bta/bta_av_api.h"
|
#include "bta/bta_av_api.h"
|
||||||
#endif ///BTA_AV_INCLUDED == TRUE
|
#endif ///BTA_AV_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#endif ///BTA_AG_INCLUDED == TRUE
|
||||||
|
|
||||||
#include "common/bt_defs.h"
|
#include "common/bt_defs.h"
|
||||||
#include "stack/btm_api.h"
|
#include "stack/btm_api.h"
|
||||||
#include "bta/bta_api.h"
|
#include "bta/bta_api.h"
|
||||||
|
@ -121,6 +126,89 @@ const char *dump_rc_pdu(UINT8 pdu)
|
||||||
}
|
}
|
||||||
#endif ///BTA_AV_INCLUDED == TRUE
|
#endif ///BTA_AV_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
const char* dump_hf_conn_state(UINT16 event)
|
||||||
|
{
|
||||||
|
switch(event)
|
||||||
|
{
|
||||||
|
CASE_RETURN_STR(ESP_HF_CONNECTION_STATE_DISCONNECTED)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CONNECTION_STATE_CONNECTING)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CONNECTION_STATE_CONNECTED)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CONNECTION_STATE_SLC_CONNECTED)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CONNECTION_STATE_DISCONNECTING)
|
||||||
|
default:
|
||||||
|
return "UNKNOWN MSG ID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* dump_hf_event(UINT16 event)
|
||||||
|
{
|
||||||
|
switch(event)
|
||||||
|
{
|
||||||
|
CASE_RETURN_STR(BTA_AG_ENABLE_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_REGISTER_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_OPEN_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_CLOSE_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_CONN_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AUDIO_OPEN_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AUDIO_CLOSE_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_SPK_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_MIC_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_CKPD_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_DISABLE_EVT)
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
CASE_RETURN_STR(BTA_AG_WBS_EVT)
|
||||||
|
#endif
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_A_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_D_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_CHLD_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_CHUP_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_CIND_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_VTS_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_BINP_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_BLDN_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_BVRA_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_NREC_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_CNUM_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_BTRH_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_CLCC_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_COPS_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_UNAT_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_CBC_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_BAC_EVT)
|
||||||
|
CASE_RETURN_STR(BTA_AG_AT_BCS_EVT)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "UNKNOWN MSG ID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* dump_hf_call_state(esp_hf_call_status_t call_state)
|
||||||
|
{
|
||||||
|
switch(call_state)
|
||||||
|
{
|
||||||
|
CASE_RETURN_STR(ESP_HF_CALL_STATUS_NO_CALLS)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CALL_STATUS_CALL_IN_PROGRESS)
|
||||||
|
default:
|
||||||
|
return "UNKNOWN CALL STATE";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* dump_hf_call_setup_state(esp_hf_call_setup_status_t call_setup_state)
|
||||||
|
{
|
||||||
|
switch(call_setup_state)
|
||||||
|
{
|
||||||
|
CASE_RETURN_STR(ESP_HF_CALL_SETUP_STATUS_IDLE)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CALL_SETUP_STATUS_INCOMING)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CALL_SETUP_STATUS_OUTGOING_DIALING)
|
||||||
|
CASE_RETURN_STR(ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING)
|
||||||
|
default:
|
||||||
|
return "UNKNOWN CALL SETUP STATE";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
|
||||||
UINT32 devclass2uint(DEV_CLASS dev_class)
|
UINT32 devclass2uint(DEV_CLASS dev_class)
|
||||||
{
|
{
|
||||||
UINT32 cod = 0;
|
UINT32 cod = 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "stack/bt_types.h"
|
#include "stack/bt_types.h"
|
||||||
#include "common/bt_defs.h"
|
#include "common/bt_defs.h"
|
||||||
#include "esp_bt_defs.h"
|
#include "esp_bt_defs.h"
|
||||||
|
#include "esp_hf_defs.h"
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Constants & Macros
|
** Constants & Macros
|
||||||
|
@ -34,9 +35,18 @@ typedef char bdstr_t[18];
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Functions
|
** Functions
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
#if(BTA_AV_INCLUDED == TRUE)
|
||||||
const char *dump_rc_event(UINT8 event);
|
const char *dump_rc_event(UINT8 event);
|
||||||
const char *dump_rc_notification_event_id(UINT8 event_id);
|
const char *dump_rc_notification_event_id(UINT8 event_id);
|
||||||
const char *dump_rc_pdu(UINT8 pdu);
|
const char *dump_rc_pdu(UINT8 pdu);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if(BTA_AG_INCLUDED == TRUE)
|
||||||
|
const char *dump_hf_conn_state(UINT16 event);
|
||||||
|
const char *dump_hf_event(UINT16 event);
|
||||||
|
const char *dump_hf_call_state(esp_hf_call_status_t call_state);
|
||||||
|
const char* dump_hf_call_setup_state(esp_hf_call_setup_status_t call_setup_state);
|
||||||
|
#endif
|
||||||
|
|
||||||
UINT32 devclass2uint(DEV_CLASS dev_class);
|
UINT32 devclass2uint(DEV_CLASS dev_class);
|
||||||
void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
|
void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
|
||||||
|
|
590
components/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c
Normal file
590
components/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c
Normal file
|
@ -0,0 +1,590 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009-2012 Broadcom Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#define LOG_TAG "bt_btc_bta_ag"
|
||||||
|
|
||||||
|
#include "btc_hf_ag.h"
|
||||||
|
#include "bta_ag_int.h"
|
||||||
|
#include "bta/bta_api.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "bta/bta_ag_co.h"
|
||||||
|
#include "bta/bta_dm_co.h"
|
||||||
|
#include "common/bt_target.h"
|
||||||
|
#include "hci/hci_audio.h"
|
||||||
|
#include "osi/allocator.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if (BTA_AG_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CONST
|
||||||
|
********************************************************************************/
|
||||||
|
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||||
|
#include "oi_codec_sbc.h"
|
||||||
|
#include "oi_status.h"
|
||||||
|
#include "sbc_encoder.h"
|
||||||
|
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
#include "sbc_plc.h"
|
||||||
|
typedef struct {
|
||||||
|
bool first_good_frame_found;
|
||||||
|
sbc_plc_state_t plc_state;
|
||||||
|
int16_t sbc_plc_out[SBC_FS];
|
||||||
|
} bta_hf_ct_plc_t;
|
||||||
|
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||||
|
static bta_hf_ct_plc_t bta_hf_ct_plc;
|
||||||
|
#else
|
||||||
|
static bta_hf_ct_plc_t *bta_hf_ct_plc_ptr;
|
||||||
|
#define bta_hf_ct_plc (*bta_hf_ct_plc_ptr)
|
||||||
|
#endif ///HFP_DYNAMIC_MEMORY == FALSE
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
#define HF_SBC_DEC_CONTEXT_DATA_LEN (CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS))
|
||||||
|
#define HF_SBC_DEC_RAW_DATA_SIZE 240
|
||||||
|
#define HF_SBC_ENC_RAW_DATA_SIZE 240
|
||||||
|
|
||||||
|
/* BTA-AG-CO control block to map bdaddr to BTA handle */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
|
||||||
|
OI_UINT32 decoder_context_data[HF_SBC_DEC_CONTEXT_DATA_LEN];
|
||||||
|
OI_INT16 decode_raw_data[HF_SBC_DEC_RAW_DATA_SIZE];
|
||||||
|
|
||||||
|
SBC_ENC_PARAMS encoder;
|
||||||
|
|
||||||
|
UINT8 sequence_number;
|
||||||
|
bool is_bad_frame;
|
||||||
|
bool decode_first_pkt;
|
||||||
|
OI_BYTE decode_msbc_data[BTM_MSBC_FRAME_SIZE];
|
||||||
|
bool encode_first_pkt;
|
||||||
|
OI_BYTE encode_msbc_data[BTM_MSBC_FRAME_SIZE];
|
||||||
|
} bta_ag_co_cb_t;
|
||||||
|
|
||||||
|
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||||
|
static bta_ag_co_cb_t bta_ag_co_cb;
|
||||||
|
#else
|
||||||
|
static bta_ag_co_cb_t *bta_ag_co_cb_ptr;
|
||||||
|
#define bta_ag_co_cb (*bta_ag_co_cb_ptr)
|
||||||
|
#endif /* HFP_DYNAMIC_MEMORY == FALSE */
|
||||||
|
|
||||||
|
static UINT8 hf_air_mode = BTM_SCO_AIR_MODE_TRANSPNT;
|
||||||
|
static UINT8 hf_inout_pkt_size = 0;
|
||||||
|
|
||||||
|
/* =========================================================================
|
||||||
|
* AG pass-through mode handle
|
||||||
|
*===========================================================================*/
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_co_tx_write
|
||||||
|
**
|
||||||
|
** Description This function is called by the AG to send data to the
|
||||||
|
** phone when the AG is configured for AT command pass-through.
|
||||||
|
** The implementation of this function must copy the data to
|
||||||
|
** the phones memory.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_co_tx_write(UINT16 handle, UNUSED_ATTR UINT8 * p_data, UINT16 len)
|
||||||
|
{
|
||||||
|
BTIF_TRACE_DEBUG( "bta_ag_co_tx_write: handle: %d, len: %d", handle, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_ci_rx_write
|
||||||
|
**
|
||||||
|
** Description This function is called to send data to the AG when the AG
|
||||||
|
** is configured for AT command pass-through. The function
|
||||||
|
** copies data to an event buffer and sends it.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
void bta_ag_ci_rx_write(UINT16 handle, char *p_data, UINT16 len)
|
||||||
|
{
|
||||||
|
tBTA_AG_CI_RX_WRITE *p_buf;
|
||||||
|
UINT16 len_remaining = len;
|
||||||
|
char *p_data_area;
|
||||||
|
|
||||||
|
if (len > (BT_DEFAULT_BUFFER_SIZE - sizeof(tBTA_AG_CI_RX_WRITE) - 1)) {
|
||||||
|
len = BT_DEFAULT_BUFFER_SIZE - sizeof(tBTA_AG_CI_RX_WRITE) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len_remaining) {
|
||||||
|
if (len_remaining < len) {
|
||||||
|
len = len_remaining;
|
||||||
|
}
|
||||||
|
if ((p_buf = (tBTA_AG_CI_RX_WRITE *) osi_malloc((UINT16)(sizeof(tBTA_AG_CI_RX_WRITE) + len + 1))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_CI_RX_WRITE_EVT;
|
||||||
|
p_buf->hdr.layer_specific = handle;
|
||||||
|
p_data_area = (char *)(p_buf+1); /* Point to data area after header */
|
||||||
|
strncpy(p_data_area, p_data, len);
|
||||||
|
p_data_area[len] = 0;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
} else {
|
||||||
|
APPL_TRACE_ERROR("ERROR: Unable to allocate buffer to hold AT response code. len=%i", len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
len_remaining-=len;
|
||||||
|
p_data+=len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_ci_slc_ready
|
||||||
|
**
|
||||||
|
** Description This function is called to notify AG that SLC is up at
|
||||||
|
** the application. This funcion is only used when the app
|
||||||
|
** is running in pass-through mode.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
******************************************************************************/
|
||||||
|
void bta_ag_ci_slc_ready(UINT16 handle)
|
||||||
|
{
|
||||||
|
tBTA_AG_DATA *p_buf;
|
||||||
|
if ((p_buf = (tBTA_AG_DATA *)osi_malloc(sizeof(tBTA_AG_DATA))) != NULL) {
|
||||||
|
p_buf->hdr.event = BTA_AG_CI_SLC_READY_EVT;
|
||||||
|
p_buf->hdr.layer_specific = handle;
|
||||||
|
bta_sys_sendmsg(p_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* H2 & DEC
|
||||||
|
********************************************************************************/
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_h2_header
|
||||||
|
**
|
||||||
|
** Description This function is called to fill in H2 header
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_h2_header(UINT16 *p_buf)
|
||||||
|
{
|
||||||
|
// H2: Header with synchronization word and sequence number
|
||||||
|
#define BTA_HF_H2_HEADER 0x0801
|
||||||
|
#define BTA_HF_H2_HEADER_BIT0_MASK (1 << 0)
|
||||||
|
#define BTA_HF_H2_HEADER_BIT1_MASK (1 << 1)
|
||||||
|
#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
|
||||||
|
#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
|
||||||
|
#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
|
||||||
|
#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
|
||||||
|
|
||||||
|
UINT16 h2_header = BTA_HF_H2_HEADER;
|
||||||
|
UINT8 h2_header_sn0 = bta_ag_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT0_MASK;
|
||||||
|
UINT8 h2_header_sn1 = bta_ag_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT1_MASK;
|
||||||
|
h2_header |= (h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET1
|
||||||
|
| h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET2
|
||||||
|
| h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 - 1)
|
||||||
|
| h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 - 1)
|
||||||
|
);
|
||||||
|
bta_ag_co_cb.sequence_number++;
|
||||||
|
*p_buf = h2_header;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_hf_dec_init
|
||||||
|
**
|
||||||
|
** Description Initialize decoding task
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_hf_dec_init(void)
|
||||||
|
{
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
sbc_plc_init(&(bta_hf_ct_plc.plc_state));
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
OI_STATUS status = OI_CODEC_SBC_DecoderReset(&bta_ag_co_cb.decoder_context, bta_ag_co_cb.decoder_context_data,
|
||||||
|
HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE);
|
||||||
|
if (!OI_SUCCESS(status)) {
|
||||||
|
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_hf_enc_init
|
||||||
|
**
|
||||||
|
** Description Initialize encoding task for mSBC
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_hf_enc_init(void)
|
||||||
|
{
|
||||||
|
bta_ag_co_cb.sequence_number = 0;
|
||||||
|
bta_ag_co_cb.decode_first_pkt = true;
|
||||||
|
bta_ag_co_cb.encode_first_pkt = true;
|
||||||
|
bta_ag_co_cb.is_bad_frame = false;
|
||||||
|
|
||||||
|
bta_ag_co_cb.encoder.sbc_mode = SBC_MODE_MSBC;
|
||||||
|
bta_ag_co_cb.encoder.s16NumOfBlocks = 15;
|
||||||
|
bta_ag_co_cb.encoder.s16NumOfSubBands = 8;
|
||||||
|
bta_ag_co_cb.encoder.s16AllocationMethod = SBC_LOUDNESS;
|
||||||
|
bta_ag_co_cb.encoder.s16BitPool = 26;
|
||||||
|
bta_ag_co_cb.encoder.s16ChannelMode = SBC_MONO;
|
||||||
|
bta_ag_co_cb.encoder.s16NumOfChannels = 1;
|
||||||
|
bta_ag_co_cb.encoder.s16SamplingFreq = SBC_sf16000;
|
||||||
|
|
||||||
|
SBC_Encoder_Init(&(bta_ag_co_cb.encoder));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_decode_msbc_frame
|
||||||
|
**
|
||||||
|
** Description This function is called decode a mSBC frame
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad_frame)
|
||||||
|
{
|
||||||
|
OI_STATUS status;
|
||||||
|
const OI_BYTE *zero_signal_frame_data;
|
||||||
|
UINT8 zero_signal_frame_len = BTM_MSBC_FRAME_DATA_SIZE;
|
||||||
|
UINT32 sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
||||||
|
|
||||||
|
if (is_bad_frame) {
|
||||||
|
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
|
||||||
|
} else {
|
||||||
|
status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, (const OI_BYTE **)data,
|
||||||
|
(OI_UINT32 *)length,
|
||||||
|
(OI_INT16 *)bta_ag_co_cb.decode_raw_data,
|
||||||
|
(OI_UINT32 *)&sbc_raw_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
switch(status) {
|
||||||
|
case OI_OK:
|
||||||
|
{
|
||||||
|
bta_hf_ct_plc.first_good_frame_found = TRUE;
|
||||||
|
sbc_plc_good_frame(&(bta_hf_ct_plc.plc_state), (int16_t *)bta_ag_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
case OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA:
|
||||||
|
case OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA:
|
||||||
|
case OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OI_CODEC_SBC_NO_SYNCWORD:
|
||||||
|
case OI_CODEC_SBC_CHECKSUM_MISMATCH:
|
||||||
|
{
|
||||||
|
if (!bta_hf_ct_plc.first_good_frame_found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
zero_signal_frame_data = sbc_plc_zero_signal_frame();
|
||||||
|
sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
||||||
|
status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, &zero_signal_frame_data,
|
||||||
|
(OI_UINT32 *)&zero_signal_frame_len,
|
||||||
|
(OI_INT16 *)bta_ag_co_cb.decode_raw_data,
|
||||||
|
(OI_UINT32 *)&sbc_raw_data_size);
|
||||||
|
sbc_plc_bad_frame(&(bta_hf_ct_plc.plc_state), bta_ag_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
|
||||||
|
APPL_TRACE_DEBUG("bad frame, using PLC to fix it.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OI_STATUS_INVALID_PARAMETERS:
|
||||||
|
{
|
||||||
|
// This caused by corrupt frames.
|
||||||
|
// The codec apparently does not recover from this.
|
||||||
|
// Re-initialize the codec.
|
||||||
|
APPL_TRACE_ERROR("Frame decode error: OI_STATUS_INVALID_PARAMETERS");
|
||||||
|
|
||||||
|
if (!OI_SUCCESS(OI_CODEC_SBC_DecoderReset(&bta_ag_co_cb.decoder_context, bta_ag_co_cb.decoder_context_data,
|
||||||
|
HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE))) {
|
||||||
|
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
APPL_TRACE_ERROR("Frame decode error: %d", status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
if (OI_SUCCESS(status)) {
|
||||||
|
btc_hf_incoming_data_cb_to_app((const uint8_t *)(bta_hf_ct_plc.sbc_plc_out), sbc_raw_data_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* BTA AG SCO CO FUNCITONS
|
||||||
|
********************************************************************************/
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_audio_state
|
||||||
|
**
|
||||||
|
** Description This function is called by the AG before the audio connection
|
||||||
|
** is brought up, after it comes up, and after it goes down.
|
||||||
|
**
|
||||||
|
** Parameters handle - handle of the AG instance
|
||||||
|
** state - Audio state
|
||||||
|
** codec - if WBS support is compiled in, codec to going to be used is provided
|
||||||
|
** and when in SCO_STATE_SETUP, BTM_I2SPCMConfig() must be called with
|
||||||
|
** the correct platform parameters.
|
||||||
|
** in the other states codec type should not be ignored
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
#if (BTM_WBS_INCLUDED == TRUE )
|
||||||
|
void bta_ag_sco_audio_state(UINT16 handle, UINT8 app_id, UINT8 state, tBTA_AG_PEER_CODEC codec)
|
||||||
|
#else
|
||||||
|
void bta_ag_sco_audio_state(UINT16 handle, UINT8 app_id, UINT8 state)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
BTIF_TRACE_DEBUG("bta_ag_sco_audio_state: handle %d, state %d", handle, state);
|
||||||
|
switch (state) {
|
||||||
|
case SCO_STATE_ON:
|
||||||
|
case SCO_STATE_OFF:
|
||||||
|
case SCO_STATE_OFF_TRANSFER:
|
||||||
|
case SCO_STATE_SETUP:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_init
|
||||||
|
**
|
||||||
|
** Description Set default data path for SCO/eSCO.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns Void.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
tBTA_HFP_SCO_ROUTE_TYPE bta_ag_sco_co_init(UINT32 rx_bw, UINT32 tx_bw, tBTA_HFP_CODEC_INFO *p_codec_info, UINT8 app_id)
|
||||||
|
{
|
||||||
|
APPL_TRACE_EVENT("%s rx_bw %d, tx_bw %d, codec %d", __FUNCTION__, rx_bw, tx_bw, p_codec_info->codec_type);
|
||||||
|
return BTA_HFP_SCO_ROUTE_HCI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_open
|
||||||
|
**
|
||||||
|
** Description This function is executed by AG when a service level connection
|
||||||
|
** is opened.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sco_co_open(UINT16 handle, tBTM_SCO_AIR_MODE_TYPE air_mode, UINT8 inout_pkt_size, UINT16 event)
|
||||||
|
{
|
||||||
|
APPL_TRACE_EVENT("%s hdl %x, pkt_sz %u, event %u", __FUNCTION__, handle, inout_pkt_size, event);
|
||||||
|
hf_air_mode = air_mode;
|
||||||
|
hf_inout_pkt_size = inout_pkt_size;
|
||||||
|
|
||||||
|
if (air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
bta_ag_co_cb_ptr = osi_calloc(sizeof(bta_ag_co_cb_t));
|
||||||
|
if (!bta_ag_co_cb_ptr) {
|
||||||
|
APPL_TRACE_ERROR("%s allocate failed", __FUNCTION__);
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
bta_hf_ct_plc_ptr = (bta_hf_ct_plc_t *)osi_calloc(sizeof(bta_hf_ct_plc_t));
|
||||||
|
if (!bta_hf_ct_plc_ptr) {
|
||||||
|
APPL_TRACE_ERROR("%s malloc fail.", __FUNCTION__);
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
bta_hf_dec_init();
|
||||||
|
bta_hf_enc_init();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
return; // Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
error_exit:;
|
||||||
|
hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN;
|
||||||
|
hf_inout_pkt_size = 0;
|
||||||
|
if (bta_ag_co_cb_ptr) {
|
||||||
|
osi_free(bta_ag_co_cb_ptr);
|
||||||
|
bta_ag_co_cb_ptr = NULL;
|
||||||
|
}
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
if (bta_hf_ct_plc_ptr) {
|
||||||
|
osi_free(bta_hf_ct_plc_ptr);
|
||||||
|
bta_hf_ct_plc_ptr = NULL;
|
||||||
|
}
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_close
|
||||||
|
**
|
||||||
|
** Description Nothing but print some log.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sco_co_close(void)
|
||||||
|
{
|
||||||
|
APPL_TRACE_EVENT("%s", __FUNCTION__);
|
||||||
|
if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
sbc_plc_deinit(&(bta_hf_ct_plc.plc_state));
|
||||||
|
bta_hf_ct_plc.first_good_frame_found = FALSE;
|
||||||
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
osi_free(bta_hf_ct_plc_ptr);
|
||||||
|
bta_hf_ct_plc_ptr = NULL;
|
||||||
|
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
osi_free(bta_ag_co_cb_ptr);
|
||||||
|
bta_ag_co_cb_ptr = NULL;
|
||||||
|
#endif /* HFP_DYNAMIC_MEMORY == TRUE */
|
||||||
|
} else {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN;
|
||||||
|
hf_inout_pkt_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_out_data
|
||||||
|
**
|
||||||
|
** Description This function is called to send SCO data over HCI.
|
||||||
|
**
|
||||||
|
** Returns number of bytes got from application
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
uint32_t bta_ag_sco_co_out_data(UINT8 *p_buf)
|
||||||
|
{
|
||||||
|
if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
|
||||||
|
// CVSD
|
||||||
|
uint32_t hf_raw_pkt_size = hf_inout_pkt_size;
|
||||||
|
return btc_hf_outgoing_data_cb_to_app(p_buf, hf_raw_pkt_size);
|
||||||
|
} else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
|
// mSBC
|
||||||
|
if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
|
||||||
|
if (bta_ag_co_cb.encode_first_pkt) {
|
||||||
|
UINT32 size = btc_hf_outgoing_data_cb_to_app((UINT8 *)bta_ag_co_cb.encoder.as16PcmBuffer, HF_SBC_ENC_RAW_DATA_SIZE);
|
||||||
|
if (size != HF_SBC_ENC_RAW_DATA_SIZE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bta_ag_h2_header((UINT16 *)bta_ag_co_cb.encode_msbc_data);
|
||||||
|
bta_ag_co_cb.encoder.pu8Packet = bta_ag_co_cb.encode_msbc_data + 2;
|
||||||
|
|
||||||
|
SBC_Encoder(&bta_ag_co_cb.encoder);
|
||||||
|
memcpy(p_buf, bta_ag_co_cb.encode_msbc_data, hf_inout_pkt_size);
|
||||||
|
bta_ag_co_cb.encode_first_pkt = !bta_ag_co_cb.encode_first_pkt;
|
||||||
|
return hf_inout_pkt_size;
|
||||||
|
} else {
|
||||||
|
memcpy(p_buf, bta_ag_co_cb.encode_msbc_data + hf_inout_pkt_size, hf_inout_pkt_size);
|
||||||
|
bta_ag_co_cb.encode_first_pkt = !bta_ag_co_cb.encode_first_pkt;
|
||||||
|
return hf_inout_pkt_size;
|
||||||
|
}
|
||||||
|
} else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
|
||||||
|
UINT32 size = btc_hf_outgoing_data_cb_to_app((UINT8 *)bta_ag_co_cb.encoder.as16PcmBuffer, HF_SBC_ENC_RAW_DATA_SIZE);
|
||||||
|
if (size != HF_SBC_ENC_RAW_DATA_SIZE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bta_ag_h2_header((UINT16 *)p_buf);
|
||||||
|
bta_ag_co_cb.encoder.pu8Packet = p_buf + 2;
|
||||||
|
|
||||||
|
SBC_Encoder(&bta_ag_co_cb.encoder);
|
||||||
|
return hf_inout_pkt_size;
|
||||||
|
} else {
|
||||||
|
//Never run to here.
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_ag_sco_co_in_data
|
||||||
|
**
|
||||||
|
** Description This function is called to send incoming SCO data to application.
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
||||||
|
{
|
||||||
|
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||||
|
UINT8 pkt_size = 0;
|
||||||
|
STREAM_SKIP_UINT16(p);
|
||||||
|
STREAM_TO_UINT8(pkt_size, p);
|
||||||
|
|
||||||
|
if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
|
||||||
|
// CVSD
|
||||||
|
if(status != BTM_SCO_DATA_CORRECT) {
|
||||||
|
APPL_TRACE_DEBUG("%s: not a correct frame(%d).", __func__, status);
|
||||||
|
}
|
||||||
|
btc_hf_incoming_data_cb_to_app(p, pkt_size);
|
||||||
|
} else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
|
// mSBC
|
||||||
|
UINT8 *data = NULL;
|
||||||
|
if (pkt_size != hf_inout_pkt_size) {
|
||||||
|
bta_ag_co_cb.is_bad_frame = true;
|
||||||
|
}
|
||||||
|
if (status != BTM_SCO_DATA_CORRECT) {
|
||||||
|
bta_ag_co_cb.is_bad_frame = true;
|
||||||
|
}
|
||||||
|
if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
|
||||||
|
if (bta_ag_co_cb.decode_first_pkt) {
|
||||||
|
if (!bta_ag_co_cb.is_bad_frame) {
|
||||||
|
memcpy(bta_ag_co_cb.decode_msbc_data, p, pkt_size);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!bta_ag_co_cb.is_bad_frame) {
|
||||||
|
memcpy(bta_ag_co_cb.decode_msbc_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
|
||||||
|
}
|
||||||
|
data = bta_ag_co_cb.decode_msbc_data;
|
||||||
|
bta_ag_decode_msbc_frame(&data, &pkt_size, bta_ag_co_cb.is_bad_frame);
|
||||||
|
bta_ag_co_cb.is_bad_frame = false;
|
||||||
|
}
|
||||||
|
bta_ag_co_cb.decode_first_pkt = !bta_ag_co_cb.decode_first_pkt;
|
||||||
|
} else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
|
||||||
|
data = p;
|
||||||
|
bta_ag_decode_msbc_frame(&data, &pkt_size, bta_ag_co_cb.is_bad_frame);
|
||||||
|
bta_ag_co_cb.is_bad_frame = false;
|
||||||
|
} else {
|
||||||
|
//Never run to here.
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
|
||||||
|
#endif /* #if (BTA_AG_INCLUDED == TRUE) */
|
1466
components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c
Normal file
1466
components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c
Normal file
File diff suppressed because it is too large
Load diff
259
components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h
Normal file
259
components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* Filename: btc_hf_ag.h
|
||||||
|
*
|
||||||
|
* Description: Main API header file for all BTC HF AG functions accessed
|
||||||
|
* from internal stack.
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __BTC_HF_AG_H__
|
||||||
|
#define __BTC_HF_AG_H__
|
||||||
|
|
||||||
|
#include "common/bt_target.h"
|
||||||
|
#include "btc/btc_task.h"
|
||||||
|
#include "btc/btc_common.h"
|
||||||
|
#include "bta/bta_ag_api.h"
|
||||||
|
#include "esp_hf_ag_api.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if (BTC_HF_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Type Defs
|
||||||
|
********************************************************************************/
|
||||||
|
/* btc_hf_act_t */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
//INIT
|
||||||
|
BTC_HF_INIT_EVT,
|
||||||
|
BTC_HF_DEINIT_EVT,
|
||||||
|
BTC_HF_CONNECT_EVT,
|
||||||
|
BTC_HF_DISCONNECT_EVT,
|
||||||
|
BTC_HF_CONNECT_AUDIO_EVT,
|
||||||
|
BTC_HF_DISCONNECT_AUDIO_EVT,
|
||||||
|
BTC_HF_VRA_EVT,
|
||||||
|
BTC_HF_VOLUME_CONTROL_EVT,
|
||||||
|
//AT_RESPONSE
|
||||||
|
BTC_HF_UNAT_RESPONSE_EVT,
|
||||||
|
BTC_HF_CME_ERR_EVT,
|
||||||
|
BTC_HF_IND_NOTIFICATION_EVT,
|
||||||
|
BTC_HF_CIND_RESPONSE_EVT,
|
||||||
|
BTC_HF_COPS_RESPONSE_EVT,
|
||||||
|
BTC_HF_CLCC_RESPONSE_EVT,
|
||||||
|
BTC_HF_CNUM_RESPONSE_EVT,
|
||||||
|
BTC_HF_INBAND_RING_EVT,
|
||||||
|
//CALL_HANDLE
|
||||||
|
BTC_HF_AC_INCALL_EVT,
|
||||||
|
BTC_HF_RJ_INCALL_EVT,
|
||||||
|
BTC_HF_OUT_CALL_EVT,
|
||||||
|
BTC_HF_END_CALL_EVT,
|
||||||
|
//REG
|
||||||
|
BTC_HF_REGISTER_DATA_CALLBACK_EVT
|
||||||
|
} btc_hf_act_t;
|
||||||
|
|
||||||
|
/* btc_hf_args_t */
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
// BTC_HF_INIT_EVT
|
||||||
|
bt_bdaddr_t init;
|
||||||
|
|
||||||
|
//BTC_HF_DEINIT_EVT
|
||||||
|
bt_bdaddr_t deinit;
|
||||||
|
|
||||||
|
// BTC_HF_CONNECT_EVT
|
||||||
|
bt_bdaddr_t connect;
|
||||||
|
|
||||||
|
// BTC_HF_DISCONNECT_EVT
|
||||||
|
bt_bdaddr_t disconnect;
|
||||||
|
|
||||||
|
// BTC_HF_CONNECT_AUDIO_EVT
|
||||||
|
bt_bdaddr_t connect_audio;
|
||||||
|
|
||||||
|
// BTC_HF_DISCONNECT_AUDIO_EVT
|
||||||
|
bt_bdaddr_t disconnect_audio;
|
||||||
|
|
||||||
|
//BTC_HF_VRA_EVT
|
||||||
|
struct vra_param {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
esp_hf_vr_state_t value;
|
||||||
|
} vra_rep;
|
||||||
|
|
||||||
|
// BTC_HF_VOLUME_CONTROL_EVT
|
||||||
|
struct volcon_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
esp_hf_volume_control_target_t target_type;
|
||||||
|
int volume;
|
||||||
|
} volcon;
|
||||||
|
|
||||||
|
//BTC_HF_UNAT_RESPONSE_EVT
|
||||||
|
struct unat_param {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
char *unat;
|
||||||
|
} unat_rep;
|
||||||
|
|
||||||
|
//BTC_HF_CME_ERR_EVT
|
||||||
|
struct at_ok_err_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
esp_hf_at_response_code_t response_code;
|
||||||
|
esp_hf_cme_err_t error_code;
|
||||||
|
} ext_at;
|
||||||
|
|
||||||
|
// BTC_HF_IND_NOTIFICATION_EVT
|
||||||
|
struct indchange_status {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
esp_hf_call_status_t call_state;
|
||||||
|
esp_hf_call_setup_status_t call_setup_state;
|
||||||
|
esp_hf_network_state_t ntk_state;
|
||||||
|
int signal;
|
||||||
|
} ind_change;
|
||||||
|
|
||||||
|
//BTC_HF_CIND_RESPONSE_EVT
|
||||||
|
struct cind_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
esp_hf_call_status_t call_state;
|
||||||
|
esp_hf_call_setup_status_t call_setup_state;
|
||||||
|
esp_hf_network_state_t ntk_state;
|
||||||
|
int signal;
|
||||||
|
esp_hf_roaming_status_t roam;
|
||||||
|
int batt_lev;
|
||||||
|
esp_hf_call_held_status_t call_held_state;
|
||||||
|
} cind_rep;
|
||||||
|
|
||||||
|
//BTC_HF_COPS_RESPONSE_EVT
|
||||||
|
struct cops_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
char *name;
|
||||||
|
} cops_rep;
|
||||||
|
|
||||||
|
// BTC_HF_CLCC_RESPONSE_EVT
|
||||||
|
struct clcc_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
int index;
|
||||||
|
esp_hf_current_call_direction_t dir;
|
||||||
|
esp_hf_current_call_status_t current_call_state;
|
||||||
|
esp_hf_current_call_mode_t mode;
|
||||||
|
esp_hf_current_call_mpty_type_t mpty;
|
||||||
|
char *number;
|
||||||
|
esp_hf_call_addr_type_t type;
|
||||||
|
} clcc_rep;
|
||||||
|
|
||||||
|
// BTC_HF_CNUM_RESPONSE_EVT
|
||||||
|
struct cnum_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
char *number;
|
||||||
|
esp_hf_subscriber_service_type_t type;
|
||||||
|
} cnum_rep;
|
||||||
|
|
||||||
|
//BTC_HF_NREC_RESPONSE_EVT
|
||||||
|
bt_bdaddr_t nrec_rep;
|
||||||
|
|
||||||
|
//BTC_HF_VTC_RESPONSE_EVT
|
||||||
|
struct bts_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
char *code;
|
||||||
|
} vts_rep;
|
||||||
|
|
||||||
|
//BTC_HF_INBAND_RING_EVT
|
||||||
|
struct bsir_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
esp_hf_in_band_ring_state_t state;
|
||||||
|
} bsir;
|
||||||
|
|
||||||
|
// BTC_HF_AC_INCALL_EVT
|
||||||
|
// BTC_HF_RJ_INCALL_EVT
|
||||||
|
// BTC_HF_OUT_CALL_EVT
|
||||||
|
// BTC_HF_END_CALL_EVT
|
||||||
|
struct phone_args {
|
||||||
|
bt_bdaddr_t remote_addr;
|
||||||
|
int num_active;
|
||||||
|
int num_held;
|
||||||
|
esp_hf_call_status_t call_state;
|
||||||
|
esp_hf_call_setup_status_t call_setup_state;
|
||||||
|
char *number;
|
||||||
|
esp_hf_call_addr_type_t call_addr_type;
|
||||||
|
} phone;
|
||||||
|
|
||||||
|
// BTC_HF_REGISTER_DATA_CALLBACK_EVT
|
||||||
|
struct reg_data_callback {
|
||||||
|
esp_hf_incoming_data_cb_t recv;
|
||||||
|
esp_hf_outgoing_data_cb_t send;
|
||||||
|
} reg_data_cb;
|
||||||
|
|
||||||
|
} btc_hf_args_t;
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
** Local definitions
|
||||||
|
************************************************************************************/
|
||||||
|
/* Number of BTC-HF-AG control blocks */
|
||||||
|
#define BTC_HF_NUM_CB 1
|
||||||
|
|
||||||
|
/* Handsfree AG app ids for service registration */
|
||||||
|
/* APP ID definition*/
|
||||||
|
#define BTC_HF_ID_1 0
|
||||||
|
|
||||||
|
#if HFP_DYNAMIC_MEMORY == TRUE
|
||||||
|
extern hf_local_param_t *hf_local_param_ptr;
|
||||||
|
#define hf_local_param (*hf_local_param_ptr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BTC-AG control block to map bdaddr to BTA handle */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
bool initialized;
|
||||||
|
UINT16 handle;
|
||||||
|
bt_bdaddr_t connected_bda;
|
||||||
|
tBTA_AG_PEER_FEAT peer_feat;
|
||||||
|
tBTA_AG_CHLD_FEAT chld_feat;
|
||||||
|
struct timespec call_end_timestamp;
|
||||||
|
struct timespec connected_timestamp;
|
||||||
|
esp_hf_connection_state_t connection_state;
|
||||||
|
esp_hf_vr_state_t vr_state;
|
||||||
|
int num_active;
|
||||||
|
int num_held;
|
||||||
|
esp_hf_call_status_t call_state;
|
||||||
|
esp_hf_call_setup_status_t call_setup_state;
|
||||||
|
} btc_hf_cb_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int hf_idx;
|
||||||
|
UINT32 btc_hf_features;
|
||||||
|
btc_hf_cb_t btc_hf_cb;
|
||||||
|
esp_hf_incoming_data_cb_t btc_hf_incoming_data_cb;
|
||||||
|
esp_hf_outgoing_data_cb_t btc_hf_outgoing_data_cb;
|
||||||
|
} hf_local_param_t;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** BTC HF AG Handle Hub
|
||||||
|
********************************************************************************/
|
||||||
|
void btc_hf_call_handler(btc_msg_t *msg); // act the cmd from esp-application
|
||||||
|
|
||||||
|
void btc_hf_cb_handler(btc_msg_t *msg); //handle the event from bta
|
||||||
|
|
||||||
|
void btc_hf_incoming_data_cb_to_app(const uint8_t *data, uint32_t len);
|
||||||
|
|
||||||
|
uint32_t btc_hf_outgoing_data_cb_to_app(uint8_t *data, uint32_t len);
|
||||||
|
|
||||||
|
void btc_hf_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||||
|
|
||||||
|
void btc_hf_arg_deep_free(btc_msg_t *msg);
|
||||||
|
|
||||||
|
#endif // BTC_HF_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#endif /* __BTC_HF_AG_H__ */
|
||||||
|
|
|
@ -53,7 +53,14 @@
|
||||||
#define UC_BT_SPP_ENABLED FALSE
|
#define UC_BT_SPP_ENABLED FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//HFP
|
//HFP(AG)
|
||||||
|
#ifdef CONFIG_BT_HFP_AG_ENABLE
|
||||||
|
#define UC_BT_HFP_AG_ENABLED CONFIG_BT_HFP_AG_ENABLE
|
||||||
|
#else
|
||||||
|
#define UC_BT_HFP_AG_ENABLED FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//HFP(Client)
|
||||||
#ifdef CONFIG_BT_HFP_CLIENT_ENABLE
|
#ifdef CONFIG_BT_HFP_CLIENT_ENABLE
|
||||||
#define UC_BT_HFP_CLIENT_ENABLED CONFIG_BT_HFP_CLIENT_ENABLE
|
#define UC_BT_HFP_CLIENT_ENABLED CONFIG_BT_HFP_CLIENT_ENABLE
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -80,6 +80,27 @@
|
||||||
#define BTC_SPP_INCLUDED TRUE
|
#define BTC_SPP_INCLUDED TRUE
|
||||||
#endif /* UC_BT_SPP_ENABLED */
|
#endif /* UC_BT_SPP_ENABLED */
|
||||||
|
|
||||||
|
#if (UC_BT_HFP_AG_ENABLED == TRUE)
|
||||||
|
#define BTC_HF_INCLUDED TRUE
|
||||||
|
#define BTA_AG_INCLUDED TRUE
|
||||||
|
#define PLC_INCLUDED TRUE
|
||||||
|
#ifndef RFCOMM_INCLUDED
|
||||||
|
#define RFCOMM_INCLUDED TRUE
|
||||||
|
#endif
|
||||||
|
#ifndef BTM_SCO_INCLUDED
|
||||||
|
#define BTM_SCO_INCLUDED TRUE
|
||||||
|
#endif
|
||||||
|
#ifndef BTM_MAX_SCO_LINKS
|
||||||
|
#define BTM_MAX_SCO_LINKS (1)
|
||||||
|
#endif
|
||||||
|
#ifndef SBC_DEC_INCLUDED
|
||||||
|
#define SBC_DEC_INCLUDED TRUE
|
||||||
|
#endif
|
||||||
|
#ifndef SBC_ENC_INCLUDED
|
||||||
|
#define SBC_ENC_INCLUDED TRUE
|
||||||
|
#endif
|
||||||
|
#endif /* UC_BT_HFP_AG_ENABLED */
|
||||||
|
|
||||||
#if (UC_BT_HFP_CLIENT_ENABLED == TRUE)
|
#if (UC_BT_HFP_CLIENT_ENABLED == TRUE)
|
||||||
#define BTC_HF_CLIENT_INCLUDED TRUE
|
#define BTC_HF_CLIENT_INCLUDED TRUE
|
||||||
#define BTA_HF_INCLUDED TRUE
|
#define BTA_HF_INCLUDED TRUE
|
||||||
|
|
|
@ -215,7 +215,7 @@ static void btm_esco_conn_rsp (UINT16 sco_inx, UINT8 hci_status, BD_ADDR bda,
|
||||||
#if BTM_SCO_HCI_INCLUDED == TRUE
|
#if BTM_SCO_HCI_INCLUDED == TRUE
|
||||||
void btm_sco_process_num_bufs (UINT16 num_lm_sco_bufs)
|
void btm_sco_process_num_bufs (UINT16 num_lm_sco_bufs)
|
||||||
{
|
{
|
||||||
BTM_TRACE_ERROR("%s, %d", __FUNCTION__, num_lm_sco_bufs);
|
BTM_TRACE_DEBUG("%s, %d", __FUNCTION__, num_lm_sco_bufs);
|
||||||
btm_cb.sco_cb.num_lm_sco_bufs = btm_cb.sco_cb.xmit_window_size = num_lm_sco_bufs;
|
btm_cb.sco_cb.num_lm_sco_bufs = btm_cb.sco_cb.xmit_window_size = num_lm_sco_bufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,7 @@ static void btu_hci_msg_process(void *param)
|
||||||
case BT_EVT_TO_BTU_HCI_SCO:
|
case BT_EVT_TO_BTU_HCI_SCO:
|
||||||
#if BTM_SCO_INCLUDED == TRUE
|
#if BTM_SCO_INCLUDED == TRUE
|
||||||
btm_route_sco_data (p_msg);
|
btm_route_sco_data (p_msg);
|
||||||
|
osi_free(p_msg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue