P4 fixes
This commit is contained in:
18
resources/espressif__esp_hosted/host/drivers/bt/hci_drv.h
Normal file
18
resources/espressif__esp_hosted/host/drivers/bt/hci_drv.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2015-2024 Espressif Systems (Shanghai) PTE LTD
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
|
||||
|
||||
#ifndef __HOSTED_HCI_DRV_H
|
||||
#define __HOSTED_HCI_DRV_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "esp_hosted_bt_config.h"
|
||||
|
||||
void hci_drv_init(void);
|
||||
|
||||
void hci_drv_show_configuration(void);
|
||||
|
||||
// Handles BT Rx
|
||||
int hci_rx_handler(interface_buffer_handle_t *buf_handle);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2015-2024 Espressif Systems (Shanghai) PTE LTD
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
|
||||
|
||||
#include "hci_drv.h"
|
||||
|
||||
#include "esp_hosted_log.h"
|
||||
static const char TAG[] = "hci_stub_drv";
|
||||
|
||||
#if H_BT_HOST_ESP_NIMBLE
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
#include "nimble/transport.h"
|
||||
#endif
|
||||
|
||||
#if H_BT_HOST_ESP_BLUEDROID
|
||||
#include "esp_hosted_bt.h"
|
||||
#endif
|
||||
|
||||
#define WEAK __attribute__((weak))
|
||||
|
||||
int hci_rx_handler(interface_buffer_handle_t *buf_handle)
|
||||
{
|
||||
/* Hosted transport received BT packets, but Hosted was not
|
||||
* configured to handle BT packets. Drop them.
|
||||
*/
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void hci_drv_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void hci_drv_show_configuration(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Host BT Support: Disabled");
|
||||
}
|
||||
|
||||
#if H_BT_HOST_ESP_NIMBLE
|
||||
/**
|
||||
* ESP NimBLE expects these interfaces for Tx
|
||||
*
|
||||
* There are marked as weak references:
|
||||
*
|
||||
* - to allow ESP NimBLE BT Host code to override the functions if
|
||||
* NimBLE BT Host is configured to act as the HCI transport
|
||||
*
|
||||
* - to allow the User to use their own ESP NimBLE HCI transport code
|
||||
* without causing linker errors from Hosted
|
||||
*
|
||||
* - to allow Hosted code to build without linker errors if ESP NimBLE
|
||||
* BT Host is enabled, but Hosted is not configured as HCI transport
|
||||
* and there is no other ESP NimBLE HCI transport code being
|
||||
* used. In this case, the stub functions are used and drops the
|
||||
* incoming data.
|
||||
*/
|
||||
|
||||
WEAK int ble_transport_to_ll_acl_impl(struct os_mbuf *om)
|
||||
{
|
||||
os_mbuf_free_chain(om);
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
WEAK int ble_transport_to_ll_cmd_impl(void *buf)
|
||||
{
|
||||
ble_transport_free(buf);
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif // H_BT_HOST_ESP_NIMBLE
|
||||
|
||||
#if H_BT_HOST_ESP_BLUEDROID
|
||||
WEAK void hosted_hci_bluedroid_open(void)
|
||||
{
|
||||
}
|
||||
|
||||
WEAK void hosted_hci_bluedroid_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
WEAK void hosted_hci_bluedroid_send(uint8_t *data, uint16_t len)
|
||||
{
|
||||
}
|
||||
|
||||
WEAK bool hosted_hci_bluedroid_check_send_available(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WEAK esp_err_t hosted_hci_bluedroid_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback)
|
||||
{
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif // H_BT_HOST_ESP_BLUEDROID
|
||||
263
resources/espressif__esp_hosted/host/drivers/bt/vhci_drv.c
Normal file
263
resources/espressif__esp_hosted/host/drivers/bt/vhci_drv.c
Normal file
@@ -0,0 +1,263 @@
|
||||
// Copyright 2015-2024 Espressif Systems (Shanghai) PTE LTD
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_hosted_transport.h"
|
||||
#include "os_wrapper.h"
|
||||
#include "transport_drv.h"
|
||||
|
||||
#include "hci_drv.h"
|
||||
|
||||
#if H_BT_HOST_ESP_NIMBLE
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
#include "os/os_mbuf.h"
|
||||
#include "nimble/transport.h"
|
||||
#include "nimble/transport/hci_h4.h"
|
||||
#include "nimble/hci_common.h"
|
||||
#endif
|
||||
|
||||
#if H_BT_HOST_ESP_BLUEDROID
|
||||
#include "esp_hosted_bt.h"
|
||||
#endif
|
||||
|
||||
#include "esp_hosted_log.h"
|
||||
static const char TAG[] = "vhci_drv";
|
||||
|
||||
#if H_BT_HOST_ESP_NIMBLE
|
||||
#define BLE_HCI_EVENT_HDR_LEN (2)
|
||||
#define BLE_HCI_CMD_HDR_LEN (3)
|
||||
#endif
|
||||
|
||||
void hci_drv_init(void)
|
||||
{
|
||||
// do nothing for VHCI: underlying transport should be ready
|
||||
}
|
||||
|
||||
void hci_drv_show_configuration(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Host BT Support: Enabled");
|
||||
ESP_LOGI(TAG, "\tBT Transport Type: VHCI");
|
||||
}
|
||||
|
||||
#if H_BT_HOST_ESP_NIMBLE
|
||||
/**
|
||||
* HCI_H4_xxx is the first byte of the received data
|
||||
*/
|
||||
int hci_rx_handler(interface_buffer_handle_t *buf_handle)
|
||||
{
|
||||
uint8_t * data = buf_handle->payload;
|
||||
uint32_t len_total_read = buf_handle->payload_len;
|
||||
|
||||
int rc;
|
||||
|
||||
if (data[0] == HCI_H4_EVT) {
|
||||
uint8_t *evbuf;
|
||||
int totlen;
|
||||
|
||||
totlen = BLE_HCI_EVENT_HDR_LEN + data[2];
|
||||
if (totlen > UINT8_MAX + BLE_HCI_EVENT_HDR_LEN) {
|
||||
ESP_LOGE(TAG, "Rx: len[%d] > max INT [%d], drop",
|
||||
totlen, UINT8_MAX + BLE_HCI_EVENT_HDR_LEN);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (totlen > MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)) {
|
||||
ESP_LOGE(TAG, "Rx: len[%d] > max BLE [%d], drop",
|
||||
totlen, MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (data[1] == BLE_HCI_EVCODE_HW_ERROR) {
|
||||
ESP_LOGE(TAG, "Rx: HW_ERROR");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Allocate LE Advertising Report Event from lo pool only */
|
||||
if ((data[1] == BLE_HCI_EVCODE_LE_META) &&
|
||||
(data[3] == BLE_HCI_LE_SUBEV_ADV_RPT || data[3] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) {
|
||||
evbuf = ble_transport_alloc_evt(1);
|
||||
/* Skip advertising report if we're out of memory */
|
||||
if (!evbuf) {
|
||||
ESP_LOGW(TAG, "Rx: Drop ADV Report Event: NimBLE OOM (not fatal)");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else {
|
||||
evbuf = ble_transport_alloc_evt(0);
|
||||
if (!evbuf) {
|
||||
ESP_LOGE(TAG, "Rx: failed transport_alloc_evt(0)");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
memset(evbuf, 0, sizeof * evbuf);
|
||||
memcpy(evbuf, &data[1], totlen);
|
||||
|
||||
rc = ble_transport_to_hs_evt(evbuf);
|
||||
if (rc) {
|
||||
ESP_LOGE(TAG, "Rx: transport_to_hs_evt failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else if (data[0] == HCI_H4_ACL) {
|
||||
struct os_mbuf *m = NULL;
|
||||
|
||||
m = ble_transport_alloc_acl_from_ll();
|
||||
if (!m) {
|
||||
ESP_LOGE(TAG, "Rx: alloc_acl_from_ll failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if ((rc = os_mbuf_append(m, &data[1], len_total_read - 1)) != 0) {
|
||||
ESP_LOGE(TAG, "Rx: failed os_mbuf_append; rc = %d", rc);
|
||||
os_mbuf_free_chain(m);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ble_transport_to_hs_acl(m);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* ESP NimBLE expects these interfaces for Tx
|
||||
*
|
||||
* For doing non-zero copy:
|
||||
* - transport expects the HCI_H4_xxx type to be the first byte of the
|
||||
* data stream
|
||||
*
|
||||
* For doing zero copy:
|
||||
* - fill in esp_paylod_header and payload data
|
||||
* - HCI_H4_xxx type should be set in esp_payload_header.hci_pkt_type
|
||||
*/
|
||||
|
||||
#if H_BT_ENABLE_LL_INIT
|
||||
void ble_transport_ll_init(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(transport_drv_reconfigure());
|
||||
}
|
||||
|
||||
void ble_transport_ll_deinit(void)
|
||||
{
|
||||
// transport may still be in used for other data (serial, Wi-Fi, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
int ble_transport_to_ll_acl_impl(struct os_mbuf *om)
|
||||
{
|
||||
// TODO: zerocopy version
|
||||
|
||||
// calculate data length from the incoming data
|
||||
int data_len = OS_MBUF_PKTLEN(om) + 1;
|
||||
|
||||
uint8_t * data = NULL;
|
||||
int res;
|
||||
|
||||
data = MEM_ALLOC(data_len);
|
||||
if (!data) {
|
||||
ESP_LOGE(TAG, "Tx %s: malloc failed", __func__);
|
||||
res = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data[0] = HCI_H4_ACL;
|
||||
res = ble_hs_mbuf_to_flat(om, &data[1], OS_MBUF_PKTLEN(om), NULL);
|
||||
if (res) {
|
||||
ESP_LOGE(TAG, "Tx: Error copying HCI_H4_ACL data %d", res);
|
||||
res = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
res = esp_hosted_tx(ESP_HCI_IF, 0, data, data_len, H_BUFF_NO_ZEROCOPY, H_DEFLT_FREE_FUNC);
|
||||
|
||||
exit:
|
||||
os_mbuf_free_chain(om);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int ble_transport_to_ll_cmd_impl(void *buf)
|
||||
{
|
||||
// TODO: zerocopy version
|
||||
|
||||
// calculate data length from the incoming data
|
||||
int buf_len = 3 + ((uint8_t *)buf)[2] + 1;
|
||||
|
||||
uint8_t * data = NULL;
|
||||
int res;
|
||||
|
||||
data = MEM_ALLOC(buf_len);
|
||||
if (!data) {
|
||||
ESP_LOGE(TAG, "Tx %s: malloc failed", __func__);
|
||||
res = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data[0] = HCI_H4_CMD;
|
||||
memcpy(&data[1], buf, buf_len - 1);
|
||||
|
||||
res = esp_hosted_tx(ESP_HCI_IF, 0, data, buf_len, H_BUFF_NO_ZEROCOPY, H_DEFLT_FREE_FUNC);
|
||||
|
||||
exit:
|
||||
ble_transport_free(buf);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif // H_BT_HOST_ESP_NIMBLE
|
||||
|
||||
#if H_BT_HOST_ESP_BLUEDROID
|
||||
static esp_bluedroid_hci_driver_callbacks_t s_callback = { 0 };
|
||||
|
||||
int hci_rx_handler(interface_buffer_handle_t *buf_handle)
|
||||
{
|
||||
uint8_t * data = buf_handle->payload;
|
||||
uint32_t len_total_read = buf_handle->payload_len;
|
||||
|
||||
if (s_callback.notify_host_recv) {
|
||||
s_callback.notify_host_recv(data, len_total_read);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void hosted_hci_bluedroid_open(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(transport_drv_reconfigure());
|
||||
}
|
||||
|
||||
void hosted_hci_bluedroid_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
esp_err_t hosted_hci_bluedroid_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback)
|
||||
{
|
||||
s_callback.notify_host_send_available = callback->notify_host_send_available;
|
||||
s_callback.notify_host_recv = callback->notify_host_recv;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void hosted_hci_bluedroid_send(uint8_t *data, uint16_t len)
|
||||
{
|
||||
int res;
|
||||
uint8_t * ptr = NULL;
|
||||
|
||||
ptr = MEM_ALLOC(len);
|
||||
if (!ptr) {
|
||||
ESP_LOGE(TAG, "%s: malloc failed", __func__);
|
||||
return;
|
||||
}
|
||||
memcpy(ptr, data, len);
|
||||
|
||||
res = esp_hosted_tx(ESP_HCI_IF, 0, ptr, len, H_BUFF_NO_ZEROCOPY, H_DEFLT_FREE_FUNC);
|
||||
|
||||
if (res) {
|
||||
ESP_LOGE(TAG, "%s: Tx failed", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
bool hosted_hci_bluedroid_check_send_available(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // H_BT_HOST_ESP_BLUEDROID
|
||||
Reference in New Issue
Block a user