component/bt: modify a2dp APIs to post event to BTC task

This commit is contained in:
wangmengyang 2017-03-07 21:15:54 +08:00
parent cfb18ba537
commit af13acdc29
5 changed files with 186 additions and 73 deletions

View File

@ -0,0 +1,113 @@
// Copyright 2015-2016 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 <string.h>
#include "esp_err.h"
#include "esp_a2dp_api.h"
#include "esp_bt_main.h"
#include "btc_manage.h"
#include "btc_av.h"
esp_err_t esp_a2d_register_callback(esp_a2d_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_A2DP, callback);
return ESP_OK;
}
esp_err_t esp_a2d_sink_init(void)
{
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_A2DP;
msg.act = BTC_AV_SINK_API_INIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_sink_deinit(void)
{
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_A2DP;
msg.act = BTC_AV_SINK_API_DEINIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_av_args_t arg;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_CONNECT_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
/* Switch to BTC context */
memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_av_args_t arg;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_DISCONNECT_REQ_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
// CHECK_BTAV_INIT(); // todo: move this function
memcpy(&(arg.disconnect), remote_bda, sizeof(bt_bdaddr_t));
/* Switch to BTC context */
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

View File

@ -186,8 +186,12 @@ esp_err_t esp_a2d_sink_init(void);
*
* @brief This function is called to deinit and free the resources for A2DP sink module
*
* @return
* - ESP_OK: success
* - ESP_FAIL: others
*
*/
void esp_a2d_sink_deinit(void);
esp_err_t esp_a2d_sink_deinit(void);
/**

View File

@ -183,6 +183,11 @@ tBTA_SERVICE_MASK btc_get_enabled_services_mask(void)
return btc_enabled_services;
}
void btc_clear_services_mask(void)
{
btc_enabled_services = 0;
}
static bt_status_t btc_in_execute_service_request(tBTA_SERVICE_ID service_id,
BOOLEAN b_enable)
{
@ -241,13 +246,23 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
LOG_DEBUG("btc_dm_upstreams_cback ev: %d\n", msg->act);
switch (msg->act) {
case BTA_DM_ENABLE_EVT:
case BTA_DM_ENABLE_EVT: {
btc_clear_services_mask();
btc_storage_load_bonded_devices();
btc_enable_bluetooth_evt(p_data->enable.status);
break;
case BTA_DM_DISABLE_EVT:
}
case BTA_DM_DISABLE_EVT: {
tBTA_SERVICE_MASK service_mask = btc_get_enabled_services_mask();
for (int i = 0; i <= BTA_MAX_SERVICE_ID; i++) {
if (service_mask &
(tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i))) {
btc_in_execute_service_request(i, FALSE);
}
}
btc_disable_bluetooth_evt();
break;
}
case BTA_DM_PIN_REQ_EVT:
break;
case BTA_DM_AUTH_CMPL_EVT:

View File

@ -37,6 +37,7 @@
#include "btu.h"
#include "bt_utils.h"
#include "btc_common.h"
#include "btc_manage.h"
/*****************************************************************************
** Constants & Macros
@ -84,19 +85,9 @@ typedef struct {
/*****************************************************************************
** Static variables
******************************************************************************/
static esp_a2d_cb_t bt_av_sink_callback = NULL;
static btc_av_cb_t btc_av_cb = {0};
static TIMER_LIST_ENT tle_av_open_on_rc;
// TODO: need protection against race
#define BTC_A2D_CB_TO_APP(_event, _param) do { \
if (bt_av_sink_callback) { \
bt_av_sink_callback(_event, _param); \
} \
} while (0)
/* both interface and media task needs to be ready to alloc incoming request */
#define CHECK_BTAV_INIT() if (btc_av_cb.sm_handle == NULL)\
{\
@ -145,6 +136,13 @@ extern tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
/*****************************************************************************
** Local helper functions
******************************************************************************/
static inline void btc_a2d_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
{
esp_a2d_cb_t btc_a2d_cb = (esp_a2d_cb_t)btc_profile_cb_get(BTC_PID_A2DP);
if (btc_a2d_cb) {
btc_a2d_cb(event, param);
}
}
static const char *dump_av_sm_state_name(btc_av_state_t state)
{
@ -241,7 +239,7 @@ static void btc_report_connection_state(esp_a2d_connection_state_t state, bt_bda
param.conn_stat.disc_rsn = (disc_rsn == 0) ? ESP_A2D_DISC_RSN_NORMAL :
ESP_A2D_DISC_RSN_ABNORMAL;
}
BTC_A2D_CB_TO_APP(ESP_A2D_CONNECTION_STATE_EVT, &param);
btc_a2d_cb_to_app(ESP_A2D_CONNECTION_STATE_EVT, &param);
}
static void btc_report_audio_state(esp_a2d_audio_state_t state, bt_bdaddr_t *bd_addr)
@ -253,7 +251,7 @@ static void btc_report_audio_state(esp_a2d_audio_state_t state, bt_bdaddr_t *bd_
if (bd_addr) {
memcpy(param.audio_stat.remote_bda, bd_addr, sizeof(esp_bd_addr_t));
}
BTC_A2D_CB_TO_APP(ESP_A2D_AUDIO_STATE_EVT, &param);
btc_a2d_cb_to_app(ESP_A2D_AUDIO_STATE_EVT, &param);
}
/*****************************************************************************
@ -423,7 +421,7 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
esp_a2d_cb_param_t param;
memcpy(param.audio_cfg.remote_bda, &btc_av_cb.peer_bda, sizeof(esp_bd_addr_t));
memcpy(&param.audio_cfg.mcc, p_data, sizeof(esp_a2d_mcc_t));
BTC_A2D_CB_TO_APP(ESP_A2D_AUDIO_CFG_EVT, &param);
btc_a2d_cb_to_app(ESP_A2D_AUDIO_CFG_EVT, &param);
}
} break;
@ -953,22 +951,6 @@ bt_status_t btc_av_init()
return BT_STATUS_SUCCESS;
}
/**
*
* Function register A2DP callback
*
* Description Initializes the AV interface for sink mode
*
* Returns bt_status_t
*
*/
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
{
// TODO: need protection against race
bt_av_sink_callback = callback;
return ESP_OK;
}
/*******************************************************************************
**
** Function init_sink
@ -978,13 +960,13 @@ esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
** Returns bt_status_t
**
*******************************************************************************/
esp_err_t esp_a2d_sink_init(void)
bt_status_t btc_a2d_sink_init(void)
{
LOG_INFO("%s()\n", __func__);
bt_status_t status = btc_av_init();
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
return status;
}
/*******************************************************************************
@ -1009,38 +991,14 @@ static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
return BT_STATUS_SUCCESS;
}
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
bt_status_t btc_a2d_sink_connect(bt_bdaddr_t* remote_bda)
{
LOG_INFO("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
bt_status_t stat;
bt_bdaddr_t bd_addr;
memcpy(&bd_addr, remote_bda, sizeof(bt_bdaddr_t));
stat = btc_queue_connect(UUID_SERVCLASS_AUDIO_SINK, &bd_addr, connect_int);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
return btc_queue_connect(UUID_SERVCLASS_AUDIO_SINK, remote_bda, connect_int);
}
esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
{
bt_status_t stat;
btc_av_args_t arg;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_DISCONNECT_REQ_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
LOG_INFO("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
memcpy(&(arg.disconnect), remote_bda, sizeof(bt_bdaddr_t));
/* Switch to BTC context */
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
/*******************************************************************************
**
** Function cleanup
@ -1050,7 +1008,7 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
** Returns None
**
*******************************************************************************/
static void cleanup(void)
static void btc_a2d_sink_deinit(void)
{
LOG_INFO("%s\n", __FUNCTION__);
@ -1066,16 +1024,6 @@ static void cleanup(void)
btc_av_cb.sm_handle = NULL;
}
void esp_a2d_sink_deinit(void)
{
LOG_INFO("%s\n", __FUNCTION__);
if (bt_av_sink_callback) {
bt_av_sink_callback = NULL;
cleanup();
}
}
/*******************************************************************************
**
** Function btc_av_get_sm_handle
@ -1264,6 +1212,30 @@ void btc_av_clear_remote_suspend_flag(void)
void btc_a2dp_evt_handler(btc_msg_t *msg)
{
btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (void *)(msg->arg));
if (msg->act < BTC_AV_MAX_SM_EVT) {
btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (void *)(msg->arg));
} else {
btc_av_args_t *arg = (btc_av_args_t *)(msg->arg);
switch (msg->act) {
case BTC_AV_SINK_API_INIT_EVT: {
btc_a2d_sink_init();
// todo: callback to application
break;
}
case BTC_AV_SINK_API_DEINIT_EVT: {
btc_a2d_sink_deinit();
// todo: callback to application
break;
}
case BTC_AV_SINK_API_CONNECT_EVT: {
btc_a2d_sink_connect(&arg->connect);
// todo: callback to application
break;
}
default:
LOG_WARN("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
}
}
btc_av_event_free_data(msg->act, msg->arg);
}

View File

@ -42,15 +42,24 @@ typedef enum {
BTC_AV_START_STREAM_REQ_EVT,
BTC_AV_STOP_STREAM_REQ_EVT,
BTC_AV_SUSPEND_STREAM_REQ_EVT,
BTC_AV_SINK_CONFIG_REQ_EVT
BTC_AV_SINK_CONFIG_REQ_EVT,
BTC_AV_MAX_SM_EVT
} btc_av_sm_event_t;
typedef enum {
BTC_AV_SINK_API_INIT_EVT = BTC_AV_MAX_SM_EVT + 1,
BTC_AV_SINK_API_DEINIT_EVT,
BTC_AV_SINK_API_CONNECT_EVT,
} btc_av_act_t;
/* btc_av_args_t */
typedef union {
// BTC_AV_SINK_CONFIG_REQ_EVT
esp_a2d_mcc_t mcc;
// BTC_AV_DISCONNECT_REQ_EVT
bt_bdaddr_t disconnect;
// BTC_AV_SINK_API_CONNECT_EVT
bt_bdaddr_t connect;
// Event set--tBTA_AV_EVT
tBTA_AV data;
} btc_av_args_t;