Merge branch 'bugfix/spp_data_send_delay' into 'master'

Add API to config QoS

See merge request espressif/esp-idf!9493
This commit is contained in:
Jiang Jiang Jian 2021-01-05 10:32:51 +08:00
commit e784469966
15 changed files with 241 additions and 7 deletions

View File

@ -96,6 +96,7 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/bta/dm/bta_dm_main.c"
"host/bluedroid/bta/dm/bta_dm_pm.c"
"host/bluedroid/bta/dm/bta_dm_sco.c"
"host/bluedroid/bta/dm/bta_dm_qos.c"
"host/bluedroid/bta/gatt/bta_gatt_common.c"
"host/bluedroid/bta/gatt/bta_gattc_act.c"
"host/bluedroid/bta/gatt/bta_gattc_api.c"

View File

@ -410,4 +410,21 @@ esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda)
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_SET_QOS;
memcpy(&arg.set_qos.bda, remote_bda, sizeof(bt_bdaddr_t));
arg.set_qos.t_poll = t_poll;
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* #if BTC_GAP_BT_INCLUDED == TRUE */

View File

@ -222,6 +222,7 @@ typedef enum {
ESP_BT_GAP_READ_REMOTE_NAME_EVT, /*!< read Remote Name event */
ESP_BT_GAP_MODE_CHG_EVT,
ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< remove bond device complete event */
ESP_BT_GAP_QOS_CMPL_EVT, /*!< QOS complete event */
ESP_BT_GAP_EVT_MAX,
} esp_bt_gap_cb_event_t;
@ -364,6 +365,16 @@ typedef union {
esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */
}remove_bond_dev_cmpl; /*!< Event parameter of ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT */
/**
* @brief ESP_BT_GAP_QOS_CMPL_EVT
*/
struct qos_cmpl_param {
esp_bt_status_t stat; /*!< QoS status */
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
uint32_t t_poll; /*!< poll interval, the maximum time between transmissions
which from the master to a particular slave on the ACL
logical transport. unit is 0.625ms. */
} qos_cmpl; /*!< QoS complete parameter struct */
} esp_bt_gap_cb_param_t;
/**
@ -720,6 +731,21 @@ esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels);
*/
esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda);
/**
* @brief Config Quality of service
*
* @param[in] remote_bda: The remote device's address
* @param[in] t_poll: Poll interval, the maximum time between transmissions
which from the master to a particular slave on the ACL
logical transport. unit is 0.625ms
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - other : failed
*
*/
esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll);
#ifdef __cplusplus
}
#endif

View File

@ -78,6 +78,10 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
bta_dm_pm_btm_status, /* BTA_DM_PM_BTM_STATUS_EVT */
bta_dm_pm_timer, /* BTA_DM_PM_TIMER_EVT */
#endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */
#if (BTA_DM_QOS_INCLUDED == TRUE)
/* Quality of Service set events */
bta_dm_set_qos, /* BTA_DM_API_QOS_SET_EVT */
#endif /* #if (BTA_DM_QOS_INCLUDED == TRUE) */
/* simple pairing events */
#if (SMP_INCLUDED == TRUE)
bta_dm_confirm, /* BTA_DM_API_CONFIRM_EVT */

View File

@ -0,0 +1,68 @@
/******************************************************************************
*
* 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 action functions for QoS state
* machine.
*
******************************************************************************/
#include "bta/bta_sys.h"
#include "bta/bta_api.h"
#include "bta_dm_int.h"
#include "stack/btm_api.h"
#include "osi/allocator.h"
#if (BTA_DM_QOS_INCLUDED == TRUE)
void bta_dm_set_qos(tBTA_DM_MSG *p_data)
{
FLOW_SPEC p_flow = {
.qos_flags = 0, /* TBD */
.service_type = GUARANTEED, /* see below */
.token_rate = 0, /* bytes/second */
.token_bucket_size = 0, /* bytes */
.peak_bandwidth = 0, /* bytes/second */
.latency = 625 * p_data->qos_set.t_poll, /* microseconds */
.delay_variation = 0xFFFFFFFF /* microseconds */
};
tBTM_STATUS status = BTM_SetQoS (p_data->qos_set.bd_addr, &p_flow, p_data->qos_set.p_cb);
if(status != BTM_CMD_STARTED) {
APPL_TRACE_ERROR("%s ERROR: 0x%x\n", __func__, status);
}
}
void BTA_DmSetQos(BD_ADDR bd_addr, UINT32 t_poll, tBTM_CMPL_CB *p_cb)
{
tBTA_DM_API_QOS_SET *p_msg;
if ((p_msg = (tBTA_DM_API_QOS_SET *) osi_malloc(sizeof(tBTA_DM_API_QOS_SET))) != NULL) {
p_msg->hdr.event = BTA_DM_API_QOS_SET_EVT;
bdcpy(p_msg->bd_addr, bd_addr);
p_msg->t_poll = t_poll;
p_msg->p_cb = p_cb;
bta_sys_sendmsg(p_msg);
}
}
#endif /// (BTA_DM_QOS_INCLUDED == TRUE)

