Merge branch 'NimBLE/fix_send_after_controller_ready_v3.3' into 'release/v3.3'

NimBLE: Fix erroneous behaviour of NPL when controller not ready to receive (v3.3)

See merge request espressif/esp-idf!6806
This commit is contained in:
Mahavir Jain 2019-12-03 02:17:35 +08:00
commit 7d26cf16cc

View file

@ -27,6 +27,9 @@
#include "nimble/nimble_port_freertos.h" #include "nimble/nimble_port_freertos.h"
#include "esp_nimble_hci.h" #include "esp_nimble_hci.h"
#include "esp_bt.h" #include "esp_bt.h"
#include "freertos/semphr.h"
#define NIMBLE_VHCI_TIMEOUT_MS 2000
static ble_hci_trans_rx_cmd_fn *ble_hci_rx_cmd_hs_cb; static ble_hci_trans_rx_cmd_fn *ble_hci_rx_cmd_hs_cb;
static void *ble_hci_rx_cmd_hs_arg; static void *ble_hci_rx_cmd_hs_arg;
@ -66,6 +69,7 @@ static os_membuf_t ble_hci_evt_lo_buf[
MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))
]; ];
static SemaphoreHandle_t vhci_send_sem;
const static char *TAG = "NimBLE"; const static char *TAG = "NimBLE";
void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
@ -83,18 +87,23 @@ void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) int ble_hci_trans_hs_cmd_tx(uint8_t *cmd)
{ {
uint16_t len; uint16_t len;
uint8_t rc = 0;
assert(cmd != NULL); assert(cmd != NULL);
*cmd = BLE_HCI_UART_H4_CMD; *cmd = BLE_HCI_UART_H4_CMD;
len = BLE_HCI_CMD_HDR_LEN + cmd[3] + 1; len = BLE_HCI_CMD_HDR_LEN + cmd[3] + 1;
if (!esp_vhci_host_check_send_available()) { if (!esp_vhci_host_check_send_available()) {
ESP_LOGE(TAG, "Controller not ready to receive packets from host at this time, try again after sometime"); ESP_LOGD(TAG, "Controller not ready to receive packets");
return BLE_HS_EAGAIN; }
if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
esp_vhci_host_send_packet(cmd, len);
} else {
rc = BLE_HS_ETIMEOUT_HCI;
} }
esp_vhci_host_send_packet(cmd, len);
ble_hci_trans_buf_free(cmd); ble_hci_trans_buf_free(cmd);
return 0; return rc;
} }
int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev)
@ -110,7 +119,7 @@ int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev)
int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) int ble_hci_trans_hs_acl_tx(struct os_mbuf *om)
{ {
uint16_t len = 0; uint16_t len = 0;
uint8_t data[MYNEWT_VAL(BLE_ACL_BUF_SIZE) + 1]; uint8_t data[MYNEWT_VAL(BLE_ACL_BUF_SIZE) + 1], rc = 0;
/* If this packet is zero length, just free it */ /* If this packet is zero length, just free it */
if (OS_MBUF_PKTLEN(om) == 0) { if (OS_MBUF_PKTLEN(om) == 0) {
os_mbuf_free_chain(om); os_mbuf_free_chain(om);
@ -120,18 +129,21 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om)
len++; len++;
if (!esp_vhci_host_check_send_available()) { if (!esp_vhci_host_check_send_available()) {
ESP_LOGE(TAG, "Controller not ready to receive packets from host at this time, try again after sometime"); ESP_LOGD(TAG, "Controller not ready to receive packets");
return BLE_HS_EAGAIN;
} }
os_mbuf_copydata(om, 0, OS_MBUF_PKTLEN(om), &data[1]); os_mbuf_copydata(om, 0, OS_MBUF_PKTLEN(om), &data[1]);
len += OS_MBUF_PKTLEN(om); len += OS_MBUF_PKTLEN(om);
esp_vhci_host_send_packet(data, len); if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
esp_vhci_host_send_packet(data, len);
} else {
rc = BLE_HS_ETIMEOUT_HCI;
}
os_mbuf_free_chain(om); os_mbuf_free_chain(om);
return 0; return rc;
} }
int ble_hci_trans_ll_acl_tx(struct os_mbuf *om) int ble_hci_trans_ll_acl_tx(struct os_mbuf *om)
@ -316,6 +328,9 @@ static void ble_hci_transport_init(void)
*/ */
static void controller_rcv_pkt_ready(void) static void controller_rcv_pkt_ready(void)
{ {
if (vhci_send_sem) {
xSemaphoreGive(vhci_send_sem);
}
} }
/* /*
@ -358,11 +373,12 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len)
return 0; return 0;
} }
static esp_vhci_host_callback_t vhci_host_cb = { static const esp_vhci_host_callback_t vhci_host_cb = {
controller_rcv_pkt_ready, .notify_host_send_available = controller_rcv_pkt_ready,
host_rcv_pkt .notify_host_recv = host_rcv_pkt,
}; };
esp_err_t esp_nimble_hci_init(void) esp_err_t esp_nimble_hci_init(void)
{ {
esp_err_t ret; esp_err_t ret;
@ -372,6 +388,13 @@ esp_err_t esp_nimble_hci_init(void)
ble_hci_transport_init(); ble_hci_transport_init();
vhci_send_sem = xSemaphoreCreateBinary();
if (vhci_send_sem == NULL) {
return ESP_ERR_NO_MEM;
}
xSemaphoreGive(vhci_send_sem);
return ESP_OK; return ESP_OK;
} }
@ -414,6 +437,13 @@ static esp_err_t ble_hci_transport_deinit(void)
esp_err_t esp_nimble_hci_deinit(void) esp_err_t esp_nimble_hci_deinit(void)
{ {
if (vhci_send_sem) {
/* Dummy take & give semaphore before deleting */
xSemaphoreTake(vhci_send_sem, portMAX_DELAY);
xSemaphoreGive(vhci_send_sem);
vSemaphoreDelete(vhci_send_sem);
vhci_send_sem = NULL;
}
return ble_hci_transport_deinit(); return ble_hci_transport_deinit();
} }