mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(ble_audio): BLE Audio PSRAM support
This commit is contained in:
@@ -70,6 +70,7 @@ if(CONFIG_IDF_DOC_BUILD OR CONFIG_BT_ENABLED)
|
||||
add_subdirectory(esp_ble_audio)
|
||||
list(APPEND srcs ${ble_audio_srcs})
|
||||
list(APPEND include_dirs ${ble_audio_include_dirs})
|
||||
list(APPEND ldscripts ${ble_audio_ldscripts})
|
||||
|
||||
# BLE profiles (host-agnostic profile cores + shared profile infrastructure)
|
||||
add_subdirectory(ble_profiles)
|
||||
|
||||
@@ -11,6 +11,7 @@ endfunction()
|
||||
|
||||
set(ble_audio_srcs "" PARENT_SCOPE)
|
||||
set(ble_audio_include_dirs "" PARENT_SCOPE)
|
||||
set(ble_audio_ldscripts "" PARENT_SCOPE)
|
||||
|
||||
# API headers that are used in the docs are also compiled
|
||||
# even if CONFIG_BT_ENABLED=n as long as CONFIG_IDF_DOC_BUILD=y
|
||||
@@ -176,3 +177,4 @@ endif()
|
||||
# Export the variables to the parent scope
|
||||
set(ble_audio_srcs "${ble_audio_srcs}" PARENT_SCOPE)
|
||||
set(ble_audio_include_dirs "${ble_audio_include_dirs}" PARENT_SCOPE)
|
||||
set(ble_audio_ldscripts "${CMAKE_CURRENT_LIST_DIR}/linker.lf" PARENT_SCOPE)
|
||||
|
||||
@@ -99,6 +99,40 @@ menu "OTS Options"
|
||||
rsource "host/services/ots/Kconfig.ots.in"
|
||||
endmenu
|
||||
|
||||
config BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY
|
||||
bool "Place BLE Audio .bss segment in external SPIRAM"
|
||||
depends on BT_ISO_BSS_SEG_EXTERNAL_MEMORY
|
||||
default n
|
||||
help
|
||||
Place the zero-initialized (.bss) static data of the BLE Audio
|
||||
profiles in external SPIRAM instead of internal DRAM. Covers both the
|
||||
esp_ble_audio IDF source files and the .bss of the prebuilt BLE Audio
|
||||
library (libble_audio.a), the latter relocated via a linker fragment.
|
||||
|
||||
Depends on BT_ISO_BSS_SEG_EXTERNAL_MEMORY: the audio layer sits on top
|
||||
of the ISO/host layer, so its static data is moved to SPIRAM only when
|
||||
the ISO layer's is, keeping the placement coherent.
|
||||
|
||||
Requires SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY. Only .bss is moved;
|
||||
initialized (.data) statistics stay internal.
|
||||
|
||||
config BT_AUDIO_HEAP_EXTERNAL_MEMORY
|
||||
bool "Place BLE Audio heap allocations in external SPIRAM"
|
||||
depends on BT_ISO_HEAP_EXTERNAL_MEMORY
|
||||
default n
|
||||
help
|
||||
Route BLE Audio runtime heap allocations to external SPIRAM instead of
|
||||
internal DRAM. Covers both the esp_ble_audio profiles and the prebuilt
|
||||
BLE Audio library (libble_audio.a): both allocate via idf_ext_calloc /
|
||||
idf_ext_malloc, which this switch points at the ISO layer's SPIRAM
|
||||
helper (heap_caps_*(MALLOC_CAP_SPIRAM)).
|
||||
|
||||
Depends on BT_ISO_HEAP_EXTERNAL_MEMORY: the audio allocator hook reuses
|
||||
the ISO layer's helper, available only when the ISO layer routes to
|
||||
SPIRAM too.
|
||||
|
||||
On SPIRAM exhaustion allocations return NULL (no internal fallback).
|
||||
|
||||
config BT_AUDIO_NO_LOG
|
||||
bool "Disable BLE Audio Lib Debug Log"
|
||||
default n
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_CAS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
#if CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER
|
||||
static struct inc_svc_inst inc_csis_inst;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_svc_inst inc_csis_inst;
|
||||
|
||||
struct inc_svc_inst *cas_not_included_inst(void)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -23,11 +24,11 @@ LOG_MODULE_REGISTER(LEA_CSIS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
#define CSIS_SVC_COUNT CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT
|
||||
|
||||
static struct csis_inst {
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct csis_inst {
|
||||
struct bt_gatt_service *svc_p;
|
||||
} csis_insts[CSIS_SVC_COUNT];
|
||||
|
||||
static uint8_t csis_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t csis_svc_count;
|
||||
|
||||
int bt_le_bluedroid_csis_init(void *svc, uint8_t count)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -29,7 +30,7 @@ LOG_MODULE_REGISTER(LEA_MCS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
/* GMCS includes a single secondary OTS instance. Mirrors the CAS->CSIS included-
|
||||
* secondary pattern: create the secondary before the primary so the include
|
||||
* declaration in the GMCS table resolves to OTS's live handle. */
|
||||
static struct inc_svc_inst inc_ots_inst;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_svc_inst inc_ots_inst;
|
||||
|
||||
struct inc_svc_inst *gmcs_not_included_inst(void)
|
||||
{
|
||||
|
||||
@@ -18,15 +18,17 @@
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_MICS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
#define AICS_INST_COUNT CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT
|
||||
|
||||
static uint8_t inc_aics_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t inc_aics_svc_count;
|
||||
|
||||
static struct inc_svc_inst inc_aics_insts[AICS_INST_COUNT];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_svc_inst inc_aics_insts[AICS_INST_COUNT];
|
||||
|
||||
struct inc_svc_inst *mics_not_included_inst(void)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -25,11 +26,11 @@ LOG_MODULE_REGISTER(LEA_VCS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
#define VOCS_INST_COUNT CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT
|
||||
#define AICS_INST_COUNT CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT
|
||||
|
||||
static uint8_t inc_vocs_svc_count;
|
||||
static uint8_t inc_aics_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t inc_vocs_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t inc_aics_svc_count;
|
||||
|
||||
static struct inc_svc_inst inc_vocs_insts[VOCS_INST_COUNT];
|
||||
static struct inc_svc_inst inc_aics_insts[AICS_INST_COUNT];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_svc_inst inc_vocs_insts[VOCS_INST_COUNT];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_svc_inst inc_aics_insts[AICS_INST_COUNT];
|
||||
|
||||
struct inc_svc_inst *vcs_not_included_inst(void)
|
||||
{
|
||||
|
||||
@@ -23,14 +23,15 @@
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_GSRV, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static uint8_t svc_in_progress;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t svc_in_progress;
|
||||
|
||||
static uint16_t inc_svc_handle;
|
||||
static uint16_t svc_handle;
|
||||
static uint16_t chrc_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_svc_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t svc_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t chrc_handle;
|
||||
|
||||
static bool is_primary_svc(void)
|
||||
{
|
||||
@@ -413,12 +414,12 @@ static uint8_t get_svc_inst_id(uint16_t svc_uuid)
|
||||
* For LE Audio, some service could have multiple instances.
|
||||
*/
|
||||
|
||||
static uint8_t aics_count;
|
||||
static uint8_t csis_count;
|
||||
static uint8_t vocs_count;
|
||||
static uint8_t mcs_count;
|
||||
static uint8_t ots_count;
|
||||
static uint8_t tbs_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t aics_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t csis_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t vocs_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t mcs_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t ots_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t tbs_count;
|
||||
|
||||
switch (svc_uuid) {
|
||||
case BT_UUID_AICS_VAL:
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -35,9 +36,9 @@ static const ble_uuid16_t ascs_uuid_ase_cp = BLE_UUID16_INIT(BT_UUID_ASCS_ASE_CP
|
||||
static const ble_uuid16_t ascs_uuid_ase_snk = BLE_UUID16_INIT(BT_UUID_ASCS_ASE_SNK_VAL);
|
||||
static const ble_uuid16_t ascs_uuid_ase_src = BLE_UUID16_INIT(BT_UUID_ASCS_ASE_SRC_VAL);
|
||||
|
||||
static uint16_t ase_control_point_handle;
|
||||
static uint16_t ase_snk_handle[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT];
|
||||
static uint16_t ase_src_handle[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t ase_control_point_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t ase_snk_handle[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t ase_src_handle[CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
|
||||
|
||||
static struct ble_gatt_svc_def gatt_svc_ascs[] = {
|
||||
{
|
||||
@@ -209,7 +210,7 @@ int bt_le_nimble_ascs_init(void)
|
||||
|
||||
LOG_DBG("[N]AscsInit[%u]", chr_count);
|
||||
|
||||
gatt_svc_ascs[0].characteristics = calloc(chr_count, sizeof(struct ble_gatt_chr_def));
|
||||
gatt_svc_ascs[0].characteristics = bt_le_ext_calloc(chr_count, sizeof(struct ble_gatt_chr_def));
|
||||
assert(gatt_svc_ascs[0].characteristics);
|
||||
|
||||
ascs_svc_add_ase_cp_chr((void *)(gatt_svc_ascs[0].characteristics + 0));
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -34,8 +35,8 @@ LOG_MODULE_REGISTER(LEA_BASS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
static const ble_uuid16_t bass_uuid_control_point = BLE_UUID16_INIT(BT_UUID_BASS_CONTROL_POINT_VAL);
|
||||
static const ble_uuid16_t bass_uuid_recv_state = BLE_UUID16_INIT(BT_UUID_BASS_RECV_STATE_VAL);
|
||||
|
||||
static uint16_t bass_control_point_handle;
|
||||
static uint16_t bass_recv_state_handle[CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t bass_control_point_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t bass_recv_state_handle[CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT];
|
||||
|
||||
static struct ble_gatt_svc_def gatt_svc_bass[] = {
|
||||
{
|
||||
@@ -179,7 +180,7 @@ int bt_le_nimble_bass_init(void)
|
||||
|
||||
LOG_DBG("[N]BassInit[%u]", chr_count);
|
||||
|
||||
gatt_svc_bass->characteristics = calloc(chr_count, sizeof(struct ble_gatt_chr_def));
|
||||
gatt_svc_bass->characteristics = bt_le_ext_calloc(chr_count, sizeof(struct ble_gatt_chr_def));
|
||||
assert(gatt_svc_bass->characteristics);
|
||||
|
||||
bass_svc_add_control_point_chr((void *)(gatt_svc_bass->characteristics + 0));
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -26,7 +27,7 @@ LOG_MODULE_REGISTER(LEA_CAS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
#if CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER
|
||||
extern struct ble_gatt_svc_def *cas_get_included_csis(void *csis_svc_p);
|
||||
|
||||
static struct bt_gatt_service *inc_csis_svc;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct bt_gatt_service *inc_csis_svc;
|
||||
|
||||
static struct ble_gatt_svc_def *cas_inc_svcs[] = {
|
||||
NULL,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -75,7 +76,7 @@ static const ble_uuid16_t csis_uuid_set_lock = BLE_UUID16_INIT(BT_UUID_CSIS_SET_
|
||||
static const ble_uuid16_t csis_uuid_rank = BLE_UUID16_INIT(BT_UUID_CSIS_RANK_VAL);
|
||||
static const ble_uuid16_t csis_uuid_set_name = BLE_UUID16_INIT(BT_UUID_CSIS_SET_NAME_VAL);
|
||||
|
||||
static struct csis_inst {
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct csis_inst {
|
||||
struct bt_gatt_service *svc_p;
|
||||
uint16_t sirk_handle;
|
||||
uint16_t set_size_handle;
|
||||
@@ -84,10 +85,10 @@ static struct csis_inst {
|
||||
uint16_t set_name_handle;
|
||||
} csis_insts[CSIS_SVC_COUNT];
|
||||
|
||||
static uint8_t csis_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t csis_svc_count;
|
||||
|
||||
/* Extra one for terminating the CSIS service array */
|
||||
static struct ble_gatt_svc_def gatt_svc_csis[CSIS_SVC_COUNT + 1];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def gatt_svc_csis[CSIS_SVC_COUNT + 1];
|
||||
|
||||
struct ble_gatt_svc_def *cas_get_included_csis(void *csis_svc_p)
|
||||
{
|
||||
@@ -244,7 +245,7 @@ static void csis_svc_init(struct csis_inst *inst,
|
||||
svc->uuid = &csis_uuid_svc.u;
|
||||
svc->includes = NULL;
|
||||
|
||||
svc->characteristics = calloc(CSIS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
svc->characteristics = bt_le_ext_calloc(CSIS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
assert(svc->characteristics);
|
||||
|
||||
/* Build the NimBLE characteristics from the ones actually present in the Zephyr
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -35,9 +36,9 @@ LOG_MODULE_REGISTER(LEA_GMAS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
#define GMAS_MAX_CHRS (1 + 4) /* GMAP Role + up to one feature char per role */
|
||||
|
||||
static const ble_uuid16_t gmas_svc_uuid = BLE_UUID16_INIT(BT_UUID_GMAS_VAL);
|
||||
static ble_uuid16_t gmas_chr_uuids[GMAS_MAX_CHRS];
|
||||
static struct ble_gatt_chr_def gmas_chrs[GMAS_MAX_CHRS + 1];
|
||||
static struct ble_gatt_svc_def gatt_svc_gmas[2];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR ble_uuid16_t gmas_chr_uuids[GMAS_MAX_CHRS];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_chr_def gmas_chrs[GMAS_MAX_CHRS + 1];
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def gatt_svc_gmas[2];
|
||||
|
||||
/* Mirror the lib's GMAS table (primary + role char + registered feature chars,
|
||||
each value attr following a 0x2803 declaration) into the NimBLE service def. */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -35,9 +36,9 @@ static const ble_uuid16_t has_uuid_features = BLE_UUID16_INIT(BT_UUID_HAS_HEARIN
|
||||
static const ble_uuid16_t has_uuid_control_point = BLE_UUID16_INIT(BT_UUID_HAS_PRESET_CONTROL_POINT_VAL);
|
||||
static const ble_uuid16_t has_uuid_preset_index = BLE_UUID16_INIT(BT_UUID_HAS_ACTIVE_PRESET_INDEX_VAL);
|
||||
|
||||
static uint16_t has_features_handle;
|
||||
static uint16_t has_control_point_handle;
|
||||
static uint16_t has_preset_index_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t has_features_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t has_control_point_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t has_preset_index_handle;
|
||||
|
||||
static struct ble_gatt_svc_def gatt_svc_has[] = {
|
||||
{
|
||||
@@ -204,7 +205,7 @@ int bt_le_nimble_has_init(void)
|
||||
|
||||
LOG_DBG("[N]HasInit[%u]", chr_count);
|
||||
|
||||
gatt_svc_has->characteristics = calloc(chr_count, sizeof(struct ble_gatt_chr_def));
|
||||
gatt_svc_has->characteristics = bt_le_ext_calloc(chr_count, sizeof(struct ble_gatt_chr_def));
|
||||
assert(gatt_svc_has->characteristics);
|
||||
|
||||
has_svc_add_features_chr((void *)(gatt_svc_has->characteristics + 0));
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -76,21 +77,21 @@ LOG_MODULE_REGISTER(LEA_MCS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
#define INC_OTS_CHR_FLAGS_LIST_CP \
|
||||
(BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_WRITE_ENC)
|
||||
|
||||
static uint8_t inc_ots_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t inc_ots_svc_count;
|
||||
|
||||
static struct bt_ots *ots;
|
||||
static uint16_t inc_ots_chr_feature_handle;
|
||||
static uint16_t inc_ots_chr_name_handle;
|
||||
static uint16_t inc_ots_chr_type_handle;
|
||||
static uint16_t inc_ots_chr_size_handle;
|
||||
static uint16_t inc_ots_chr_id_handle;
|
||||
static uint16_t inc_ots_chr_props_handle;
|
||||
static uint16_t inc_ots_chr_action_cp_handle;
|
||||
static uint16_t inc_ots_chr_list_cp_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct bt_ots *ots;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_feature_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_name_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_type_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_size_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_props_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_action_cp_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t inc_ots_chr_list_cp_handle;
|
||||
|
||||
static struct ble_gatt_svc_def *gatt_svc_inc_ots;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def *gatt_svc_inc_ots;
|
||||
|
||||
static struct ble_gatt_svc_def **gmcs_inc_svcs;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def **gmcs_inc_svcs;
|
||||
|
||||
static const ble_uuid16_t inc_ots_uuid_svc = BLE_UUID16_INIT(BT_UUID_OTS_VAL);
|
||||
static const ble_uuid16_t inc_ots_uuid_feature = BLE_UUID16_INIT(BT_UUID_OTS_FEATURE_VAL);
|
||||
@@ -103,34 +104,34 @@ static const ble_uuid16_t inc_ots_uuid_action_cp = BLE_UUID16_INIT(BT_UUID_OTS_A
|
||||
static const ble_uuid16_t inc_ots_uuid_list_cp = BLE_UUID16_INIT(BT_UUID_OTS_LIST_CP_VAL);
|
||||
#endif /* CONFIG_BT_OTS */
|
||||
|
||||
static uint16_t mcs_player_name_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_player_name_handle;
|
||||
#if CONFIG_BT_OTS
|
||||
static uint16_t mcs_icon_obj_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_icon_obj_id_handle;
|
||||
#endif /* CONFIG_BT_OTS */
|
||||
static uint16_t mcs_icon_url_handle;
|
||||
static uint16_t mcs_track_changed_handle;
|
||||
static uint16_t mcs_track_title_handle;
|
||||
static uint16_t mcs_track_duration_handle;
|
||||
static uint16_t mcs_track_position_handle;
|
||||
static uint16_t mcs_playback_speed_handle;
|
||||
static uint16_t mcs_seeking_speed_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_icon_url_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_track_changed_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_track_title_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_track_duration_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_track_position_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_playback_speed_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_seeking_speed_handle;
|
||||
#if CONFIG_BT_OTS
|
||||
static uint16_t mcs_track_segments_obj_id_handle;
|
||||
static uint16_t mcs_current_track_obj_id_handle;
|
||||
static uint16_t mcs_next_track_obj_id_handle;
|
||||
static uint16_t mcs_parent_group_obj_id_handle;
|
||||
static uint16_t mcs_current_group_obj_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_track_segments_obj_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_current_track_obj_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_next_track_obj_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_parent_group_obj_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_current_group_obj_id_handle;
|
||||
#endif /* CONFIG_BT_OTS */
|
||||
static uint16_t mcs_playing_order_handle;
|
||||
static uint16_t mcs_playing_orders_handle;
|
||||
static uint16_t mcs_media_state_handle;
|
||||
static uint16_t mcs_media_control_point_handle;
|
||||
static uint16_t mcs_media_control_opcodes_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_playing_order_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_playing_orders_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_media_state_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_media_control_point_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_media_control_opcodes_handle;
|
||||
#if CONFIG_BT_OTS
|
||||
static uint16_t mcs_search_control_point_handle;
|
||||
static uint16_t mcs_search_results_obj_id_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_search_control_point_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mcs_search_results_obj_id_handle;
|
||||
#endif /* CONFIG_BT_OTS */
|
||||
static uint16_t ccid_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t ccid_handle;
|
||||
|
||||
static struct ble_gatt_svc_def gatt_svc_gmcs[] = {
|
||||
{
|
||||
@@ -355,7 +356,7 @@ static struct ble_gatt_svc_def gatt_svc_gmcs[] = {
|
||||
/* Discrete MCS (0x1848): INSTANCE_COUNT instances sharing GMCS's characteristic table
|
||||
* and OTS include (val_handle vars are write-only here, so sharing is safe). Built in
|
||||
* bt_le_nimble_mcs_init as an N+1 NULL-terminated array for the GATT DB lifetime. */
|
||||
static struct ble_gatt_svc_def *gatt_svc_mcs;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def *gatt_svc_mcs;
|
||||
static const ble_uuid16_t mcs_uuid_svc = BLE_UUID16_INIT(BT_UUID_MCS_VAL);
|
||||
|
||||
#if CONFIG_BT_OTS
|
||||
@@ -574,7 +575,7 @@ static int inc_ots_svc_init(void)
|
||||
svc->includes = NULL;
|
||||
|
||||
/* An additional characteristic consist of all 0s indicating end of characteristics */
|
||||
svc->characteristics = calloc(INC_OTS_CHR_COUNT + 1, sizeof(struct ble_gatt_chr_def));
|
||||
svc->characteristics = bt_le_ext_calloc(INC_OTS_CHR_COUNT + 1, sizeof(struct ble_gatt_chr_def));
|
||||
assert(svc->characteristics);
|
||||
|
||||
/* Characteristic - OTS Feature */
|
||||
@@ -640,11 +641,11 @@ int bt_le_nimble_gmcs_init(bool ots_included)
|
||||
inc_ots_svc_count = 1;
|
||||
|
||||
/* Extra one for terminating the included service array with NULL */
|
||||
gmcs_inc_svcs = calloc(2, sizeof(struct ble_gatt_svc_def *));
|
||||
gmcs_inc_svcs = bt_le_ext_calloc(2, sizeof(struct ble_gatt_svc_def *));
|
||||
assert(gmcs_inc_svcs);
|
||||
|
||||
/* Extra one for terminating the OTS service array */
|
||||
gatt_svc_inc_ots = calloc(2, sizeof(struct ble_gatt_svc_def));
|
||||
gatt_svc_inc_ots = bt_le_ext_calloc(2, sizeof(struct ble_gatt_svc_def));
|
||||
assert(gatt_svc_inc_ots);
|
||||
|
||||
ots = lib_mcs_get_ots();
|
||||
@@ -809,7 +810,7 @@ int bt_le_nimble_mcs_init(void)
|
||||
|
||||
/* One ble_gatt_svc_def per instance + a zeroed terminator. Persists for the
|
||||
* GATT DB lifetime (NimBLE references these defs until ble_gatts_start). */
|
||||
gatt_svc_mcs = calloc(count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
gatt_svc_mcs = bt_le_ext_calloc(count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
assert(gatt_svc_mcs);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -52,9 +53,9 @@ LOG_MODULE_REGISTER(LEA_MICS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
(BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_WRITE_NO_RSP | \
|
||||
BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC)
|
||||
|
||||
static uint8_t inc_aics_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t inc_aics_svc_count;
|
||||
|
||||
static struct inc_aics_inst {
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_aics_inst {
|
||||
struct bt_gatt_service *svc_p;
|
||||
uint16_t state_handle;
|
||||
uint16_t gain_handle;
|
||||
@@ -64,7 +65,7 @@ static struct inc_aics_inst {
|
||||
uint16_t description_handle;
|
||||
} *inc_aics_insts;
|
||||
|
||||
static struct ble_gatt_svc_def *gatt_svc_inc_aics;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def *gatt_svc_inc_aics;
|
||||
|
||||
static const ble_uuid16_t inc_aics_uuid_svc = BLE_UUID16_INIT(BT_UUID_AICS_VAL);
|
||||
static const ble_uuid16_t inc_aics_uuid_state = BLE_UUID16_INIT(BT_UUID_AICS_STATE_VAL);
|
||||
@@ -74,9 +75,9 @@ static const ble_uuid16_t inc_aics_uuid_status = BLE_UUID16_INIT(BT_UUID_AICS_IN
|
||||
static const ble_uuid16_t inc_aics_uuid_control = BLE_UUID16_INIT(BT_UUID_AICS_CONTROL_VAL);
|
||||
static const ble_uuid16_t inc_aics_uuid_description = BLE_UUID16_INIT(BT_UUID_AICS_DESCRIPTION_VAL);
|
||||
|
||||
static struct ble_gatt_svc_def **mics_inc_svcs;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def **mics_inc_svcs;
|
||||
|
||||
static uint16_t mics_mute_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t mics_mute_handle;
|
||||
|
||||
static struct ble_gatt_svc_def gatt_svc_mics[] = {
|
||||
{
|
||||
@@ -305,7 +306,7 @@ static void inc_aics_svc_init(struct inc_aics_inst *inst,
|
||||
svc->uuid = &inc_aics_uuid_svc.u;
|
||||
svc->includes = NULL;
|
||||
|
||||
svc->characteristics = calloc(INC_AICS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
svc->characteristics = bt_le_ext_calloc(INC_AICS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
assert(svc->characteristics);
|
||||
|
||||
/* Characteristic - Audio Input State */
|
||||
@@ -369,16 +370,16 @@ int bt_le_nimble_mics_init(void *micp_inc)
|
||||
/* Extra one for terminating the included service array with NULL */
|
||||
inc_count = inc_aics_svc_count + 1;
|
||||
|
||||
mics_inc_svcs = calloc(inc_count, sizeof(struct ble_gatt_svc_def *));
|
||||
mics_inc_svcs = bt_le_ext_calloc(inc_count, sizeof(struct ble_gatt_svc_def *));
|
||||
assert(mics_inc_svcs);
|
||||
|
||||
/* MICS may include zero or more instances of AICS */
|
||||
if (inc_aics_svc_count) {
|
||||
inc_aics_insts = calloc(inc_aics_svc_count, sizeof(struct inc_aics_inst));
|
||||
inc_aics_insts = bt_le_ext_calloc(inc_aics_svc_count, sizeof(struct inc_aics_inst));
|
||||
assert(inc_aics_insts);
|
||||
|
||||
/* Extra one for terminating the AICS service array */
|
||||
gatt_svc_inc_aics = calloc(inc_aics_svc_count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
gatt_svc_inc_aics = bt_le_ext_calloc(inc_aics_svc_count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
assert(gatt_svc_inc_aics);
|
||||
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
|
||||
@@ -24,27 +24,28 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_PACS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
#if CONFIG_BT_PAC_SNK
|
||||
static uint16_t pacs_snk_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t pacs_snk_handle;
|
||||
#if CONFIG_BT_PAC_SNK_LOC
|
||||
static uint16_t pacs_snk_loc_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t pacs_snk_loc_handle;
|
||||
#endif /* CONFIG_BT_PAC_SNK_LOC */
|
||||
#endif /* CONFIG_BT_PAC_SNK */
|
||||
|
||||
#if CONFIG_BT_PAC_SRC
|
||||
static uint16_t pacs_src_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t pacs_src_handle;
|
||||
#if CONFIG_BT_PAC_SRC_LOC
|
||||
static uint16_t pacs_src_loc_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t pacs_src_loc_handle;
|
||||
#endif /* CONFIG_BT_PAC_SRC_LOC */
|
||||
#endif /* CONFIG_BT_PAC_SRC */
|
||||
|
||||
static uint16_t pacs_ava_ctx_handle;
|
||||
static uint16_t pacs_sup_ctx_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t pacs_ava_ctx_handle;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint16_t pacs_sup_ctx_handle;
|
||||
|
||||
static const struct ble_gatt_svc_def gatt_svc_pacs[] = {
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
#include "common/audio_attr.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -49,9 +50,9 @@ LOG_MODULE_REGISTER(LEA_VCS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
(BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_WRITE_NO_RSP | \
|
||||
BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC)
|
||||
|
||||
static uint8_t inc_vocs_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t inc_vocs_svc_count;
|
||||
|
||||
static struct inc_vocs_inst {
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_vocs_inst {
|
||||
struct bt_gatt_service *svc_p;
|
||||
uint16_t state_handle;
|
||||
uint16_t location_handle;
|
||||
@@ -59,7 +60,7 @@ static struct inc_vocs_inst {
|
||||
uint16_t description_handle;
|
||||
} inc_vocs_insts[VOCS_INST_COUNT];
|
||||
|
||||
static struct ble_gatt_svc_def *gatt_svc_inc_vocs;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def *gatt_svc_inc_vocs;
|
||||
|
||||
static const ble_uuid16_t inc_vocs_uuid_svc = BLE_UUID16_INIT(BT_UUID_VOCS_VAL);
|
||||
static const ble_uuid16_t inc_vocs_uuid_state = BLE_UUID16_INIT(BT_UUID_VOCS_STATE_VAL);
|
||||
@@ -90,9 +91,9 @@ static const ble_uuid16_t inc_vocs_uuid_description = BLE_UUID16_INIT(BT_UUID_VO
|
||||
(BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_WRITE_NO_RSP | \
|
||||
BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC)
|
||||
|
||||
static uint8_t inc_aics_svc_count;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR uint8_t inc_aics_svc_count;
|
||||
|
||||
static struct inc_aics_inst {
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct inc_aics_inst {
|
||||
struct bt_gatt_service *svc_p;
|
||||
uint16_t state_handle;
|
||||
uint16_t gain_handle;
|
||||
@@ -102,7 +103,7 @@ static struct inc_aics_inst {
|
||||
uint16_t description_handle;
|
||||
} inc_aics_insts[AICS_INST_COUNT];
|
||||
|
||||
static struct ble_gatt_svc_def *gatt_svc_inc_aics;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def *gatt_svc_inc_aics;
|
||||
|
||||
static const ble_uuid16_t inc_aics_uuid_svc = BLE_UUID16_INIT(BT_UUID_AICS_VAL);
|
||||
static const ble_uuid16_t inc_aics_uuid_state = BLE_UUID16_INIT(BT_UUID_AICS_STATE_VAL);
|
||||
@@ -112,7 +113,7 @@ static const ble_uuid16_t inc_aics_uuid_status = BLE_UUID16_INIT(BT_UUID_AICS_IN
|
||||
static const ble_uuid16_t inc_aics_uuid_control = BLE_UUID16_INIT(BT_UUID_AICS_CONTROL_VAL);
|
||||
static const ble_uuid16_t inc_aics_uuid_description = BLE_UUID16_INIT(BT_UUID_AICS_DESCRIPTION_VAL);
|
||||
|
||||
static struct ble_gatt_svc_def **vcs_inc_svcs;
|
||||
static BT_AUDIO_EXT_RAM_BSS_ATTR struct ble_gatt_svc_def **vcs_inc_svcs;
|
||||
|
||||
static struct ble_gatt_svc_def gatt_svc_vcs[] = {
|
||||
{
|
||||
@@ -448,7 +449,7 @@ static void inc_vocs_svc_init(struct inc_vocs_inst *inst,
|
||||
svc->uuid = &inc_vocs_uuid_svc.u;
|
||||
svc->includes = NULL;
|
||||
|
||||
svc->characteristics = calloc(INC_VOCS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
svc->characteristics = bt_le_ext_calloc(INC_VOCS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
assert(svc->characteristics);
|
||||
|
||||
/* Characteristic - Volume Offset State */
|
||||
@@ -501,7 +502,7 @@ static void inc_aics_svc_init(struct inc_aics_inst *inst,
|
||||
svc->uuid = &inc_aics_uuid_svc.u;
|
||||
svc->includes = NULL;
|
||||
|
||||
svc->characteristics = calloc(INC_AICS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
svc->characteristics = bt_le_ext_calloc(INC_AICS_CHR_COUNT, sizeof(struct ble_gatt_chr_def));
|
||||
assert(svc->characteristics);
|
||||
|
||||
/* Characteristic - Audio Input State */
|
||||
@@ -569,13 +570,13 @@ int bt_le_nimble_vcs_init(void *vcp_inc)
|
||||
/* Extra one for terminating the included service array with NULL */
|
||||
inc_count = inc_vocs_svc_count + inc_aics_svc_count + 1;
|
||||
|
||||
vcs_inc_svcs = calloc(inc_count, sizeof(struct ble_gatt_svc_def *));
|
||||
vcs_inc_svcs = bt_le_ext_calloc(inc_count, sizeof(struct ble_gatt_svc_def *));
|
||||
assert(vcs_inc_svcs);
|
||||
|
||||
/* VCS may include zero or more instances of VOCS */
|
||||
if (inc_vocs_svc_count) {
|
||||
/* Extra one for terminating the VOCS service array */
|
||||
gatt_svc_inc_vocs = calloc(inc_vocs_svc_count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
gatt_svc_inc_vocs = bt_le_ext_calloc(inc_vocs_svc_count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
assert(gatt_svc_inc_vocs);
|
||||
|
||||
for (size_t i = 0; i < inc_vocs_svc_count; i++) {
|
||||
@@ -612,7 +613,7 @@ int bt_le_nimble_vcs_init(void *vcp_inc)
|
||||
/* VCS may include zero or more instances of AICS */
|
||||
if (inc_aics_svc_count) {
|
||||
/* Extra one for terminating the AICS service array */
|
||||
gatt_svc_inc_aics = calloc(inc_aics_svc_count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
gatt_svc_inc_aics = bt_le_ext_calloc(inc_aics_svc_count + 1, sizeof(struct ble_gatt_svc_def));
|
||||
assert(gatt_svc_inc_aics);
|
||||
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
|
||||
@@ -123,7 +123,7 @@ static int gatts_access_cb(uint16_t conn_handle, uint16_t attr_handle,
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
data = calloc(1, alloc_len);
|
||||
data = bt_le_ext_calloc(1, alloc_len);
|
||||
assert(data);
|
||||
|
||||
rc = os_mbuf_copydata(ctx->om, 0, OS_MBUF_PKTLEN(ctx->om), data);
|
||||
@@ -136,7 +136,7 @@ static int gatts_access_cb(uint16_t conn_handle, uint16_t attr_handle,
|
||||
} else {
|
||||
LOG_DBG("[N]Wr[%u]", OS_MBUF_PKTLEN(ctx->om));
|
||||
|
||||
data = calloc(1, OS_MBUF_PKTLEN(ctx->om));
|
||||
data = bt_le_ext_calloc(1, OS_MBUF_PKTLEN(ctx->om));
|
||||
assert(data);
|
||||
|
||||
rc = os_mbuf_copydata(ctx->om, 0, OS_MBUF_PKTLEN(ctx->om), data);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
/* Static (.bss) placement markers for esp_ble_audio source files. Host-neutral:
|
||||
* used by the bluedroid adapter profiles AND the host-agnostic OTS service, so
|
||||
* it lives in the audio component's common include (not under bluedroid/).
|
||||
*
|
||||
* Distinct from esp_ble_iso's utils/iso_attr.h in both name and include prefix, so
|
||||
* neither collides on the bt component's shared flat include path.
|
||||
*
|
||||
* - BT_AUDIO_EXT_RAM_BSS_ATTR: eligible for external SPIRAM (cold, task-context,
|
||||
* non-DMA). Moves to PSRAM when BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY is set, else
|
||||
* expands to nothing.
|
||||
* - BT_AUDIO_CTRL_BSS_ATTR: must stay in internal DRAM (marker only).
|
||||
*
|
||||
* net_buf pools (NET_BUF_POOL_FIXED_DEFINE / NET_BUF_SIMPLE_DEFINE_STATIC) hide
|
||||
* their .bss backing behind auto-generated names and cannot take a per-variable
|
||||
* attribute; those objects (e.g. ots_l2cap) are moved via the linker fragment in
|
||||
* linker_common.lf instead.
|
||||
*/
|
||||
#if CONFIG_BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY
|
||||
#define BT_AUDIO_EXT_RAM_BSS_ATTR EXT_RAM_BSS_ATTR
|
||||
#else
|
||||
#define BT_AUDIO_EXT_RAM_BSS_ATTR
|
||||
#endif
|
||||
|
||||
#define BT_AUDIO_CTRL_BSS_ATTR
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <../host/conn_internal.h>
|
||||
#include <../host/hci_core.h>
|
||||
|
||||
#include "utils/mem.h"
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "bluedroid/init.h"
|
||||
#else
|
||||
@@ -1227,8 +1229,13 @@ static const struct lib_ext_funcs ext_funcs = {
|
||||
|
||||
._assert = (void *)assert_fatal,
|
||||
|
||||
#if CONFIG_BT_AUDIO_HEAP_EXTERNAL_MEMORY
|
||||
._malloc = (void *)bt_le_ext_malloc,
|
||||
._calloc = (void *)bt_le_ext_calloc,
|
||||
#else
|
||||
._malloc = (void *)malloc,
|
||||
._calloc = (void *)calloc,
|
||||
#endif
|
||||
._free = (void *)free,
|
||||
|
||||
._rand = (void *)bt_rand,
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# BLE Audio external-RAM (.bss -> PSRAM) link-time placement.
|
||||
#
|
||||
# The bt_extram_bss scheme and bt_bss/bt_common sections referenced below are
|
||||
# defined in the component's linker_common.lf. ldgen merges all registered
|
||||
# fragments into one model, so the cross-file reference resolves.
|
||||
|
||||
# Prebuilt archive: EXT_RAM_BSS_ATTR can't apply at its compile time, so move
|
||||
# its .bss to SPIRAM at link time instead.
|
||||
[mapping:ble_audio]
|
||||
archive: libble_audio.a
|
||||
entries:
|
||||
if BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY = y:
|
||||
* (bt_extram_bss)
|
||||
|
||||
# Move the OTS objects' .bss to SPIRAM at link time (their net_buf pools can't
|
||||
# take a per-var attr). Gates mirror CMakeLists so no entry names an object
|
||||
# that isn't built.
|
||||
[mapping:ble_audio_ots]
|
||||
archive: libbt.a
|
||||
entries:
|
||||
if BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY = y && (BT_OTS = y || BT_OTS_CLIENT = y):
|
||||
ots_l2cap (bt_extram_bss)
|
||||
if BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY = y && BT_OTS = y:
|
||||
ots (bt_extram_bss)
|
||||
ots_oacp (bt_extram_bss)
|
||||
ots_obj_manager (bt_extram_bss)
|
||||
ots_olcp (bt_extram_bss)
|
||||
if BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY = y && BT_OTS = y && BT_OTS_DIR_LIST_OBJ = y:
|
||||
ots_dir_list (bt_extram_bss)
|
||||
if BT_AUDIO_BSS_SEG_EXTERNAL_MEMORY = y && BT_OTS_CLIENT = y:
|
||||
ots_client (bt_extram_bss)
|
||||
@@ -48,9 +48,10 @@ list(APPEND ble_iso_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/bt_str.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/buf.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/crypto.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/keys.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/mem.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/timer.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/utf8.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/utils.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/uuid.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/iso/iso.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/api/esp_ble_iso_common_api.c"
|
||||
@@ -74,6 +75,7 @@ endif()
|
||||
list(APPEND ble_iso_include_dirs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/api/include"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/common/include"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/utils/include"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include/subsys/bluetooth"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include/subsys/bluetooth/host"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include"
|
||||
|
||||
@@ -104,6 +104,38 @@ if BT_ISO
|
||||
|
||||
endif # BT_ISO_BROADCAST
|
||||
|
||||
config BT_ISO_BSS_SEG_EXTERNAL_MEMORY
|
||||
bool "Place BLE ISO .bss segment in external SPIRAM"
|
||||
depends on SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
default n
|
||||
help
|
||||
Place the zero-initialized (.bss) static data of the esp_ble_iso
|
||||
component in external SPIRAM instead of internal DRAM, to free
|
||||
internal RAM.
|
||||
|
||||
Safe because the esp_ble_iso sources register no IRAM ISRs: their
|
||||
data is only touched in task context, never while the flash cache
|
||||
is disabled. Hot ISO data-path state that must stay internal for
|
||||
latency is excluded at each placement site, not by this switch.
|
||||
|
||||
Requires SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY (which makes SPIRAM
|
||||
mandatory at boot). Only .bss is moved; initialized (.data) statistics
|
||||
stay internal.
|
||||
|
||||
config BT_ISO_HEAP_EXTERNAL_MEMORY
|
||||
bool "Place BLE ISO heap allocations in external SPIRAM"
|
||||
depends on SPIRAM
|
||||
default n
|
||||
help
|
||||
Route esp_ble_iso runtime heap allocations (control-plane only:
|
||||
GATT/GAP event marshalling, CIS/CIG setup params, CCC pools) to
|
||||
external SPIRAM via heap_caps_*(MALLOC_CAP_SPIRAM) instead of the
|
||||
internal heap.
|
||||
|
||||
The real-time ISO data path (TX/RX SDU packet buffers) is excluded
|
||||
at each allocation site and stays in internal DRAM. On SPIRAM
|
||||
exhaustion the allocation returns NULL (no internal fallback).
|
||||
|
||||
config BT_ISO_DISPATCH_MONITOR
|
||||
bool "Monitor ISO task callback dispatch latency"
|
||||
depends on !BT_ISO_NO_LOG
|
||||
|
||||
@@ -63,7 +63,9 @@ extern void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
|
||||
* matching the NimBLE host contract; then both this tracker and the
|
||||
* synthesis below become dead code. */
|
||||
#define ISO_PA_SYNC_HANDLE_NONE 0xFFFF
|
||||
static uint16_t active_pa_sync_handle = ISO_PA_SYNC_HANDLE_NONE;
|
||||
/* Reset in bt_le_bluedroid_gap_init() (not static init) so a deinit/init cycle
|
||||
* restarts from "no active sync"; static init runs only once at boot. */
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR uint16_t active_pa_sync_handle;
|
||||
#endif /* BLE_50_EXTEND_SYNC_EN == TRUE */
|
||||
|
||||
/* Fast-path BTA → iso-queue post.
|
||||
@@ -151,7 +153,7 @@ void bt_le_bluedroid_gap_post_event(uint16_t event, void *param)
|
||||
struct bt_le_gap_app_param *qev = NULL;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
/* Only AUTH_CMPL reaches here from the application's
|
||||
@@ -231,7 +233,7 @@ static void bt_le_bluedroid_gap_post_event_bta(tBTA_DM_BLE_5_GAP_EVENT event,
|
||||
enum iso_queue_item_type q_type;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
switch (event) {
|
||||
@@ -255,7 +257,7 @@ static void bt_le_bluedroid_gap_post_event_bta(tBTA_DM_BLE_5_GAP_EVENT event,
|
||||
qev->ext_scan_recv.data_len = r->adv_data_len;
|
||||
|
||||
if (qev->ext_scan_recv.data_len) {
|
||||
qev->ext_scan_recv.data = calloc(1, qev->ext_scan_recv.data_len);
|
||||
qev->ext_scan_recv.data = bt_le_ext_calloc(1, qev->ext_scan_recv.data_len);
|
||||
assert(qev->ext_scan_recv.data);
|
||||
memcpy(qev->ext_scan_recv.data, r->adv_data, qev->ext_scan_recv.data_len);
|
||||
}
|
||||
@@ -344,7 +346,7 @@ static void bt_le_bluedroid_gap_post_event_bta(tBTA_DM_BLE_5_GAP_EVENT event,
|
||||
qev->pa_sync_recv.data_len = r->data_length;
|
||||
|
||||
if (qev->pa_sync_recv.data_len) {
|
||||
qev->pa_sync_recv.data = calloc(1, qev->pa_sync_recv.data_len);
|
||||
qev->pa_sync_recv.data = bt_le_ext_calloc(1, qev->pa_sync_recv.data_len);
|
||||
assert(qev->pa_sync_recv.data);
|
||||
memcpy(qev->pa_sync_recv.data, r->data, qev->pa_sync_recv.data_len);
|
||||
}
|
||||
@@ -557,6 +559,10 @@ int bt_le_bluedroid_scan_stop(void)
|
||||
|
||||
int bt_le_bluedroid_gap_init(void)
|
||||
{
|
||||
#if (BLE_50_EXTEND_SYNC_EN == TRUE)
|
||||
active_pa_sync_handle = ISO_PA_SYNC_HANDLE_NONE;
|
||||
#endif
|
||||
|
||||
BTM_BleGapRegisterCallback(gap_app_cb);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -34,39 +34,29 @@ LOG_MODULE_REGISTER(ISO_BGAT, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
* module that follows this pattern. */
|
||||
#define GATTS_APP_UUID_BYTE 0x98
|
||||
|
||||
static const tBT_UUID gatts_app_uuid = {
|
||||
.len = LEN_UUID_128,
|
||||
.uu.uuid128 = {
|
||||
[0 ... 15] = GATTS_APP_UUID_BYTE,
|
||||
},
|
||||
};
|
||||
static tBTA_GATTS_IF gatts_if;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR tBT_UUID gatts_app_uuid;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR tBTA_GATTS_IF gatts_if;
|
||||
|
||||
/* Use UUID with a fixed pattern 0x99 for ISO & LE Audio GATT Client */
|
||||
#define GATTC_APP_UUID_BYTE 0x99
|
||||
|
||||
static tBT_UUID gattc_app_uuid = {
|
||||
.len = LEN_UUID_128,
|
||||
.uu.uuid128 = {
|
||||
[0 ... 15] = GATTC_APP_UUID_BYTE,
|
||||
},
|
||||
};
|
||||
static tBTA_GATTC_IF gattc_if;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR tBT_UUID gattc_app_uuid;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR tBTA_GATTC_IF gattc_if;
|
||||
|
||||
static struct gatts_svc_cb *gatts_svc_cb;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct gatts_svc_cb *gatts_svc_cb;
|
||||
|
||||
static struct gatt_conn gatt_conns[CONFIG_BT_MAX_CONN];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct gatt_conn gatt_conns[CONFIG_BT_MAX_CONN];
|
||||
|
||||
/* Sems block bt_le_bluedroid_gatt_init() until the BTA app registrations
|
||||
* report back. gatts_sem is also reused by the audio adapter — only one
|
||||
* gatts_svc_cb is registered at a time, so sequential reuse is safe. */
|
||||
static struct k_sem gatts_sem;
|
||||
static struct k_sem gattc_sem;
|
||||
static BT_ISO_CTRL_BSS_ATTR struct k_sem gatts_sem;
|
||||
static BT_ISO_CTRL_BSS_ATTR struct k_sem gattc_sem;
|
||||
|
||||
/* Set by deinit before deleting the sems so a late BTA_*_REG_EVT skips the
|
||||
* give on a deleted handle. Same accepted residual race as hci.c's
|
||||
* direct_hci_shutting_down; the init-timeout window is near-unreachable. */
|
||||
static volatile bool gatt_shutting_down;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR volatile bool gatt_shutting_down;
|
||||
|
||||
enum {
|
||||
GATTC_OP_READ,
|
||||
@@ -90,7 +80,7 @@ static struct gattc_list_node *gattc_list_node_alloc(uint8_t type, void *params)
|
||||
{
|
||||
struct gattc_list_node *op;
|
||||
|
||||
op = calloc(1, sizeof(*op));
|
||||
op = bt_le_ext_calloc(1, sizeof(*op));
|
||||
if (op == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -180,7 +170,7 @@ static struct gatts_list_node *gatts_list_node_alloc(struct bt_gatt_indicate_par
|
||||
{
|
||||
struct gatts_list_node *n;
|
||||
|
||||
n = calloc(1, sizeof(*n));
|
||||
n = bt_le_ext_calloc(1, sizeof(*n));
|
||||
if (n == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -193,7 +183,7 @@ static struct gatts_list_node *gatts_list_node_alloc(struct bt_gatt_indicate_par
|
||||
if (ip->len > 0) {
|
||||
assert(ip->data);
|
||||
|
||||
n->data_copy = malloc(ip->len);
|
||||
n->data_copy = bt_le_ext_malloc(ip->len);
|
||||
if (n->data_copy == NULL) {
|
||||
free(n);
|
||||
return NULL;
|
||||
@@ -444,7 +434,7 @@ static void gattc_connect_event_handler(tBTA_GATTC_CONNECT *connect)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_CONNECT_EVENT;
|
||||
@@ -467,7 +457,7 @@ static void gattc_disconnect_event_handler(tBTA_GATTC_DISCONNECT *disconnect)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_DISCONNECT_EVENT;
|
||||
@@ -487,7 +477,7 @@ static void gattc_open_event_handler(tBTA_GATTC_OPEN *open)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_OPEN_EVENT;
|
||||
@@ -507,7 +497,7 @@ static void gattc_mtu_event_handler(tBTA_GATTC_CFG_MTU *cfg_mtu)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_MTU_EVENT;
|
||||
@@ -528,7 +518,7 @@ static void gattc_disc_cmpl_event_handler(tBTA_GATTC_DIS_CMPL *disc_cmpl)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_DISC_CMPL_EVENT;
|
||||
@@ -548,7 +538,7 @@ static void gattc_read_chrc_event_handler(tBTA_GATTC_READ *read)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_READ_CHRC_EVENT;
|
||||
@@ -562,7 +552,7 @@ static void gattc_read_chrc_event_handler(tBTA_GATTC_READ *read)
|
||||
read->p_value->p_value) {
|
||||
qev->gattc_read_chrc.len = read->p_value->len;
|
||||
|
||||
qev->gattc_read_chrc.value = calloc(1, read->p_value->len);
|
||||
qev->gattc_read_chrc.value = bt_le_ext_calloc(1, read->p_value->len);
|
||||
assert(qev->gattc_read_chrc.value);
|
||||
|
||||
memcpy(qev->gattc_read_chrc.value, read->p_value->p_value, read->p_value->len);
|
||||
@@ -583,7 +573,7 @@ static void gattc_write_chrc_event_handler(tBTA_GATTC_WRITE *write)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_WRITE_CHRC_EVENT;
|
||||
@@ -605,7 +595,7 @@ static void gatts_notify_tx_event_handler(tBTA_GATTS_REQ *req)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTS_NOTIFY_TX_EVENT;
|
||||
@@ -632,7 +622,7 @@ static void gattc_notify_rx_event_handler(tBTA_GATTC_NOTIFY *notify)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_NOTIFY_RX_EVENT;
|
||||
@@ -644,7 +634,7 @@ static void gattc_notify_rx_event_handler(tBTA_GATTC_NOTIFY *notify)
|
||||
if (notify->len) {
|
||||
qev->gattc_notify_rx.len = notify->len;
|
||||
|
||||
qev->gattc_notify_rx.value = calloc(1, notify->len);
|
||||
qev->gattc_notify_rx.value = bt_le_ext_calloc(1, notify->len);
|
||||
assert(qev->gattc_notify_rx.value);
|
||||
|
||||
memcpy(qev->gattc_notify_rx.value, notify->value, notify->len);
|
||||
@@ -665,7 +655,7 @@ static void gatts_connect_event_handler(tBTA_GATTS_CONN *connect)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTS_CONNECT_EVENT;
|
||||
@@ -688,7 +678,7 @@ static void gatts_disconnect_event_handler(tBTA_GATTS_CONN *disconnect)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTS_DISCONNECT_EVENT;
|
||||
@@ -709,7 +699,7 @@ static void gatts_mtu_event_handler(tBTA_GATTS_REQ *req)
|
||||
int err;
|
||||
|
||||
/* req->p_data is non-NULL here: BTA always passes a stack object. */
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTS_MTU_EVENT;
|
||||
@@ -729,7 +719,7 @@ static void gatts_read_req_handler(tBTA_GATTS_REQ *req)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTS_READ_EVENT;
|
||||
@@ -755,7 +745,7 @@ static void gatts_write_req_handler(tBTA_GATTS_REQ *req)
|
||||
int err;
|
||||
|
||||
/* req->p_data is non-NULL here: BTA always passes a stack object. */
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTS_WRITE_EVENT;
|
||||
@@ -771,7 +761,7 @@ static void gatts_write_req_handler(tBTA_GATTS_REQ *req)
|
||||
if (req->p_data->write_req.len) {
|
||||
qev->gatts_write.len = req->p_data->write_req.len;
|
||||
|
||||
qev->gatts_write.value = calloc(1, req->p_data->write_req.len);
|
||||
qev->gatts_write.value = bt_le_ext_calloc(1, req->p_data->write_req.len);
|
||||
assert(qev->gatts_write.value);
|
||||
|
||||
memcpy(qev->gatts_write.value, req->p_data->write_req.value, req->p_data->write_req.len);
|
||||
@@ -792,7 +782,7 @@ static void gatts_exec_write_req_handler(tBTA_GATTS_REQ *req)
|
||||
struct bt_le_gatt_event_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTS_EXEC_WRITE_EVENT;
|
||||
@@ -1378,7 +1368,7 @@ static void post_acl_connect_app_event(struct gatt_conn *gatt_conn)
|
||||
struct bt_le_gap_app_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GAP_APP_PARAM_ACL_CONNECT;
|
||||
@@ -1406,7 +1396,7 @@ static void post_acl_disconnect_app_event(uint16_t conn_handle, uint8_t reason)
|
||||
struct bt_le_gap_app_param *qev;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GAP_APP_PARAM_ACL_DISCONNECT;
|
||||
@@ -1982,7 +1972,7 @@ static void handle_gatts_read_event(struct bt_le_gatts_read_event *event)
|
||||
/* The tBTA_GATT_STATUS structure is too large, hence use
|
||||
* dynamic memory here to avoid stack overflow.
|
||||
*/
|
||||
rsp = calloc(1, sizeof(*(rsp)));
|
||||
rsp = bt_le_ext_calloc(1, sizeof(*(rsp)));
|
||||
assert(rsp);
|
||||
|
||||
rsp->attr_value.handle = event->attr_handle;
|
||||
@@ -2078,7 +2068,7 @@ static void handle_gatts_prepare_write(struct bt_le_gatts_write_event *event)
|
||||
|
||||
if (status == BTA_GATT_OK) {
|
||||
/* The prepare-write response must echo handle/offset/value. */
|
||||
rsp = calloc(1, sizeof(*rsp));
|
||||
rsp = bt_le_ext_calloc(1, sizeof(*rsp));
|
||||
assert(rsp);
|
||||
|
||||
rsp->attr_value.handle = event->attr_handle;
|
||||
@@ -2553,7 +2543,7 @@ static int gatts_notify_enqueue(struct bt_conn *conn, uint16_t value_handle)
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
n = calloc(1, sizeof(*n));
|
||||
n = bt_le_ext_calloc(1, sizeof(*n));
|
||||
if (n == NULL) {
|
||||
LOG_ERR("[B]GattsNotifyNodeAllocFail[%u]", conn->handle);
|
||||
return -ENOMEM;
|
||||
@@ -3357,6 +3347,13 @@ int bt_le_bluedroid_gatt_init(void)
|
||||
* └─ btc_transfer_context classic app cb hops to BTC task here
|
||||
*/
|
||||
|
||||
/* Runtime init (not static) so the UUID is restored across a deinit/init
|
||||
* cycle; static init runs only once at boot. */
|
||||
gatts_app_uuid = (tBT_UUID){
|
||||
.len = LEN_UUID_128,
|
||||
.uu.uuid128 = { [0 ... 15] = GATTS_APP_UUID_BYTE },
|
||||
};
|
||||
|
||||
k_sem_reset(&gatts_sem);
|
||||
BTA_GATTS_AppRegister(&gatts_app_uuid, gatts_app_cb);
|
||||
|
||||
@@ -3365,6 +3362,11 @@ int bt_le_bluedroid_gatt_init(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
gattc_app_uuid = (tBT_UUID){
|
||||
.len = LEN_UUID_128,
|
||||
.uu.uuid128 = { [0 ... 15] = GATTC_APP_UUID_BYTE },
|
||||
};
|
||||
|
||||
k_sem_reset(&gattc_sem);
|
||||
BTA_GATTC_AppRegister(&gattc_app_uuid, gattc_app_cb);
|
||||
|
||||
|
||||
@@ -43,15 +43,15 @@ LOG_MODULE_REGISTER(ISO_BHCI, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
*
|
||||
* Concurrent safety: send_sync is serialized by callers via bt_le_host_lock,
|
||||
* so the static rsp_buf pointer / opcode latch are single-slot. */
|
||||
static struct k_sem direct_hci_sem;
|
||||
static BT_ISO_CTRL_BSS_ATTR struct k_sem direct_hci_sem;
|
||||
|
||||
/* Set by deinit before deleting the sem. Late-arriving cb's must check
|
||||
* this before touching the sem. Residual race exists (cb past the check
|
||||
* but pre-give vs. deinit completing the delete) — accepted in practice
|
||||
* because the BTU/HCI layer offers no way to cancel an in-flight cmd. */
|
||||
static volatile bool direct_hci_shutting_down;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR volatile bool direct_hci_shutting_down;
|
||||
|
||||
static struct {
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct {
|
||||
uint16_t opcode; /* expected — set by caller, verified by cb */
|
||||
uint8_t status; /* HCI status from Command_Complete */
|
||||
} direct_hci_rsp;
|
||||
@@ -64,8 +64,8 @@ static struct {
|
||||
* teardown race. Sized for the largest payload any direct-HCI caller reads
|
||||
* back (SET_CIG: 2 + 2*cis_count, ISO_READ_TX_SYNC: 11). */
|
||||
#define DIRECT_HCI_RSP_MAX MAX(2 + 2 * CONFIG_BT_ISO_MAX_CHAN, 11)
|
||||
static uint8_t direct_hci_rsp_data[DIRECT_HCI_RSP_MAX];
|
||||
static uint8_t direct_hci_rsp_data_len;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR uint8_t direct_hci_rsp_data[DIRECT_HCI_RSP_MAX];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR uint8_t direct_hci_rsp_data_len;
|
||||
|
||||
static void direct_hci_complete_cb(BT_HDR *response, void *context)
|
||||
{
|
||||
|
||||
@@ -47,9 +47,9 @@ LOG_MODULE_REGISTER(ISO_BISO, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
* zero would yield bogus packet_seq_num / cis_handle to the lib).
|
||||
* K_SEM_SHORT must exceed the worst-case BTU dispatch chain. */
|
||||
|
||||
static struct k_sem iso_sem;
|
||||
static BT_ISO_CTRL_BSS_ATTR struct k_sem iso_sem;
|
||||
|
||||
static struct {
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct {
|
||||
uint8_t status;
|
||||
uint16_t conn_handle;
|
||||
uint16_t packet_seq_num;
|
||||
@@ -57,7 +57,7 @@ static struct {
|
||||
uint32_t time_offset;
|
||||
} tx_sync;
|
||||
|
||||
static struct {
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct {
|
||||
uint8_t status;
|
||||
uint8_t cig_id;
|
||||
uint8_t cis_count;
|
||||
@@ -183,7 +183,7 @@ static int hci_cmd_set_cig_params(struct net_buf *buf, struct net_buf **rsp)
|
||||
mtl_c_to_p = sys_get_le16(buf->data + 13);
|
||||
mtl_p_to_c = sys_get_le16(buf->data + 15);
|
||||
|
||||
cis_params = calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params));
|
||||
cis_params = bt_le_ext_calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params));
|
||||
assert(cis_params);
|
||||
|
||||
for (size_t i = 0; i < cis_count; i++) {
|
||||
@@ -301,7 +301,7 @@ static int hci_cmd_set_cig_params_test(struct net_buf *buf, struct net_buf **rsp
|
||||
packing = buf->data[15];
|
||||
framing = buf->data[16];
|
||||
|
||||
cis_params = calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params_test));
|
||||
cis_params = bt_le_ext_calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params_test));
|
||||
assert(cis_params);
|
||||
|
||||
for (size_t i = 0; i < cis_count; i++) {
|
||||
@@ -376,7 +376,7 @@ static int hci_cmd_create_cis(struct net_buf *buf, struct net_buf **rsp)
|
||||
|
||||
cis_count = buf->data[3];
|
||||
|
||||
cis_params = calloc(1, cis_count * sizeof(struct ble_hci_cis_hdls));
|
||||
cis_params = bt_le_ext_calloc(1, cis_count * sizeof(struct ble_hci_cis_hdls));
|
||||
assert(cis_params);
|
||||
|
||||
for (size_t i = 0; i < cis_count; i++) {
|
||||
@@ -858,7 +858,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_disconn_complete ev = {0};
|
||||
|
||||
qdata_len = 2 + sizeof(ev);
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.status = 0x00;
|
||||
@@ -875,7 +875,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_le_cis_established ev = {0};
|
||||
|
||||
qdata_len = 2 + 1 + sizeof(ev);
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.status = iso_hci_status(params->btm_cis_established_evt.status);
|
||||
@@ -906,7 +906,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_le_cis_req ev = {0};
|
||||
|
||||
qdata_len = 2 + 1 + sizeof(ev);
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.acl_handle = params->btm_cis_request_evt.acl_handle;
|
||||
@@ -925,7 +925,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_le_big_complete ev = {0};
|
||||
|
||||
qdata_len = 2 + 1 + sizeof(ev) + params->btm_big_cmpl.num_bis * 2;
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.status = iso_hci_status(params->btm_big_cmpl.status);
|
||||
@@ -956,7 +956,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_le_big_terminate ev = {0};
|
||||
|
||||
qdata_len = 2 + 1 + sizeof(ev);
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.big_handle = params->btm_big_term.big_handle;
|
||||
@@ -973,7 +973,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_le_big_sync_established ev = {0};
|
||||
|
||||
qdata_len = 2 + 1 + sizeof(ev) + params->btm_big_sync_estab.num_bis * 2;
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.status = iso_hci_status(params->btm_big_sync_estab.status);
|
||||
@@ -1002,7 +1002,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_le_big_sync_lost ev = {0};
|
||||
|
||||
qdata_len = 2 + 1 + sizeof(ev);
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.big_handle = params->btm_big_sync_lost.big_handle;
|
||||
@@ -1019,7 +1019,7 @@ static void iso_evt_handler(tBTM_BLE_ISO_EVENT event, tBTM_BLE_ISO_CB_PARAMS *pa
|
||||
struct bt_hci_evt_le_biginfo_adv_report ev = {0};
|
||||
|
||||
qdata_len = 2 + 1 + sizeof(ev);
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
ev.sync_handle = params->btm_biginfo_report.sync_handle;
|
||||
|
||||
@@ -82,7 +82,7 @@ void bt_le_nimble_gap_post_event(void *param)
|
||||
enum iso_queue_item_type q_type;
|
||||
int err;
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
@@ -116,7 +116,7 @@ void bt_le_nimble_gap_post_event(void *param)
|
||||
qev->ext_scan_recv.data_len = ev->ext_disc.length_data;
|
||||
|
||||
if (qev->ext_scan_recv.data_len) {
|
||||
qev->ext_scan_recv.data = calloc(1, qev->ext_scan_recv.data_len);
|
||||
qev->ext_scan_recv.data = bt_le_ext_calloc(1, qev->ext_scan_recv.data_len);
|
||||
assert(qev->ext_scan_recv.data);
|
||||
|
||||
memcpy(qev->ext_scan_recv.data, ev->ext_disc.data, qev->ext_scan_recv.data_len);
|
||||
@@ -171,7 +171,7 @@ void bt_le_nimble_gap_post_event(void *param)
|
||||
qev->pa_sync_recv.data_len = ev->periodic_report.data_length;
|
||||
|
||||
if (qev->pa_sync_recv.data_len) {
|
||||
qev->pa_sync_recv.data = calloc(1, qev->pa_sync_recv.data_len);
|
||||
qev->pa_sync_recv.data = bt_le_ext_calloc(1, qev->pa_sync_recv.data_len);
|
||||
assert(qev->pa_sync_recv.data);
|
||||
|
||||
memcpy(qev->pa_sync_recv.data, ev->periodic_report.data, qev->pa_sync_recv.data_len);
|
||||
|
||||
@@ -44,7 +44,7 @@ void bt_le_nimble_gatt_post_event(void *param)
|
||||
return;
|
||||
}
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
switch (ev->type) {
|
||||
@@ -78,7 +78,7 @@ void bt_le_nimble_gatt_post_event(void *param)
|
||||
uint16_t total_len = OS_MBUF_PKTLEN(ev->notify_rx.om);
|
||||
qev->gattc_notify_rx.len = total_len;
|
||||
|
||||
qev->gattc_notify_rx.value = calloc(1, total_len);
|
||||
qev->gattc_notify_rx.value = bt_le_ext_calloc(1, total_len);
|
||||
assert(qev->gattc_notify_rx.value);
|
||||
|
||||
os_mbuf_copydata(ev->notify_rx.om, 0, total_len, qev->gattc_notify_rx.value);
|
||||
@@ -128,7 +128,7 @@ int bt_le_nimble_gatt_post_disc_event(uint16_t conn_handle, ble_uuid16_t *uuid,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_DISCOVER_EVENT;
|
||||
@@ -155,7 +155,7 @@ int bt_le_nimble_gatt_post_disc_cmpl_event(uint16_t conn_handle, uint8_t status)
|
||||
|
||||
LOG_DBG("[N]GattcDiscCmplEvtHdlr[%u][%02x]", conn_handle, status);
|
||||
|
||||
qev = calloc(1, sizeof(*qev));
|
||||
qev = bt_le_ext_calloc(1, sizeof(*qev));
|
||||
assert(qev);
|
||||
|
||||
qev->type = BT_LE_GATTC_DISC_CMPL_EVENT;
|
||||
|
||||
@@ -104,7 +104,7 @@ struct gattc_db_dsc {
|
||||
sys_snode_t node;
|
||||
};
|
||||
|
||||
static struct gattc_db {
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct gattc_db {
|
||||
uint16_t conn_handle;
|
||||
enum {
|
||||
DISC_IDLE = 0,
|
||||
@@ -113,12 +113,7 @@ static struct gattc_db {
|
||||
DISC_FAIL,
|
||||
} status;
|
||||
sys_slist_t svc_list; /* List of the GATT server database of the connection */
|
||||
} gattc_db[CONFIG_BT_MAX_CONN] = {
|
||||
[0 ...(CONFIG_BT_MAX_CONN - 1)] = {
|
||||
.conn_handle = UINT16_MAX,
|
||||
.status = DISC_IDLE,
|
||||
},
|
||||
};
|
||||
} gattc_db[CONFIG_BT_MAX_CONN];
|
||||
|
||||
static struct gattc_db *gattc_db_add(uint16_t conn_handle)
|
||||
{
|
||||
@@ -186,7 +181,7 @@ static void gattc_db_svc_insert(struct gattc_db *adb, const struct ble_gatt_svc
|
||||
{
|
||||
struct gattc_db_svc *asvc;
|
||||
|
||||
asvc = calloc(1, sizeof(*asvc));
|
||||
asvc = bt_le_ext_calloc(1, sizeof(*asvc));
|
||||
assert(asvc);
|
||||
|
||||
memcpy(&asvc->svc, svc, sizeof(asvc->svc));
|
||||
@@ -202,7 +197,7 @@ static void gattc_db_inc_svc_insert(struct gattc_db_svc *asvc, const struct ble_
|
||||
{
|
||||
struct gattc_db_inc_svc *ainc_svc;
|
||||
|
||||
ainc_svc = calloc(1, sizeof(*ainc_svc));
|
||||
ainc_svc = bt_le_ext_calloc(1, sizeof(*ainc_svc));
|
||||
assert(ainc_svc);
|
||||
|
||||
memcpy(&ainc_svc->svc, inc_svc, sizeof(ainc_svc->svc));
|
||||
@@ -224,7 +219,7 @@ static void gattc_db_chrc_insert(sys_slist_t *chrc_list, const struct ble_gatt_c
|
||||
{
|
||||
struct gattc_db_chrc *achrc;
|
||||
|
||||
achrc = calloc(1, sizeof(*achrc));
|
||||
achrc = bt_le_ext_calloc(1, sizeof(*achrc));
|
||||
assert(achrc);
|
||||
|
||||
memcpy(&achrc->chrc, chrc, sizeof(achrc->chrc));
|
||||
@@ -1475,3 +1470,25 @@ void bt_le_nimble_gattc_db_remove(uint16_t conn_handle)
|
||||
|
||||
gattc_db_del(adb);
|
||||
}
|
||||
|
||||
/* Runtime init (not static): the array is .bss (PSRAM-eligible), so a
|
||||
* deinit/init cycle must restart with every slot free. conn_handle 0 is a
|
||||
* valid handle, so the free marker is UINT16_MAX. */
|
||||
void bt_le_nimble_gattc_db_init(void)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(gattc_db); i++) {
|
||||
gattc_db[i].conn_handle = UINT16_MAX;
|
||||
gattc_db[i].status = DISC_IDLE;
|
||||
sys_slist_init(&gattc_db[i].svc_list);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free each slot's discovery nodes on deinit so an init/deinit/re-init cycle stays
|
||||
* leak-free (mirrors the Bluedroid bt_le_bluedroid_gatt_deinit). gattc_db_del is a
|
||||
* safe no-op on an already-free slot. */
|
||||
void bt_le_nimble_gattc_db_deinit(void)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(gattc_db); i++) {
|
||||
gattc_db_del(&gattc_db[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,15 +79,11 @@ struct gatt_nrp_node {
|
||||
sys_snode_t node;
|
||||
};
|
||||
|
||||
static struct gatt_nrp {
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct gatt_nrp {
|
||||
uint16_t conn_handle;
|
||||
|
||||
sys_slist_t list; /* List of GATT need response pdu (e.g., read req, write req, indication, etc.) */
|
||||
} gatt_nrp[CONFIG_BT_MAX_CONN] = {
|
||||
[0 ...(CONFIG_BT_MAX_CONN - 1)] = {
|
||||
.conn_handle = UINT16_MAX,
|
||||
},
|
||||
};
|
||||
} gatt_nrp[CONFIG_BT_MAX_CONN];
|
||||
|
||||
static struct gatt_nrp *gatt_nrp_find(uint16_t conn_handle);
|
||||
|
||||
@@ -738,7 +734,7 @@ static int gatt_nrp_insert(struct bt_conn *conn, uint8_t type, void *params)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nrp_node = calloc(1, sizeof(*nrp_node));
|
||||
nrp_node = bt_le_ext_calloc(1, sizeof(*nrp_node));
|
||||
assert(nrp_node);
|
||||
|
||||
nrp_node->type = type;
|
||||
@@ -760,7 +756,7 @@ static int gatt_nrp_insert(struct bt_conn *conn, uint8_t type, void *params)
|
||||
nrp_node->write_req.data_copy = NULL;
|
||||
if (wp->length > 0) {
|
||||
assert(wp->data);
|
||||
nrp_node->write_req.data_copy = malloc(wp->length);
|
||||
nrp_node->write_req.data_copy = bt_le_ext_malloc(wp->length);
|
||||
if (nrp_node->write_req.data_copy == NULL) {
|
||||
LOG_ERR("[N]GattNrpWrDataAllocFail[%u]", wp->length);
|
||||
free(nrp_node);
|
||||
@@ -780,7 +776,7 @@ static int gatt_nrp_insert(struct bt_conn *conn, uint8_t type, void *params)
|
||||
nrp_node->indicate.data_copy = NULL;
|
||||
if (ip->len > 0) {
|
||||
assert(ip->data);
|
||||
nrp_node->indicate.data_copy = malloc(ip->len);
|
||||
nrp_node->indicate.data_copy = bt_le_ext_malloc(ip->len);
|
||||
if (nrp_node->indicate.data_copy == NULL) {
|
||||
LOG_ERR("[N]GattNrpIndDataAllocFail[%u]", ip->len);
|
||||
free(nrp_node);
|
||||
@@ -1043,3 +1039,22 @@ void bt_le_nimble_gatt_nrp_clear(uint16_t conn_handle)
|
||||
|
||||
gatt_nrp_del(nrp);
|
||||
}
|
||||
|
||||
/* Runtime init (not static): .bss array (PSRAM-eligible) that a deinit/init
|
||||
* cycle must restart all-free (UINT16_MAX, since conn_handle 0 is valid). */
|
||||
void bt_le_nimble_gatt_nrp_init(void)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(gatt_nrp); i++) {
|
||||
gatt_nrp[i].conn_handle = UINT16_MAX;
|
||||
sys_slist_init(&gatt_nrp[i].list);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free each slot's queued NRP nodes on deinit (mirrors bt_le_nimble_gattc_db_deinit);
|
||||
* gatt_nrp_del is a safe no-op on an already-free slot. */
|
||||
void bt_le_nimble_gatt_nrp_deinit(void)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(gatt_nrp); i++) {
|
||||
gatt_nrp_del(&gatt_nrp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,10 @@ int bt_le_nimble_gattc_db_auto_disc(uint16_t conn_handle);
|
||||
|
||||
void bt_le_nimble_gattc_db_remove(uint16_t conn_handle);
|
||||
|
||||
void bt_le_nimble_gattc_db_init(void);
|
||||
|
||||
void bt_le_nimble_gattc_db_deinit(void);
|
||||
|
||||
enum {
|
||||
GATTC_NRP_READ_BY_UUID,
|
||||
GATTC_NRP_READ_LONG,
|
||||
@@ -113,12 +117,14 @@ void bt_le_nimble_gatts_nrp_indicate_cb(uint16_t conn_handle,
|
||||
|
||||
int bt_le_nimble_gatt_nrp_insert(struct bt_conn *conn, uint8_t type, void *params);
|
||||
|
||||
/* err is forwarded only to the INDICATE func cb; other NRP types invoke their
|
||||
* own func with err in cb_safe and pass 0 here. */
|
||||
int bt_le_nimble_gatt_nrp_remove(struct bt_conn *conn, uint8_t type, void *params, uint8_t err);
|
||||
|
||||
void bt_le_nimble_gatt_nrp_clear(uint16_t conn_handle);
|
||||
|
||||
void bt_le_nimble_gatt_nrp_init(void);
|
||||
|
||||
void bt_le_nimble_gatt_nrp_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -105,12 +105,12 @@ static int hci_cmd_set_cig_params(struct net_buf *buf, struct net_buf **rsp)
|
||||
|
||||
/* The cis_count can be 0 */
|
||||
if (cis_count) {
|
||||
cis_params = calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params));
|
||||
cis_params = bt_le_ext_calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params));
|
||||
assert(cis_params);
|
||||
}
|
||||
|
||||
rp_len = sizeof(struct ble_hci_le_set_cig_params_rp) + cis_count * 2;
|
||||
rp = calloc(1, rp_len);
|
||||
rp = bt_le_ext_calloc(1, rp_len);
|
||||
assert(rp);
|
||||
|
||||
for (size_t i = 0; i < cis_count; i++) {
|
||||
@@ -199,12 +199,12 @@ static int hci_cmd_set_cig_params_test(struct net_buf *buf, struct net_buf **rsp
|
||||
|
||||
/* The cis_count can be 0 */
|
||||
if (cis_count) {
|
||||
cis_params = calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params_test));
|
||||
cis_params = bt_le_ext_calloc(1, cis_count * sizeof(struct ble_hci_le_cis_params_test));
|
||||
assert(cis_params);
|
||||
}
|
||||
|
||||
rp_len = sizeof(struct ble_hci_le_set_cig_params_test_rp) + cis_count * 2;
|
||||
rp = calloc(1, rp_len);
|
||||
rp = bt_le_ext_calloc(1, rp_len);
|
||||
assert(rp);
|
||||
|
||||
for (size_t i = 0; i < cis_count; i++) {
|
||||
@@ -276,7 +276,7 @@ static int hci_cmd_create_cis(struct net_buf *buf, struct net_buf **rsp)
|
||||
|
||||
assert(buf->len >= 4 + cis_count * sizeof(struct ble_hci_le_create_cis_params));
|
||||
|
||||
cis_params = calloc(1, cis_count * sizeof(struct ble_hci_le_create_cis_params));
|
||||
cis_params = bt_le_ext_calloc(1, cis_count * sizeof(struct ble_hci_le_create_cis_params));
|
||||
assert(cis_params);
|
||||
|
||||
for (size_t i = 0; i < cis_count; i++) {
|
||||
@@ -792,7 +792,7 @@ static void iso_evt_rx(uint8_t event, const void *data,
|
||||
|
||||
qdata_len = len + 2;
|
||||
|
||||
qdata = calloc(1, qdata_len);
|
||||
qdata = bt_le_ext_calloc(1, qdata_len);
|
||||
assert(qdata);
|
||||
|
||||
qdata[0] = le_meta;
|
||||
|
||||
@@ -32,11 +32,11 @@ _Static_assert(CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM && "At least one L2CAP coc sha
|
||||
#define OTS_L2CAP_BUF_COUNT (3 * CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM)
|
||||
#define OTS_L2CAP_MEM_SIZE OS_MEMPOOL_SIZE(OTS_L2CAP_BUF_COUNT, L2CAP_LE_OTS_MTU * 2)
|
||||
|
||||
static os_membuf_t ots_mem[OTS_L2CAP_MEM_SIZE];
|
||||
static struct os_mempool ots_mbuf_mempool;
|
||||
static struct os_mbuf_pool ots_mbuf_pool;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR os_membuf_t ots_mem[OTS_L2CAP_MEM_SIZE];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct os_mempool ots_mbuf_mempool;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct os_mbuf_pool ots_mbuf_pool;
|
||||
|
||||
static struct ble_l2cap_chan *ots_chan;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct ble_l2cap_chan *ots_chan;
|
||||
|
||||
static int ots_l2cap_recv_ready(struct ble_l2cap_chan *chan)
|
||||
{
|
||||
@@ -158,7 +158,7 @@ static int ots_l2cap_event_cb(struct ble_l2cap_event *event, void *arg)
|
||||
|
||||
sdu_len = OS_MBUF_PKTLEN(event->receive.sdu_rx);
|
||||
|
||||
sdu = calloc(1, sdu_len);
|
||||
sdu = bt_le_ext_calloc(1, sdu_len);
|
||||
assert(sdu);
|
||||
|
||||
err = os_mbuf_copydata(event->receive.sdu_rx, 0, sdu_len, sdu);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_ADV, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static struct bt_le_ext_adv ext_adv_pool[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct bt_le_ext_adv ext_adv_pool[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
|
||||
|
||||
static struct bt_le_ext_adv *ext_adv_find(uint8_t adv_handle)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_AGAP, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static bt_le_gap_app_cb gap_app_cb;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR bt_le_gap_app_cb gap_app_cb;
|
||||
|
||||
int bt_le_gap_app_cb_register(bt_le_gap_app_cb cb)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_AGAT, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static bt_le_gatt_app_cb gatt_app_cb;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR bt_le_gatt_app_cb gatt_app_cb;
|
||||
|
||||
int bt_le_gatt_app_cb_register(bt_le_gatt_app_cb cb)
|
||||
{
|
||||
|
||||
@@ -23,18 +23,18 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_CONN, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static struct bt_conn acl_conns[CONFIG_BT_MAX_CONN];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct bt_conn acl_conns[CONFIG_BT_MAX_CONN];
|
||||
|
||||
/* Per-ACL LTK backing store (indexed in lockstep with acl_conns[]). conn->le.keys is
|
||||
* a bare pointer the adapters fill after bonding; point it at the matching slot so the
|
||||
* lib's CSIS sirk_encrypt can read conn->le.keys->ltk.val. */
|
||||
static struct bt_keys conn_ltk[CONFIG_BT_MAX_CONN];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct bt_keys conn_ltk[CONFIG_BT_MAX_CONN];
|
||||
|
||||
extern struct bt_conn iso_conns[CONFIG_BT_ISO_MAX_CHAN];
|
||||
|
||||
static sys_slist_t conn_cbs = SYS_SLIST_STATIC_INIT(&conn_cbs);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t conn_cbs;
|
||||
|
||||
static sys_slist_t auth_info_cbs = SYS_SLIST_STATIC_INIT(&auth_info_cbs);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t auth_info_cbs;
|
||||
|
||||
_IDF_ONLY
|
||||
void bt_conn_get_acl_conns(struct bt_conn **conns, uint8_t *count)
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_GATT, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static sys_slist_t gatt_db = SYS_SLIST_STATIC_INIT(&gatt_db);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t gatt_db;
|
||||
|
||||
static struct gattc_sub subscriptions[CONFIG_BT_MAX_CONN];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct gattc_sub subscriptions[CONFIG_BT_MAX_CONN];
|
||||
|
||||
/* Each CCC descriptor's cfg is a heap pool (depth BT_GATT_CCC_MAX = bonded peers +
|
||||
* active conn), allocated here at registration; freed in gatts_free_svc_ccc_cfg. */
|
||||
@@ -44,7 +44,7 @@ static int gatts_alloc_svc_ccc_cfg(struct bt_gatt_service *svc)
|
||||
}
|
||||
|
||||
ccc = attr->user_data;
|
||||
ccc->cfg = calloc(BT_GATT_CCC_MAX, sizeof(struct bt_gatt_ccc_cfg));
|
||||
ccc->cfg = bt_le_ext_calloc(BT_GATT_CCC_MAX, sizeof(struct bt_gatt_ccc_cfg));
|
||||
if (ccc->cfg == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/buf.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/hci_types.h>
|
||||
#include <zephyr/bluetooth/gap.h>
|
||||
|
||||
#include <../host/hci_core.h>
|
||||
#include <../host/iso_internal.h>
|
||||
@@ -23,6 +25,24 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_HCI, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
/* Device/HCI state, not an ISO packet, task-context -> eligible for PSRAM. */
|
||||
BT_ISO_EXT_RAM_BSS_ATTR struct bt_dev bt_dev;
|
||||
|
||||
uint8_t bt_get_phy(uint8_t hci_phy)
|
||||
{
|
||||
switch (hci_phy) {
|
||||
case BT_HCI_LE_PHY_1M:
|
||||
return BT_GAP_LE_PHY_1M;
|
||||
case BT_HCI_LE_PHY_2M:
|
||||
return BT_GAP_LE_PHY_2M;
|
||||
case BT_HCI_LE_PHY_CODED:
|
||||
return BT_GAP_LE_PHY_CODED;
|
||||
default:
|
||||
LOG_WRN("UnknownHciPhy[%u]", hci_phy);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct cmd_data {
|
||||
/** HCI status of the command completion */
|
||||
uint8_t status;
|
||||
@@ -34,7 +54,7 @@ struct cmd_data {
|
||||
struct bt_hci_cmd_state_set *state;
|
||||
};
|
||||
|
||||
static struct cmd_data cmd_data;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct cmd_data cmd_data;
|
||||
|
||||
#define cmd(buf) (&cmd_data)
|
||||
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "bluedroid/gap.h"
|
||||
#include "bluedroid/gatt.h"
|
||||
#else
|
||||
#include "nimble/gatt.h"
|
||||
#endif
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_HOST, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static struct k_mutex host_mutex;
|
||||
static BT_ISO_CTRL_BSS_ATTR struct k_mutex host_mutex;
|
||||
|
||||
#if HOST_LOCK_DEBUG
|
||||
void bt_le_host_lock_debug(const char *func, int line)
|
||||
@@ -97,6 +99,11 @@ int bt_le_host_init(void)
|
||||
if (err) {
|
||||
goto deinit_bluedroid_gatt;
|
||||
}
|
||||
#else
|
||||
/* nimble: reset the per-conn GATT cache/NRP arrays (now .bss/PSRAM, no
|
||||
* static init) so this init - and any later deinit/re-init - starts clean. */
|
||||
bt_le_nimble_gattc_db_init();
|
||||
bt_le_nimble_gatt_nrp_init();
|
||||
#endif /* CONFIG_BT_BLUEDROID_ENABLED */
|
||||
|
||||
err = bt_le_iso_init();
|
||||
@@ -137,6 +144,9 @@ void bt_le_host_deinit(void)
|
||||
bt_le_iso_deinit();
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
bt_le_bluedroid_gatt_deinit();
|
||||
#else
|
||||
bt_le_nimble_gattc_db_deinit();
|
||||
bt_le_nimble_gatt_nrp_deinit();
|
||||
#endif /* CONFIG_BT_BLUEDROID_ENABLED */
|
||||
#if CONFIG_BT_OTS || CONFIG_BT_OTS_CLIENT
|
||||
bt_le_l2cap_deinit();
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <zephyr/bluetooth/iso.h>
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
|
||||
#include "utils/iso_attr.h"
|
||||
#include "utils/mem.h"
|
||||
|
||||
#include "common/adv.h"
|
||||
#include "common/conn.h"
|
||||
#include "common/iso.h"
|
||||
|
||||
@@ -44,7 +44,7 @@ LOG_MODULE_REGISTER(ISO_SHIM, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
#define ISO_PKT_COMP_SDU (0b10)
|
||||
#define ISO_PKT_LAST_FRAG (0b11)
|
||||
|
||||
static sys_slist_t iso_cbs = SYS_SLIST_STATIC_INIT(&iso_cbs);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t iso_cbs;
|
||||
|
||||
#if CONFIG_BT_ISO_UNICAST
|
||||
static void hci_le_cis_disconnected(struct net_buf *buf);
|
||||
@@ -407,13 +407,13 @@ struct iso_tx_sdu_node {
|
||||
sys_snode_t node;
|
||||
};
|
||||
|
||||
static sys_slist_t iso_tx_sdu_list = SYS_SLIST_STATIC_INIT(&iso_tx_sdu_list);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t iso_tx_sdu_list;
|
||||
|
||||
static int iso_tx_sdu_insert(struct bt_iso_chan *chan, const uint8_t *sdu, uint16_t sdu_len)
|
||||
{
|
||||
struct iso_tx_sdu_node *sdu_node;
|
||||
|
||||
sdu_node = calloc(1, sizeof(*sdu_node));
|
||||
sdu_node = bt_le_int_calloc(1, sizeof(*sdu_node));
|
||||
if (sdu_node == NULL) {
|
||||
LOG_ERR("IsoTxSduInsertNoMem[%u]", sizeof(*sdu_node));
|
||||
return -ENOMEM;
|
||||
@@ -513,7 +513,7 @@ static int iso_tx_now(struct bt_iso_chan *chan, const uint8_t *sdu,
|
||||
* Check if ISO SDU needs to be fragmented here.
|
||||
*/
|
||||
|
||||
pkt = malloc(4 + data_total_len);
|
||||
pkt = bt_le_int_malloc(4 + data_total_len);
|
||||
if (pkt == NULL) {
|
||||
LOG_ERR("IsoTxNowNoMem[%u]", 4 + data_total_len);
|
||||
return -ENOMEM;
|
||||
@@ -689,7 +689,7 @@ static void iso_tx_comp_cb(uint16_t conn_handle, void *info, size_t size)
|
||||
|
||||
assert(size == sizeof(struct bt_iso_tx_cb_info));
|
||||
|
||||
evt = calloc(1, sizeof(*evt));
|
||||
evt = bt_le_int_calloc(1, sizeof(*evt));
|
||||
if (evt == NULL) {
|
||||
LOG_ERR("IsoTxCompNoMem[%u]", sizeof(*evt));
|
||||
return;
|
||||
@@ -743,7 +743,7 @@ int bt_le_iso_rx(const uint8_t *data, uint16_t len, void *arg)
|
||||
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
rx_data = calloc(1, len);
|
||||
rx_data = bt_le_int_calloc(1, len);
|
||||
if (rx_data == NULL) {
|
||||
LOG_ERR("IsoRxNoMem[%u]", len);
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -35,7 +35,7 @@ LOG_MODULE_REGISTER(ISO_L2CAP, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
#define L2CAP_LE_PSM_DYN_END 0x00FF
|
||||
#define L2CAP_LE_PSM_IS_DYN(_psm) (_psm >= L2CAP_LE_PSM_DYN_START && _psm <= L2CAP_LE_PSM_DYN_END)
|
||||
|
||||
static sys_slist_t l2cap_servers = SYS_SLIST_STATIC_INIT(&l2cap_servers);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t l2cap_servers;
|
||||
|
||||
static struct bt_l2cap_chan *l2cap_lookup_tx_cid(struct bt_conn *conn, uint16_t cid)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_SCAN, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static sys_slist_t scan_cbs = SYS_SLIST_STATIC_INIT(&scan_cbs);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t scan_cbs;
|
||||
|
||||
_LIB_ONLY
|
||||
int bt_le_scan_cb_register(struct bt_le_scan_cb *cb)
|
||||
@@ -146,9 +146,9 @@ void bt_le_scan_recv_listener(uint16_t event_type,
|
||||
}
|
||||
}
|
||||
|
||||
static struct bt_le_per_adv_sync per_adv_sync_pool[CONFIG_BT_PER_ADV_SYNC_MAX];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct bt_le_per_adv_sync per_adv_sync_pool[CONFIG_BT_PER_ADV_SYNC_MAX];
|
||||
|
||||
static sys_slist_t pa_sync_cbs = SYS_SLIST_STATIC_INIT(&pa_sync_cbs);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t pa_sync_cbs;
|
||||
|
||||
_LIB_ONLY
|
||||
int bt_le_per_adv_sync_cb_register(struct bt_le_per_adv_sync_cb *cb)
|
||||
|
||||
@@ -29,19 +29,19 @@ LOG_MODULE_REGISTER(ISO_TASK, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
* critical before normal before floodable, so a flood of GAP reports cannot
|
||||
* delay the latency-critical ISO data path. See common/task.h for the mapping.
|
||||
*/
|
||||
static QueueHandle_t iso_critical_queue;
|
||||
static QueueHandle_t iso_normal_queue;
|
||||
static QueueHandle_t iso_floodable_queue;
|
||||
static QueueSetHandle_t iso_queue_set;
|
||||
static BT_ISO_CTRL_BSS_ATTR QueueHandle_t iso_critical_queue;
|
||||
static BT_ISO_CTRL_BSS_ATTR QueueHandle_t iso_normal_queue;
|
||||
static BT_ISO_CTRL_BSS_ATTR QueueHandle_t iso_floodable_queue;
|
||||
static BT_ISO_CTRL_BSS_ATTR QueueSetHandle_t iso_queue_set;
|
||||
|
||||
static TaskHandle_t iso_task_handle;
|
||||
static BT_ISO_CTRL_BSS_ATTR TaskHandle_t iso_task_handle;
|
||||
|
||||
extern void bt_le_timer_handle_event(void *arg);
|
||||
|
||||
#if CONFIG_BT_ISO_DISPATCH_MONITOR
|
||||
/* Per-type dispatch timing, indexed by iso_queue_item_type. Written only by
|
||||
* iso_task (single writer); read by bt_le_iso_dispatch_stats_dump. */
|
||||
static struct iso_dispatch_stats {
|
||||
static BT_ISO_CTRL_BSS_ATTR struct iso_dispatch_stats {
|
||||
int64_t max_us;
|
||||
uint32_t count;
|
||||
uint32_t slow_count;
|
||||
|
||||
@@ -55,11 +55,13 @@ LOG_MODULE_REGISTER(ISO_CORE, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
#define iso_chan(_iso) ((_iso)->iso.chan);
|
||||
|
||||
struct bt_conn iso_conns[CONFIG_BT_ISO_MAX_CHAN];
|
||||
/* ISO connection state, not the SDU buffers: task-context only, no ISR/DMA,
|
||||
* so PSRAM-eligible despite the per-SDU lookups. */
|
||||
BT_ISO_EXT_RAM_BSS_ATTR struct bt_conn iso_conns[CONFIG_BT_ISO_MAX_CHAN];
|
||||
|
||||
/* TODO: Allow more than one server? */
|
||||
#if defined(CONFIG_BT_ISO_CENTRAL)
|
||||
struct bt_iso_cig cigs[CONFIG_BT_ISO_MAX_CIG];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct bt_iso_cig cigs[CONFIG_BT_ISO_MAX_CIG];
|
||||
|
||||
static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan);
|
||||
static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t count);
|
||||
@@ -67,13 +69,13 @@ static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t co
|
||||
#endif /* CONFIG_BT_ISO_CENTRAL */
|
||||
|
||||
#if defined(CONFIG_BT_ISO_PERIPHERAL)
|
||||
static struct bt_iso_server *iso_server;
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct bt_iso_server *iso_server;
|
||||
|
||||
static struct bt_conn *bt_conn_add_iso(struct bt_conn *acl);
|
||||
#endif /* CONFIG_BT_ISO_PERIPHERAL */
|
||||
|
||||
#if defined(CONFIG_BT_ISO_BROADCAST)
|
||||
struct bt_iso_big bigs[CONFIG_BT_ISO_MAX_BIG];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR struct bt_iso_big bigs[CONFIG_BT_ISO_MAX_BIG];
|
||||
|
||||
static struct bt_iso_big *lookup_big_by_handle(uint8_t big_handle);
|
||||
#endif /* CONFIG_BT_ISO_BROADCAST */
|
||||
@@ -2256,7 +2258,7 @@ int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count)
|
||||
#endif /* CONFIG_BT_ISO_UNICAST */
|
||||
|
||||
#if defined(CONFIG_BT_ISO_BROADCAST)
|
||||
static sys_slist_t iso_big_cbs = SYS_SLIST_STATIC_INIT(&iso_big_cbs);
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR sys_slist_t iso_big_cbs;
|
||||
|
||||
static struct bt_iso_big *lookup_big_by_handle(uint8_t big_handle)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Nordic Semiconductor ASA
|
||||
* SPDX-FileContributor: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -18,10 +19,12 @@
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include "utils/iso_attr.h"
|
||||
|
||||
const char *bt_hex(const void *buf, size_t len)
|
||||
{
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
static char str[129];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR char str[129];
|
||||
const uint8_t *b = buf;
|
||||
size_t i;
|
||||
|
||||
@@ -39,7 +42,7 @@ const char *bt_hex(const void *buf, size_t len)
|
||||
|
||||
const char *bt_addr_str(const bt_addr_t *addr)
|
||||
{
|
||||
static char str[BT_ADDR_STR_LEN];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR char str[BT_ADDR_STR_LEN];
|
||||
|
||||
bt_addr_to_str(addr, str, sizeof(str));
|
||||
|
||||
@@ -48,7 +51,7 @@ const char *bt_addr_str(const bt_addr_t *addr)
|
||||
|
||||
const char *bt_addr_le_str(const bt_addr_le_t *addr)
|
||||
{
|
||||
static char str[BT_ADDR_LE_STR_LEN];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR char str[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(addr, str, sizeof(str));
|
||||
|
||||
@@ -57,7 +60,7 @@ const char *bt_addr_le_str(const bt_addr_le_t *addr)
|
||||
|
||||
const char *bt_uuid_str(const struct bt_uuid *uuid)
|
||||
{
|
||||
static char str[BT_UUID_STR_LEN];
|
||||
static BT_ISO_EXT_RAM_BSS_ATTR char str[BT_UUID_STR_LEN];
|
||||
|
||||
bt_uuid_to_str(uuid, str, sizeof(str));
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
/* Static (.bss) placement markers for the esp_ble_iso component.
|
||||
*
|
||||
* These sources compile into libbt.a, where object names collide
|
||||
* (common/iso.c vs adapter/bluedroid/iso.c vs host/iso/iso.c, etc.), so a
|
||||
* linker fragment cannot target them cleanly - placement is done per-variable
|
||||
* via these attributes.
|
||||
*
|
||||
* - BT_ISO_EXT_RAM_BSS_ATTR: eligible for external SPIRAM (cold or
|
||||
* control-plane, task-context, non-DMA). Moves to PSRAM when
|
||||
* BT_ISO_BSS_SEG_EXTERNAL_MEMORY is set, else expands to nothing. Safe
|
||||
* because esp_ble_iso registers no IRAM ISR (nothing here is touched with
|
||||
* the flash cache disabled).
|
||||
*
|
||||
* - BT_ISO_CTRL_BSS_ATTR: must stay in internal DRAM - currently cannot go
|
||||
* to PSRAM. Marker only (expands to nothing = default internal placement).
|
||||
* Used for the real-time ISO data path and anything DMA-reachable or
|
||||
* otherwise unsafe/uncertain in PSRAM. Kernel-object wrappers (k_sem/k_mutex)
|
||||
* are marked CTRL too - synchronization primitives taken on hot/host paths
|
||||
* (incl. the ISO dispatch), kept internal for determinism (and tiny anyway).
|
||||
* net_buf pools and initialized (.data) statistics also stay internal but need
|
||||
* no marker (auto-named .bss cannot take a per-var attribute; .data cannot
|
||||
* use EXT_RAM_BSS).
|
||||
*
|
||||
* esp_ble_audio has its own equivalent (common/audio_attr.h, BT_AUDIO_* macros),
|
||||
* kept separate for the audio layer. The distinct name and include prefix
|
||||
* (utils/ here vs common/ there) avoid any collision on the bt component's shared
|
||||
* flat include path.
|
||||
*/
|
||||
#if CONFIG_BT_ISO_BSS_SEG_EXTERNAL_MEMORY
|
||||
#define BT_ISO_EXT_RAM_BSS_ATTR EXT_RAM_BSS_ATTR
|
||||
#else
|
||||
#define BT_ISO_EXT_RAM_BSS_ATTR
|
||||
#endif
|
||||
|
||||
#define BT_ISO_CTRL_BSS_ATTR
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Heap allocation policy for LE Audio. Every runtime allocation should use one
|
||||
* of these two so intent is explicit (a bare malloc/calloc reads as "not yet
|
||||
* classified" and risks being rerouted by a later PSRAM sweep). Both pin the
|
||||
* allocation to a memory type with heap_caps, independent of the platform's
|
||||
* default malloc policy (which, under CONFIG_SPIRAM_USE_MALLOC, may itself hand
|
||||
* out PSRAM).
|
||||
*
|
||||
* - bt_le_ext_*: control-plane data (GATT/GAP event marshalling, profile setup,
|
||||
* per-conn state, ...). Placed in external SPIRAM (MALLOC_CAP_SPIRAM) when
|
||||
* BT_ISO_HEAP_EXTERNAL_MEMORY is set, else the internal heap. Returns NULL on
|
||||
* SPIRAM exhaustion (no internal fallback).
|
||||
*
|
||||
* - bt_le_int_*: the real-time ISO TX/RX data path (SDU packet buffers handed to
|
||||
* the controller, per-SDU nodes/events). Forced to internal DRAM
|
||||
* (MALLOC_CAP_INTERNAL): controller/DMA-reachable and latency-critical, so it
|
||||
* must never land in PSRAM. Plain malloc/calloc would NOT guarantee this -
|
||||
* under CONFIG_SPIRAM_USE_MALLOC they can return PSRAM.
|
||||
*
|
||||
* Both are freed with plain free() (valid for heap_caps allocations in ESP-IDF).
|
||||
*/
|
||||
void *bt_le_ext_malloc(size_t size);
|
||||
void *bt_le_ext_calloc(size_t n, size_t size);
|
||||
void *bt_le_int_malloc(size_t size);
|
||||
void *bt_le_int_calloc(size_t n, size_t size);
|
||||
-17
@@ -28,23 +28,6 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ISO_UTILS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
struct bt_dev bt_dev;
|
||||
|
||||
uint8_t bt_get_phy(uint8_t hci_phy)
|
||||
{
|
||||
switch (hci_phy) {
|
||||
case BT_HCI_LE_PHY_1M:
|
||||
return BT_GAP_LE_PHY_1M;
|
||||
case BT_HCI_LE_PHY_2M:
|
||||
return BT_GAP_LE_PHY_2M;
|
||||
case BT_HCI_LE_PHY_CODED:
|
||||
return BT_GAP_LE_PHY_CODED;
|
||||
default:
|
||||
LOG_WRN("UnknownHciPhy[%u]", hci_phy);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Query the active host's persistent bond store (the old local key_pool was never
|
||||
* populated, so bt_le_bond_exists() was always false). `id` ignored (single identity);
|
||||
* addresses stay in native host byte order. */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#include "utils/mem.h"
|
||||
|
||||
void *bt_le_ext_malloc(size_t size)
|
||||
{
|
||||
#if CONFIG_BT_ISO_HEAP_EXTERNAL_MEMORY
|
||||
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *bt_le_ext_calloc(size_t n, size_t size)
|
||||
{
|
||||
#if CONFIG_BT_ISO_HEAP_EXTERNAL_MEMORY
|
||||
return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
#else
|
||||
return calloc(n, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ISO TX/RX data path: force internal DRAM. Plain malloc/calloc follow IDF's
|
||||
* default heap policy and could return PSRAM under CONFIG_SPIRAM_USE_MALLOC;
|
||||
* MALLOC_CAP_INTERNAL guarantees internal regardless. */
|
||||
void *bt_le_int_malloc(size_t size)
|
||||
{
|
||||
return heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
}
|
||||
|
||||
void *bt_le_int_calloc(size_t n, size_t size)
|
||||
{
|
||||
return heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
}
|
||||
Reference in New Issue
Block a user