View File

@ -74,6 +74,10 @@ enum {
BTA_DM_PM_BTM_STATUS_EVT,
BTA_DM_PM_TIMER_EVT,
#endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */
#if (BTA_DM_QOS_INCLUDED == TRUE)
/* Quality of Service set events */
BTA_DM_API_QOS_SET_EVT,
#endif /* #if (BTA_DM_QOS_INCLUDED == TRUE) */
#if (SMP_INCLUDED == TRUE)
/* simple pairing events */
BTA_DM_API_CONFIRM_EVT,
@ -460,6 +464,16 @@ typedef struct {
} tBTA_DM_PM_TIMER;
#endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */
#if (BTA_DM_QOS_INCLUDED == TRUE)
/* data type for BTA_DM_API_QOS_SET_EVT */
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
UINT32 t_poll;
tBTM_CMPL_CB *p_cb;
} tBTA_DM_API_QOS_SET;
#endif /* #if (BTA_DM_QOS_INCLUDED == TRUE) */
/* data type for BTA_DM_API_ADD_DEVICE_EVT */
typedef struct {
BT_HDR hdr;
@ -888,6 +902,11 @@ typedef union {
tBTA_DM_PM_TIMER pm_timer;
#endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */
#if (BTA_DM_QOS_INCLUDED == TRUE)
/* Quality of Service set events */
tBTA_DM_API_QOS_SET qos_set;
#endif /* #if (BTA_DM_QOS_INCLUDED == TRUE) */
tBTA_DM_API_DI_DISC di_disc;
tBTA_DM_API_EXECUTE_CBACK exec_cback;
@ -1392,6 +1411,10 @@ extern void bta_dm_pm_btm_status(tBTA_DM_MSG *p_data);
extern void bta_dm_pm_timer(tBTA_DM_MSG *p_data);
#endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */
#if (BTA_DM_QOS_INCLUDED == TRUE)
extern void bta_dm_set_qos(tBTA_DM_MSG *p_data);
#endif /* #if (BTA_DM_QOS_INCLUDED == TRUE) */
extern UINT8 bta_dm_get_av_count(void);
extern void bta_dm_search_start (tBTA_DM_MSG *p_data);
extern void bta_dm_search_cancel (tBTA_DM_MSG *p_data);

View File

@ -1527,6 +1527,20 @@ extern void BTA_DmConfigEir(tBTA_DM_EIR_CONF *eir_config);
*******************************************************************************/
void BTA_DmSetAfhChannels(const uint8_t *channels, tBTA_CMPL_CB *set_afh_cb);
#if (BTA_DM_QOS_INCLUDED == TRUE)
/*******************************************************************************
**
** Function BTA_DmSetQos
**
** Description This function sets the QOS
**
**
** Returns void
**
*******************************************************************************/
void BTA_DmSetQos(BD_ADDR bd_addr, UINT32 t_poll, tBTM_CMPL_CB *p_cb);
#endif /// (BTA_DM_QOS_INCLUDED == TRUE)
#if (BLE_INCLUDED == TRUE)
/*******************************************************************************
**

View File

@ -757,6 +757,37 @@ static void btc_gap_bt_read_remote_name(btc_gap_bt_args_t *arg)
BTA_DmGetRemoteName(arg->rmt_name_bda.address, btc_gap_bt_read_remote_name_cmpl_callback);
}
#if (BTA_DM_QOS_INCLUDED == TRUE)
static void btc_gap_bt_set_qos_cmpl_callback(void *p_data)
{
tBTM_QOS_SETUP_CMPL *result = (tBTM_QOS_SETUP_CMPL *)p_data;
esp_bt_gap_cb_param_t param;
btc_msg_t msg;
bt_status_t ret;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_QOS_EVT;
param.qos_cmpl.stat = btc_btm_status_to_esp_status(result->status);
param.qos_cmpl.t_poll = result->flow.latency / 625;
memcpy(param.qos_cmpl.bda,result->rem_bda,BD_ADDR_LEN);
ret = btc_transfer_context(&msg, &param, sizeof(esp_bt_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
#endif /// (BTA_DM_QOS_INCLUDED == TRUE)
static void btc_gap_bt_set_qos(btc_gap_bt_args_t *arg)
{
#if (BTA_DM_QOS_INCLUDED == TRUE)
BTA_DmSetQos(arg->set_qos.bda.address, arg->set_qos.t_poll, btc_gap_bt_set_qos_cmpl_callback);
#else
BTC_TRACE_ERROR("%s: QoS is not supported.\n",__func__);
#endif /// (BTA_DM_QOS_INCLUDED == TRUE)
}
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
@ -772,6 +803,7 @@ void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
case BTC_GAP_BT_ACT_SET_PIN_TYPE:
case BTC_GAP_BT_ACT_SET_AFH_CHANNELS:
case BTC_GAP_BT_ACT_READ_REMOTE_NAME:
case BTC_GAP_BT_ACT_SET_QOS:
break;
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_ACT_PASSKEY_REPLY:
@ -837,6 +869,7 @@ void btc_gap_bt_arg_deep_free(btc_msg_t *msg)
case BTC_GAP_BT_ACT_SET_PIN_TYPE:
case BTC_GAP_BT_ACT_SET_AFH_CHANNELS:
case BTC_GAP_BT_ACT_READ_REMOTE_NAME:
case BTC_GAP_BT_ACT_SET_QOS:
break;
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_ACT_PASSKEY_REPLY:
@ -935,6 +968,10 @@ void btc_gap_bt_call_handler(btc_msg_t *msg)
btc_gap_bt_read_remote_name(arg);
break;
}
case BTC_GAP_BT_ACT_SET_QOS: {
btc_gap_bt_set_qos(arg);
break;
}
default:
break;
}
@ -976,6 +1013,7 @@ void btc_gap_bt_cb_deep_free(btc_msg_t *msg)
case BTC_GAP_BT_SET_AFH_CHANNELS_EVT:
case BTC_GAP_BT_READ_REMOTE_NAME_EVT:
case BTC_GAP_BT_REMOVE_BOND_DEV_COMPLETE_EVT:
case BTC_GAP_BT_QOS_EVT:
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_CFM_REQ_EVT:
case BTC_GAP_BT_KEY_NOTIF_EVT:
@ -1056,6 +1094,11 @@ void btc_gap_bt_cb_handler(btc_msg_t *msg)
btc_gap_bt_cb_to_app(ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT,(esp_bt_gap_cb_param_t *)msg->arg);
break;
}
case BTC_GAP_BT_QOS_EVT:{
btc_gap_bt_cb_to_app(ESP_BT_GAP_QOS_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
break;
}
default:
BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
break;

View File

@ -38,6 +38,7 @@ typedef enum {
BTC_GAP_BT_READ_REMOTE_NAME_EVT,
BTC_GAP_BT_MODE_CHG_EVT,
BTC_GAP_BT_REMOVE_BOND_DEV_COMPLETE_EVT,
BTC_GAP_BT_QOS_EVT,
}btc_gap_bt_evt_t;
typedef enum {
@ -57,6 +58,7 @@ typedef enum {
BTC_GAP_BT_ACT_CONFIG_EIR,
BTC_GAP_BT_ACT_SET_AFH_CHANNELS,
BTC_GAP_BT_ACT_READ_REMOTE_NAME,
BTC_GAP_BT_ACT_SET_QOS,
} btc_gap_bt_act_t;
/* btc_bt_gap_args_t */
@ -147,6 +149,12 @@ typedef union {
// BTC_GAP_BT_ACT_READ_REMOTE_NAME
bt_bdaddr_t rmt_name_bda;
// BTC_GAP_BT_ACT_SET_QOS
struct set_qos_args {
bt_bdaddr_t bda;
uint32_t t_poll;
} set_qos;
} btc_gap_bt_args_t;
void btc_gap_bt_call_handler(btc_msg_t *msg);

View File

@ -59,6 +59,7 @@
#define BTA_DM_PM_INCLUDED TRUE
#define BTC_DM_PM_INCLUDED TRUE
#define SDP_INCLUDED TRUE
#define BTA_DM_QOS_INCLUDED TRUE
#if (UC_BT_A2DP_ENABLED == TRUE)
#define BTA_AR_INCLUDED TRUE
@ -301,6 +302,10 @@
#define BTA_DM_PM_INCLUDED FALSE
#endif
#ifndef BTA_DM_QOS_INCLUDED
#define BTA_DM_QOS_INCLUDED FALSE
#endif
#ifndef BTA_PAN_INCLUDED
#define BTA_PAN_INCLUDED FALSE
#endif

View File

@ -1866,7 +1866,7 @@ tBTM_STATUS BTM_SetQoS (BD_ADDR bd, FLOW_SPEC *p_flow, tBTM_CMPL_CB *p_cb)
}
if ( (p = btm_bda_to_acl(bd, BT_TRANSPORT_BR_EDR)) != NULL) {
btu_start_timer (&btm_cb.devcb.qossu_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
btu_start_timer (&btm_cb.devcb.qossu_timer, BTU_TTYPE_BTM_QOS, BTM_DEV_REPLY_TIMEOUT);
btm_cb.devcb.p_qossu_cmpl_cb = p_cb;
if (!btsnd_hcic_qos_setup (p->hci_handle, p_flow->qos_flags, p_flow->service_type,
@ -1907,6 +1907,10 @@ void btm_qos_setup_complete (UINT8 status, UINT16 handle, FLOW_SPEC *p_flow)
memset(&qossu, 0, sizeof(tBTM_QOS_SETUP_CMPL));
qossu.status = status;
qossu.handle = handle;
tACL_CONN *p = btm_handle_to_acl(handle);
if (p != NULL) {
memcpy (qossu.rem_bda, p->remote_addr, BD_ADDR_LEN);
}
if (p_flow != NULL) {
qossu.flow.qos_flags = p_flow->qos_flags;
qossu.flow.service_type = p_flow->service_type;
@ -1921,6 +1925,22 @@ void btm_qos_setup_complete (UINT8 status, UINT16 handle, FLOW_SPEC *p_flow)
}
}
/*******************************************************************************
**
** Function btm_qos_setup_timeout
**
** Description This function processes a timeout.
** Currently, we just report an error log
**
** Returns void
**
*******************************************************************************/
void btm_qos_setup_timeout (void *p_tle)
{
BTM_TRACE_DEBUG ("%s\n", __func__);
btm_qos_setup_complete (HCI_ERR_HOST_TIMEOUT, 0, NULL);
}
/*******************************************************************************
**

View File

@ -1068,6 +1068,7 @@ void btm_sco_process_num_completed_pkts (UINT8 *p);
#define btm_sco_chk_pend_unpark(hci_status, hci_handle)
#endif /* BTM_SCO_INCLUDED */
void btm_qos_setup_complete (UINT8 status, UINT16 handle, FLOW_SPEC *p_flow);
void btm_qos_setup_timeout (void *p_tle);
/* Internal functions provided by btm_sco.c

View File

@ -385,17 +385,17 @@ static void btu_general_alarm_process(void *param)
}
break;
default:;
int i = 0;
BOOLEAN handled = FALSE;
for (; !handled && i < BTU_MAX_REG_TIMER; i++) {
case BTU_TTYPE_BTM_QOS:
btm_qos_setup_timeout(p_tle);
break;
default:
for (int i = 0; i < BTU_MAX_REG_TIMER; i++) {
if (btu_cb.timer_reg[i].timer_cb == NULL) {
continue;
}
if (btu_cb.timer_reg[i].p_tle == p_tle) {
btu_cb.timer_reg[i].timer_cb(p_tle);
handled = TRUE;
break;
}
}
break;

View File

@ -765,6 +765,7 @@ typedef struct {
FLOW_SPEC flow;
UINT16 handle;
UINT8 status;
BD_ADDR rem_bda;
} tBTM_QOS_SETUP_CMPL;

View File

@ -164,6 +164,9 @@ typedef void (*tBTU_EVENT_CALLBACK)(BT_HDR *p_hdr);
#define BTU_TTYPE_UCD_TO 108
#define BTU_TTYPE_BLE_SCAN 109
/* BTU internal timer for QOS */
#define BTU_TTYPE_BTM_QOS 110
/* BTU Task Signal */
typedef enum {
SIG_BTU_START_UP = 0,