Jelajahi Sumber

Merge branch 'bugfix/spp_data_send_delay_v4.1' into 'release/v4.1'

Bugfix/spp data send delay v4.1

See merge request espressif/esp-idf!11773
Jiang Jiang Jian 4 tahun lalu
induk
melakukan
997ac7e166

+ 1 - 0
components/bt/CMakeLists.txt

@@ -95,6 +95,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"

+ 17 - 0
components/bt/host/bluedroid/api/esp_gap_bt_api.c

@@ -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 */

+ 26 - 0
components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h

@@ -211,6 +211,7 @@ typedef enum {
     ESP_BT_GAP_SET_AFH_CHANNELS_EVT,                /*!< set AFH channels event */
     ESP_BT_GAP_READ_REMOTE_NAME_EVT,                /*!< read Remote Name event */
     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;
 
@@ -345,6 +346,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;
 
 /**
@@ -701,6 +712,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

+ 4 - 0
components/bt/host/bluedroid/bta/dm/bta_dm_main.c

@@ -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 */

+ 68 - 0
components/bt/host/bluedroid/bta/dm/bta_dm_qos.c

@@ -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)

+ 23 - 0
components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h

@@ -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,
@@ -459,6 +463,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;
@@ -887,6 +901,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;
@@ -1390,6 +1409,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);

+ 14 - 0
components/bt/host/bluedroid/bta/include/bta/bta_api.h

@@ -1510,6 +1510,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)
 /*******************************************************************************
 **

+ 43 - 0
components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c

@@ -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:
@@ -1047,6 +1085,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;

+ 8 - 0
components/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h

@@ -37,6 +37,7 @@ typedef enum {
     BTC_GAP_BT_SET_AFH_CHANNELS_EVT,
     BTC_GAP_BT_READ_REMOTE_NAME_EVT,
     BTC_GAP_BT_REMOVE_BOND_DEV_COMPLETE_EVT,
+    BTC_GAP_BT_QOS_EVT,
 }btc_gap_bt_evt_t;
 
 typedef enum {
@@ -56,6 +57,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 */
@@ -146,6 +148,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);

+ 5 - 0
components/bt/host/bluedroid/common/include/common/bt_target.h

@@ -58,6 +58,7 @@
 #define BTA_SDP_INCLUDED            TRUE
 #define BTA_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
@@ -295,6 +296,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

+ 21 - 1
components/bt/host/bluedroid/stack/btm/btm_acl.c

@@ -1860,7 +1860,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,
@@ -1901,6 +1901,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;
@@ -1915,6 +1919,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);
+}
 
 /*******************************************************************************
 **

+ 1 - 0
components/bt/host/bluedroid/stack/btm/include/btm_int.h

@@ -1042,6 +1042,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

+ 6 - 6
components/bt/host/bluedroid/stack/btu/btu_task.c

@@ -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;

+ 1 - 0
components/bt/host/bluedroid/stack/include/stack/btm_api.h

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

+ 3 - 0
components/bt/host/bluedroid/stack/include/stack/btu.h

@@ -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,