mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(ble_audio): Support running ISO & LE Audio with Bluedroid Host
This commit is contained in:
@@ -29,13 +29,24 @@ endif()
|
||||
list(APPEND ble_audio_include_dirs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/api/include"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/common/include"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/include"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include"
|
||||
)
|
||||
|
||||
if(CONFIG_BT_NIMBLE_ENABLED)
|
||||
set(audio_adapter "host/adapter/nimble")
|
||||
elseif(CONFIG_BT_BLUEDROID_ENABLED)
|
||||
set(audio_adapter "host/adapter/bluedroid")
|
||||
endif()
|
||||
|
||||
list(APPEND ble_audio_include_dirs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/include"
|
||||
)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/server.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/init.c"
|
||||
)
|
||||
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/server.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/init.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/common/init.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/api/esp_ble_audio_aics_api.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/api/esp_ble_audio_bap_api.c"
|
||||
@@ -57,69 +68,71 @@ list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/api/esp_ble_audio_vocs_api.c"
|
||||
)
|
||||
|
||||
# Profile glue files live under the host adapter; same set of profile sources
|
||||
# for either host, dispatched via ${audio_adapter}.
|
||||
if(CONFIG_BT_ASCS)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/ascs.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/ascs.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_PACS)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/pacs.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/pacs.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_BAP_SCAN_DELEGATOR)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/bass.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/bass.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_CAP_ACCEPTOR)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/cas.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/cas.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_CSIP_SET_MEMBER)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/csis.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/csis.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_TBS)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/tbs.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/tbs.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_TMAP)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/tmas.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/tmas.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_VCP_VOL_REND)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/vcs.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/vcs.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_MICP_MIC_DEV)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/mics.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/mics.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_MCS)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/mcs.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/mcs.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BT_HAS)
|
||||
list(APPEND ble_audio_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/host/adapter/nimble/profiles/has.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${audio_adapter}/profiles/has.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@ if BT_MCC
|
||||
it.
|
||||
|
||||
config BT_MCC_OTS
|
||||
bool "Media Control Client support for Object Transfer Service (depends on OTS Client)"
|
||||
depends on BT_OTS_CLIENT
|
||||
bool "Media Control Client support for Object Transfer Service"
|
||||
select BT_OTS_CLIENT
|
||||
help
|
||||
Use this option to configure support in the Media Control Client for
|
||||
an included Object Transfer Service in the Media Control Service.
|
||||
|
||||
@@ -71,9 +71,10 @@ if BT_MPL
|
||||
|
||||
config BT_MPL_OBJECTS
|
||||
bool "Support for media player objects"
|
||||
depends on BT_OTS
|
||||
select BT_OTS
|
||||
# TODO: Temporarily depends also on BT_MCS, to avoid issues with the
|
||||
# bt_mcs_get_ots() call
|
||||
# bt_mcs_get_ots() call. BT_MCS stays as `depends on` because it has
|
||||
# non-leaf prerequisites (BT_MCTL_LOCAL_PLAYER_REMOTE_CONTROL ...).
|
||||
depends on BT_MCS
|
||||
# OTS shall be instantiated as a Secondary Service and shall be
|
||||
# included in MCS or GMCS.
|
||||
|
||||
@@ -70,10 +70,12 @@ void esp_ble_audio_gap_app_post_event(uint8_t type, void *param)
|
||||
bt_le_gap_app_post_event(type, param);
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_BLUEDROID_ENABLED
|
||||
void esp_ble_audio_gatt_app_post_event(uint8_t type, void *param)
|
||||
{
|
||||
bt_le_gatt_app_post_event(type, param);
|
||||
}
|
||||
#endif /* !CONFIG_BT_BLUEDROID_ENABLED */
|
||||
|
||||
esp_err_t esp_ble_audio_common_init(esp_ble_audio_init_info_t *info)
|
||||
{
|
||||
@@ -156,3 +158,10 @@ esp_err_t esp_ble_audio_common_start(esp_ble_audio_start_info_t *info)
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
uint8_t esp_ble_audio_bluedroid_get_gattc_if(void)
|
||||
{
|
||||
return bt_le_bluedroid_gattc_get_if();
|
||||
}
|
||||
#endif /* CONFIG_BT_BLUEDROID_ENABLED */
|
||||
|
||||
@@ -128,15 +128,20 @@ typedef struct {
|
||||
*/
|
||||
void esp_ble_audio_gap_app_post_event(uint8_t type, void *param);
|
||||
|
||||
#if !CONFIG_BT_BLUEDROID_ENABLED
|
||||
/**
|
||||
* @brief Post an application-layer GATT event for audio internal usage.
|
||||
*
|
||||
* @note This function is only needed while using NimBLE Host.
|
||||
* @note NimBLE-only. Bluedroid dispatches GATT events directly inside the
|
||||
* adapter (BTA callbacks), so no app-level post is needed. This
|
||||
* declaration is hidden from Bluedroid builds to make misuse a
|
||||
* compile-time error.
|
||||
*
|
||||
* @param type Event type.
|
||||
* @param param Event parameters.
|
||||
*/
|
||||
void esp_ble_audio_gatt_app_post_event(uint8_t type, void *param);
|
||||
#endif /* !CONFIG_BT_BLUEDROID_ENABLED */
|
||||
|
||||
/**
|
||||
* @brief Initialize BLE Audio common functionality.
|
||||
@@ -167,6 +172,21 @@ typedef struct {
|
||||
*/
|
||||
esp_err_t esp_ble_audio_common_start(esp_ble_audio_start_info_t *info);
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
/**
|
||||
* @brief Get the engine's internal GATTC interface handle (Bluedroid only).
|
||||
*
|
||||
* Pass this to esp_ble_gattc_aux_open() / esp_ble_gattc_open() so the
|
||||
* resulting ACL events route back to the engine, avoiding the need for the
|
||||
* application to register a second BTA GATTC app for connection initiation.
|
||||
*
|
||||
* @return Engine's gattc_if (ABI-compatible with esp_gatt_if_t), or
|
||||
* ESP_GATT_IF_NONE (0xFF) if GATTC registration has not completed —
|
||||
* callers must bail rather than pass it to aux_open.
|
||||
*/
|
||||
uint8_t esp_ble_audio_bluedroid_get_gattc_if(void);
|
||||
#endif /* CONFIG_BT_BLUEDROID_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_INIT_H_
|
||||
#define HOST_BLUEDROID_INIT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
#include "bluedroid/profiles/ascs.h"
|
||||
#include "bluedroid/profiles/bass.h"
|
||||
#include "bluedroid/profiles/cas.h"
|
||||
#include "bluedroid/profiles/csis.h"
|
||||
#include "bluedroid/profiles/mcs.h"
|
||||
#include "bluedroid/profiles/mics.h"
|
||||
#include "bluedroid/profiles/pacs.h"
|
||||
#include "bluedroid/profiles/tbs.h"
|
||||
#include "bluedroid/profiles/tmas.h"
|
||||
#include "bluedroid/profiles/vcs.h"
|
||||
#include "bluedroid/profiles/has.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_audio_init(void);
|
||||
|
||||
int bt_le_bluedroid_media_proxy_pl_init(void);
|
||||
|
||||
int bt_le_bluedroid_vcp_vol_rend_init(void);
|
||||
|
||||
int bt_le_bluedroid_micp_mic_dev_init(void);
|
||||
|
||||
int bt_le_bluedroid_audio_start(void *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_INIT_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_ASCS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_ASCS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_ascs_init(void);
|
||||
|
||||
int bt_le_bluedroid_ascs_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_ASCS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_BASS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_BASS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_bass_init(void);
|
||||
|
||||
int bt_le_bluedroid_bass_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_BASS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_CAS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_CAS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_cas_init(void *csis_svc_p);
|
||||
|
||||
int bt_le_bluedroid_cas_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_CAS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_CSIS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_CSIS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_csis_init(void *csis_svc, uint8_t count);
|
||||
|
||||
int bt_le_bluedroid_csis_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_CSIS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_HAS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_HAS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_has_init(void);
|
||||
|
||||
int bt_le_bluedroid_has_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_HAS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_MCS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_MCS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_gmcs_init(void);
|
||||
|
||||
int bt_le_bluedroid_gmcs_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_MCS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_MICS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_MICS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_mics_init(void *micp_inc);
|
||||
|
||||
int bt_le_bluedroid_mics_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_MICS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_PACS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_PACS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_pacs_init(void);
|
||||
|
||||
int bt_le_bluedroid_pacs_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_PACS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_TBS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_TBS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_gtbs_init(void);
|
||||
|
||||
int bt_le_bluedroid_gtbs_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_TBS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_TMAS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_TMAS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_tmas_init(void);
|
||||
|
||||
int bt_le_bluedroid_tmas_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_TMAS_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_PROFILE_VCS_H_
|
||||
#define HOST_BLUEDROID_PROFILE_VCS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bt_le_bluedroid_vcs_init(void *vcp_inc);
|
||||
|
||||
int bt_le_bluedroid_vcs_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_PROFILE_VCS_H_ */
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef HOST_BLUEDROID_SERVER_H_
|
||||
#define HOST_BLUEDROID_SERVER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline char *audio_svc_uuid_to_str(uint16_t uuid)
|
||||
{
|
||||
switch (uuid) {
|
||||
case BT_UUID_AICS_VAL: return "AICS";
|
||||
case BT_UUID_CAS_VAL: return "CAS";
|
||||
case BT_UUID_VCS_VAL: return "VCS";
|
||||
case BT_UUID_VOCS_VAL: return "VOCS";
|
||||
case BT_UUID_CSIS_VAL: return "CSIS";
|
||||
case BT_UUID_MCS_VAL: return "MCS";
|
||||
case BT_UUID_GMCS_VAL: return "GMCS";
|
||||
case BT_UUID_TBS_VAL: return "TBS";
|
||||
case BT_UUID_GTBS_VAL: return "GTBS";
|
||||
case BT_UUID_MICS_VAL: return "MICS";
|
||||
case BT_UUID_ASCS_VAL: return "ASCS";
|
||||
case BT_UUID_BASS_VAL: return "BASS";
|
||||
case BT_UUID_PACS_VAL: return "PACS";
|
||||
case BT_UUID_BASIC_AUDIO_VAL: return "BASIC_AUDIO";
|
||||
case BT_UUID_HAS_VAL: return "HAS";
|
||||
case BT_UUID_TMAS_VAL: return "TMAS";
|
||||
case BT_UUID_PBA_VAL: return "PBA";
|
||||
case BT_UUID_GMAS_VAL: return "GMAS";
|
||||
case BT_UUID_OTS_VAL: return "OTS";
|
||||
default: return "UnknownSvc";
|
||||
}
|
||||
}
|
||||
|
||||
static inline char *audio_chrc_uuid_to_str(uint16_t uuid)
|
||||
{
|
||||
switch (uuid) {
|
||||
case BT_UUID_OTS_FEATURE_VAL: return "OTS_FEATURE";
|
||||
case BT_UUID_OTS_NAME_VAL: return "OTS_NAME";
|
||||
case BT_UUID_OTS_TYPE_VAL: return "OTS_TYPE";
|
||||
case BT_UUID_OTS_SIZE_VAL: return "OTS_SIZE";
|
||||
case BT_UUID_OTS_FIRST_CREATED_VAL: return "OTS_FIRST_CREATED";
|
||||
case BT_UUID_OTS_LAST_MODIFIED_VAL: return "OTS_LAST_MODIFIED";
|
||||
case BT_UUID_OTS_ID_VAL: return "OTS_ID";
|
||||
case BT_UUID_OTS_PROPERTIES_VAL: return "OTS_PROPERTIES";
|
||||
case BT_UUID_OTS_ACTION_CP_VAL: return "OTS_ACTION_CP";
|
||||
case BT_UUID_OTS_LIST_CP_VAL: return "OTS_LIST_CP";
|
||||
case BT_UUID_OTS_LIST_FILTER_VAL: return "OTS_LIST_FILTER";
|
||||
case BT_UUID_OTS_CHANGED_VAL: return "OTS_CHANGED";
|
||||
case BT_UUID_GATT_TMAPR_VAL: return "TMAP_ROLE";
|
||||
case BT_UUID_AICS_STATE_VAL: return "AICS_STATE";
|
||||
case BT_UUID_AICS_GAIN_SETTINGS_VAL: return "AICS_GAIN_SETTINGS";
|
||||
case BT_UUID_AICS_INPUT_TYPE_VAL: return "AICS_INPUT_TYPE";
|
||||
case BT_UUID_AICS_INPUT_STATUS_VAL: return "AICS_INPUT_STATUS";
|
||||
case BT_UUID_AICS_CONTROL_VAL: return "AICS_CONTROL";
|
||||
case BT_UUID_AICS_DESCRIPTION_VAL: return "AICS_DESCRIPTION";
|
||||
case BT_UUID_VCS_STATE_VAL: return "VCS_STATE";
|
||||
case BT_UUID_VCS_CONTROL_VAL: return "VCS_CONTROL";
|
||||
case BT_UUID_VCS_FLAGS_VAL: return "VCS_FLAGS";
|
||||
case BT_UUID_VOCS_STATE_VAL: return "VOCS_STATE";
|
||||
case BT_UUID_VOCS_LOCATION_VAL: return "VOCS_LOCATION";
|
||||
case BT_UUID_VOCS_CONTROL_VAL: return "VOCS_CONTROL";
|
||||
case BT_UUID_VOCS_DESCRIPTION_VAL: return "VOCS_DESCRIPTION";
|
||||
case BT_UUID_CSIS_SIRK_VAL: return "CSIS_SIRK";
|
||||
case BT_UUID_CSIS_SET_SIZE_VAL: return "CSIS_SET_SIZE";
|
||||
case BT_UUID_CSIS_SET_LOCK_VAL: return "CSIS_SET_LOCK";
|
||||
case BT_UUID_CSIS_RANK_VAL: return "CSIS_RANK";
|
||||
case BT_UUID_MCS_PLAYER_NAME_VAL: return "MCS_PLAYER_NAME";
|
||||
case BT_UUID_MCS_ICON_OBJ_ID_VAL: return "MCS_ICON_OBJ_ID";
|
||||
case BT_UUID_MCS_ICON_URL_VAL: return "MCS_ICON_URL";
|
||||
case BT_UUID_MCS_TRACK_CHANGED_VAL: return "MCS_TRACK_CHANGED";
|
||||
case BT_UUID_MCS_TRACK_TITLE_VAL: return "MCS_TRACK_TITLE";
|
||||
case BT_UUID_MCS_TRACK_DURATION_VAL: return "MCS_TRACK_DURATION";
|
||||
case BT_UUID_MCS_TRACK_POSITION_VAL: return "MCS_TRACK_POSITION";
|
||||
case BT_UUID_MCS_PLAYBACK_SPEED_VAL: return "MCS_PLAYBACK_SPEED";
|
||||
case BT_UUID_MCS_SEEKING_SPEED_VAL: return "MCS_SEEKING_SPEED";
|
||||
case BT_UUID_MCS_TRACK_SEGMENTS_OBJ_ID_VAL: return "MCS_TRACK_SEGMENTS_OBJ_ID";
|
||||
case BT_UUID_MCS_CURRENT_TRACK_OBJ_ID_VAL: return "MCS_CURRENT_TRACK_OBJ_ID";
|
||||
case BT_UUID_MCS_NEXT_TRACK_OBJ_ID_VAL: return "MCS_NEXT_TRACK_OBJ_ID";
|
||||
case BT_UUID_MCS_PARENT_GROUP_OBJ_ID_VAL: return "MCS_PARENT_GROUP_OBJ_ID";
|
||||
case BT_UUID_MCS_CURRENT_GROUP_OBJ_ID_VAL: return "MCS_CURRENT_GROUP_OBJ_ID";
|
||||
case BT_UUID_MCS_PLAYING_ORDER_VAL: return "MCS_PLAYING_ORDER";
|
||||
case BT_UUID_MCS_PLAYING_ORDERS_VAL: return "MCS_PLAYING_ORDERS";
|
||||
case BT_UUID_MCS_MEDIA_STATE_VAL: return "MCS_MEDIA_STATE";
|
||||
case BT_UUID_MCS_MEDIA_CONTROL_POINT_VAL: return "MCS_MEDIA_CONTROL_POINT";
|
||||
case BT_UUID_MCS_MEDIA_CONTROL_OPCODES_VAL: return "MCS_MEDIA_CONTROL_OPCODES";
|
||||
case BT_UUID_MCS_SEARCH_RESULTS_OBJ_ID_VAL: return "MCS_SEARCH_RESULTS_OBJ_ID";
|
||||
case BT_UUID_MCS_SEARCH_CONTROL_POINT_VAL: return "MCS_SEARCH_CONTROL_POINT";
|
||||
case BT_UUID_TBS_PROVIDER_NAME_VAL: return "TBS_PROVIDER_NAME";
|
||||
case BT_UUID_TBS_UCI_VAL: return "TBS_UCI";
|
||||
case BT_UUID_TBS_TECHNOLOGY_VAL: return "TBS_TECHNOLOGY";
|
||||
case BT_UUID_TBS_URI_LIST_VAL: return "TBS_URI_LIST";
|
||||
case BT_UUID_TBS_SIGNAL_STRENGTH_VAL: return "TBS_SIGNAL_STRENGTH";
|
||||
case BT_UUID_TBS_SIGNAL_INTERVAL_VAL: return "TBS_SIGNAL_INTERVAL";
|
||||
case BT_UUID_TBS_LIST_CURRENT_CALLS_VAL: return "TBS_LIST_CURRENT_CALLS";
|
||||
case BT_UUID_CCID_VAL: return "CCID";
|
||||
case BT_UUID_TBS_STATUS_FLAGS_VAL: return "TBS_STATUS_FLAGS";
|
||||
case BT_UUID_TBS_INCOMING_URI_VAL: return "TBS_INCOMING_URI";
|
||||
case BT_UUID_TBS_CALL_STATE_VAL: return "TBS_CALL_STATE";
|
||||
case BT_UUID_TBS_CALL_CONTROL_POINT_VAL: return "TBS_CALL_CONTROL_POINT";
|
||||
case BT_UUID_TBS_OPTIONAL_OPCODES_VAL: return "TBS_OPTIONAL_OPCODES";
|
||||
case BT_UUID_TBS_TERMINATE_REASON_VAL: return "TBS_TERMINATE_REASON";
|
||||
case BT_UUID_TBS_INCOMING_CALL_VAL: return "TBS_INCOMING_CALL";
|
||||
case BT_UUID_TBS_FRIENDLY_NAME_VAL: return "TBS_FRIENDLY_NAME";
|
||||
case BT_UUID_MICS_MUTE_VAL: return "MICS_MUTE";
|
||||
case BT_UUID_ASCS_ASE_SNK_VAL: return "ASCS_ASE_SNK";
|
||||
case BT_UUID_ASCS_ASE_SRC_VAL: return "ASCS_ASE_SRC";
|
||||
case BT_UUID_ASCS_ASE_CP_VAL: return "ASCS_ASE_CP";
|
||||
case BT_UUID_BASS_CONTROL_POINT_VAL: return "BASS_CP";
|
||||
case BT_UUID_BASS_RECV_STATE_VAL: return "BASS_RECV_STATE";
|
||||
case BT_UUID_PACS_SNK_VAL: return "PACS_SNK";
|
||||
case BT_UUID_PACS_SNK_LOC_VAL: return "PACS_SNK_LOC";
|
||||
case BT_UUID_PACS_SRC_VAL: return "PACS_SRC";
|
||||
case BT_UUID_PACS_SRC_LOC_VAL: return "PACS_SRC_LOC";
|
||||
case BT_UUID_PACS_AVAILABLE_CONTEXT_VAL: return "PACS_AVAILABLE_CONTEXT";
|
||||
case BT_UUID_PACS_SUPPORTED_CONTEXT_VAL: return "PACS_SUPPORTED_CONTEXT";
|
||||
case BT_UUID_HAS_HEARING_AID_FEATURES_VAL: return "HAS_HEARING_AID_FEATURES";
|
||||
case BT_UUID_HAS_PRESET_CONTROL_POINT_VAL: return "HAS_PRESET_CONTROL_POINT";
|
||||
case BT_UUID_HAS_ACTIVE_PRESET_INDEX_VAL: return "HAS_ACTIVE_PRESET_INDEX";
|
||||
case BT_UUID_GMAP_ROLE_VAL: return "GMAP_ROLE";
|
||||
case BT_UUID_GMAP_UGG_FEAT_VAL: return "GMAP_UGG_FEAT";
|
||||
case BT_UUID_GMAP_UGT_FEAT_VAL: return "GMAP_UGT_FEAT";
|
||||
case BT_UUID_GMAP_BGS_FEAT_VAL: return "GMAP_BGS_FEAT";
|
||||
case BT_UUID_GMAP_BGR_FEAT_VAL: return "GMAP_BGR_FEAT";
|
||||
default: return "UnknownChrc";
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
AICS_IN_PROGRESS,
|
||||
ASCS_IN_PROGRESS,
|
||||
BASS_IN_PROGRESS,
|
||||
CAS_IN_PROGRESS,
|
||||
CSIS_IN_PROGRESS,
|
||||
HAS_IN_PROGRESS,
|
||||
GMCS_IN_PROGRESS,
|
||||
MCS_IN_PROGRESS,
|
||||
MICS_IN_PROGRESS,
|
||||
PACS_IN_PROGRESS,
|
||||
GTBS_IN_PROGRESS,
|
||||
TBS_IN_PROGRESS,
|
||||
TMAS_IN_PROGRESS,
|
||||
VCS_IN_PROGRESS,
|
||||
VOCS_IN_PROGRESS,
|
||||
|
||||
MAX_IN_PROGRESS,
|
||||
};
|
||||
|
||||
void bt_le_bluedroid_audio_gatts_init(void);
|
||||
|
||||
int bt_le_bluedroid_set_svc_in_progress(uint8_t value);
|
||||
|
||||
int bt_le_bluedroid_svc_init(struct bt_gatt_service *svc);
|
||||
|
||||
int bt_le_bluedroid_svc_start(struct bt_gatt_service *svc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HOST_BLUEDROID_SERVER_H_ */
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bta/bta_gatt_common.h"
|
||||
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/audio/micp.h>
|
||||
#include <zephyr/bluetooth/audio/vcp.h>
|
||||
|
||||
#include "bluedroid/init.h"
|
||||
#include "common/init.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_BINIT, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
#if CONFIG_BT_CSIP_SET_MEMBER
|
||||
#define CSIS_SVC_COUNT CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT
|
||||
#else /* CONFIG_BT_CSIP_SET_MEMBER */
|
||||
#define CSIS_SVC_COUNT 0
|
||||
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
|
||||
|
||||
/* 3 is reserved for other GATT services */
|
||||
#define TOTAL_SERVICE_COUNT (3 + \
|
||||
(IS_ENABLED(CONFIG_BT_ASCS) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_PACS) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_BAP_SCAN_DELEGATOR) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_TMAP) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_MCS) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER) ? CSIS_SVC_COUNT : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_VCP_VOL_REND) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_MICP_MIC_DEV) ? 1 : 0) + \
|
||||
CONFIG_BT_VOCS_MAX_INSTANCE_COUNT + \
|
||||
CONFIG_BT_AICS_MAX_INSTANCE_COUNT + \
|
||||
(IS_ENABLED(CONFIG_BT_TBS) ? 1 : 0) + \
|
||||
(IS_ENABLED(CONFIG_BT_HAS) ? 1 : 0))
|
||||
|
||||
_Static_assert(TOTAL_SERVICE_COUNT <= CONFIG_BT_GATT_MAX_SR_PROFILES, "Too small BT_GATT_MAX_SR_PROFILES");
|
||||
|
||||
int bt_le_bluedroid_audio_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
BTA_GATT_SetLocalMTU(BLE_AUDIO_ATT_MTU_MIN);
|
||||
|
||||
bt_le_bluedroid_audio_gatts_init();
|
||||
|
||||
#if CONFIG_BT_PACS
|
||||
err = bt_le_bluedroid_pacs_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_PACS */
|
||||
|
||||
#if (BLE_AUDIO_SVC_DEFERRED_ADD == 0)
|
||||
#if CONFIG_BT_ASCS
|
||||
err = bt_le_bluedroid_ascs_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_ASCS */
|
||||
|
||||
#if CONFIG_BT_BAP_SCAN_DELEGATOR
|
||||
err = bt_le_bluedroid_bass_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
|
||||
|
||||
#if CONFIG_BT_TMAP
|
||||
err = bt_le_bluedroid_tmas_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_TMAP */
|
||||
|
||||
#if CONFIG_BT_TBS
|
||||
err = bt_le_bluedroid_gtbs_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_TBS */
|
||||
|
||||
#if CONFIG_BT_HAS
|
||||
err = bt_le_bluedroid_has_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_HAS */
|
||||
#endif /* (BLE_AUDIO_SVC_DEFERRED_ADD == 0) */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_CSIP_SET_MEMBER
|
||||
static int bluedroid_gatt_csis_init(struct bt_le_audio_start_info *info,
|
||||
struct bt_gatt_service **inc_csis_svc)
|
||||
{
|
||||
struct bt_gatt_service *csis_svc[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT];
|
||||
uint8_t count;
|
||||
int err;
|
||||
|
||||
if (info == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*inc_csis_svc = NULL;
|
||||
count = 0;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(info->csis_insts); i++) {
|
||||
if (info->csis_insts[i].svc_inst == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
csis_svc[count] = lib_csip_set_member_svc_get(info->csis_insts[i].svc_inst);
|
||||
if (!csis_svc[count]) {
|
||||
LOG_ERR("[B]CsisSvcGetFail[%u]", i);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (info->csis_insts[i].included_by_cas) {
|
||||
if (*inc_csis_svc == NULL) {
|
||||
*inc_csis_svc = csis_svc[count];
|
||||
} else {
|
||||
/* CAS may include at most one CSIS — caller misconfigured. */
|
||||
LOG_ERR("[B]CsisMultiIncByCas");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
err = bt_le_bluedroid_csis_init(csis_svc, count);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
|
||||
|
||||
#if CONFIG_BT_MCS
|
||||
int bt_le_bluedroid_media_proxy_pl_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
#if CONFIG_BT_MPL_OBJECTS
|
||||
|
||||
#endif /* CONFIG_BT_MPL_OBJECTS */
|
||||
|
||||
err = bt_le_bluedroid_gmcs_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_MCS */
|
||||
|
||||
#if CONFIG_BT_VCP_VOL_REND
|
||||
int bt_le_bluedroid_vcp_vol_rend_init(void)
|
||||
{
|
||||
struct bt_vcp_included vcp_included;
|
||||
int err;
|
||||
|
||||
memset(&vcp_included, 0, sizeof(vcp_included));
|
||||
|
||||
err = bt_vcp_vol_rend_included_get_safe(&vcp_included);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = bt_le_bluedroid_vcs_init(&vcp_included);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_VCP_VOL_REND */
|
||||
|
||||
#if CONFIG_BT_MICP_MIC_DEV
|
||||
int bt_le_bluedroid_micp_mic_dev_init(void)
|
||||
{
|
||||
struct bt_micp_included micp_included;
|
||||
int err;
|
||||
|
||||
memset(&micp_included, 0, sizeof(micp_included));
|
||||
|
||||
err = bt_micp_mic_dev_included_get_safe(&micp_included);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = bt_le_bluedroid_mics_init(&micp_included);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_MICP_MIC_DEV */
|
||||
|
||||
int bt_le_bluedroid_audio_start(void *info)
|
||||
{
|
||||
struct bt_gatt_service *inc_csis_svc = NULL;
|
||||
int err = 0;
|
||||
|
||||
#if CONFIG_BT_CSIP_SET_MEMBER
|
||||
/* Note:
|
||||
* Should add CSIS before CAS in case one CSIS instance
|
||||
* is included by CAS.
|
||||
*/
|
||||
err = bluedroid_gatt_csis_init(info, &inc_csis_svc);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
|
||||
|
||||
#if CONFIG_BT_CAP_ACCEPTOR
|
||||
err = bt_le_bluedroid_cas_init(inc_csis_svc);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#else /* CONFIG_BT_CAP_ACCEPTOR */
|
||||
ARG_UNUSED(inc_csis_svc);
|
||||
#endif /* CONFIG_BT_CAP_ACCEPTOR */
|
||||
|
||||
#if (BLE_AUDIO_SVC_DEFERRED_ADD == 0)
|
||||
#if CONFIG_BT_MCS
|
||||
err = bt_le_bluedroid_media_proxy_pl_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_MCS */
|
||||
|
||||
#if CONFIG_BT_VCP_VOL_REND
|
||||
err = bt_le_bluedroid_vcp_vol_rend_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_VCP_VOL_REND */
|
||||
|
||||
#if CONFIG_BT_MICP_MIC_DEV
|
||||
err = bt_le_bluedroid_micp_mic_dev_init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_MICP_MIC_DEV */
|
||||
#endif /* (BLE_AUDIO_SVC_DEFERRED_ADD == 0) */
|
||||
|
||||
#if CONFIG_BT_ASCS
|
||||
err = bt_le_bluedroid_ascs_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_ASCS */
|
||||
|
||||
#if CONFIG_BT_PACS
|
||||
err = bt_le_bluedroid_pacs_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_PACS */
|
||||
|
||||
#if CONFIG_BT_BAP_SCAN_DELEGATOR
|
||||
err = bt_le_bluedroid_bass_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
|
||||
|
||||
#if CONFIG_BT_TMAP
|
||||
err = bt_le_bluedroid_tmas_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_TMAP */
|
||||
|
||||
#if CONFIG_BT_CSIP_SET_MEMBER
|
||||
err = bt_le_bluedroid_csis_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
|
||||
|
||||
#if CONFIG_BT_CAP_ACCEPTOR
|
||||
err = bt_le_bluedroid_cas_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_CAP_ACCEPTOR */
|
||||
|
||||
#if CONFIG_BT_VCP_VOL_REND
|
||||
err = bt_le_bluedroid_vcs_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_VCP_VOL_REND */
|
||||
|
||||
#if CONFIG_BT_MICP_MIC_DEV
|
||||
err = bt_le_bluedroid_mics_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_MICP_MIC_DEV */
|
||||
|
||||
#if CONFIG_BT_MCS
|
||||
err = bt_le_bluedroid_gmcs_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_MCS */
|
||||
|
||||
#if CONFIG_BT_TBS
|
||||
err = bt_le_bluedroid_gtbs_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_TBS */
|
||||
|
||||
#if CONFIG_BT_HAS
|
||||
err = bt_le_bluedroid_has_start();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BT_HAS */
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_ASCS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
int bt_le_bluedroid_ascs_init(void)
|
||||
{
|
||||
struct bt_gatt_service *ascs_svc;
|
||||
|
||||
LOG_DBG("[B]AscsInit");
|
||||
|
||||
ascs_svc = lib_ascs_svc_get();
|
||||
if (!ascs_svc) {
|
||||
LOG_ERR("[B]AscsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(ASCS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_init(ascs_svc);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_ascs_start(void)
|
||||
{
|
||||
struct bt_gatt_service *ascs_svc;
|
||||
|
||||
LOG_DBG("[B]AscsStart");
|
||||
|
||||
ascs_svc = lib_ascs_svc_get();
|
||||
if (!ascs_svc) {
|
||||
LOG_ERR("[B]AscsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(ASCS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(ascs_svc);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_BASS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
int bt_le_bluedroid_bass_init(void)
|
||||
{
|
||||
struct bt_gatt_service *bass_svc;
|
||||
|
||||
LOG_DBG("[B]BassInit");
|
||||
|
||||
bass_svc = lib_bap_bass_svc_get();
|
||||
if (!bass_svc) {
|
||||
LOG_ERR("[B]BassSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(BASS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_init(bass_svc);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_bass_start(void)
|
||||
{
|
||||
struct bt_gatt_service *bass_svc;
|
||||
|
||||
LOG_DBG("[B]BassStart");
|
||||
|
||||
bass_svc = lib_bap_bass_svc_get();
|
||||
if (!bass_svc) {
|
||||
LOG_ERR("[B]BassSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(BASS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(bass_svc);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.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;
|
||||
|
||||
struct inc_svc_inst *cas_not_included_inst(void)
|
||||
{
|
||||
if (inc_csis_inst.included == false) {
|
||||
return &inc_csis_inst;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */
|
||||
|
||||
int bt_le_bluedroid_cas_init(void *csis_svc_p)
|
||||
{
|
||||
struct bt_gatt_service *cas_svc;
|
||||
int err = 0;
|
||||
|
||||
LOG_DBG("[B]CasInit");
|
||||
|
||||
#if CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER
|
||||
/* csis_svc_p is non-NULL in practice (SET_MEMBER depends on CSIP_SET_MEMBER,
|
||||
* which populates it), but guard for parity with the nimble adapter. With
|
||||
* no CSIS, mark included=true so cas_not_included_inst() skips it and
|
||||
* svc_init never feeds a NULL svc_p into BTA_GATTS_AddIncludeService. */
|
||||
if (csis_svc_p) {
|
||||
/* The instance of CSIS is included by CAS */
|
||||
inc_csis_inst.svc_p = csis_svc_p;
|
||||
/* Reset included before svc_init; see mics.c for rationale. */
|
||||
inc_csis_inst.included = false;
|
||||
} else {
|
||||
inc_csis_inst.included = true;
|
||||
}
|
||||
#else /* CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */
|
||||
ARG_UNUSED(csis_svc_p);
|
||||
#endif /* CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */
|
||||
|
||||
cas_svc = lib_cas_svc_get();
|
||||
if (!cas_svc) {
|
||||
LOG_ERR("[B]CasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(CAS_IN_PROGRESS);
|
||||
|
||||
err = bt_le_bluedroid_svc_init(cas_svc);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER
|
||||
if (cas_not_included_inst()) {
|
||||
LOG_ERR("[B]CasCsisNotInc");
|
||||
return -EIO;
|
||||
}
|
||||
#else /* CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */
|
||||
/* Insert CAS to the GATT db list */
|
||||
err = bt_gatt_service_register_safe(cas_svc);
|
||||
if (err) {
|
||||
LOG_ERR("[B]CasSvcRegFail[%d]", err);
|
||||
}
|
||||
#endif /* CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_cas_start(void)
|
||||
{
|
||||
struct bt_gatt_service *cas_svc;
|
||||
|
||||
LOG_DBG("[B]CasStart");
|
||||
|
||||
cas_svc = lib_cas_svc_get();
|
||||
if (!cas_svc) {
|
||||
LOG_ERR("[B]CasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(CAS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(cas_svc);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
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 {
|
||||
struct bt_gatt_service *svc_p;
|
||||
} csis_insts[CSIS_SVC_COUNT];
|
||||
|
||||
static uint8_t csis_svc_count;
|
||||
|
||||
int bt_le_bluedroid_csis_init(void *svc, uint8_t count)
|
||||
{
|
||||
int err;
|
||||
|
||||
LOG_DBG("[B]CsisInit");
|
||||
|
||||
if (count > CSIS_SVC_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(CSIS_IN_PROGRESS);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
csis_insts[i].svc_p = ((struct bt_gatt_service **)svc)[i];
|
||||
|
||||
err = bt_le_bluedroid_svc_init(csis_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit the count only after the loop succeeds, so a mid-loop failure
|
||||
* doesn't leave csis_start() iterating uninitialized entries. */
|
||||
csis_svc_count = count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_csis_start(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
LOG_DBG("[B]CsisStart");
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(CSIS_IN_PROGRESS);
|
||||
|
||||
for (size_t i = 0; i < csis_svc_count; i++) {
|
||||
err = bt_le_bluedroid_svc_start(csis_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_HAS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
int bt_le_bluedroid_has_init(void)
|
||||
{
|
||||
struct bt_gatt_service *has_svc;
|
||||
|
||||
LOG_DBG("[B]HasInit");
|
||||
|
||||
has_svc = lib_has_svc_get();
|
||||
if (!has_svc) {
|
||||
LOG_ERR("[B]HasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(HAS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_init(has_svc);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_has_start(void)
|
||||
{
|
||||
struct bt_gatt_service *has_svc;
|
||||
|
||||
LOG_DBG("[B]HasStart");
|
||||
|
||||
has_svc = lib_has_svc_get();
|
||||
if (!has_svc) {
|
||||
LOG_ERR("[B]HasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(HAS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(has_svc);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_MCS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
int bt_le_bluedroid_gmcs_init(void)
|
||||
{
|
||||
struct bt_gatt_service *gmcs_svc;
|
||||
|
||||
gmcs_svc = lib_mcs_svc_get();
|
||||
if (!gmcs_svc) {
|
||||
LOG_ERR("[B]GmcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(GMCS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_init(gmcs_svc);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_gmcs_start(void)
|
||||
{
|
||||
struct bt_gatt_service *gmcs_svc;
|
||||
|
||||
gmcs_svc = lib_mcs_svc_get();
|
||||
if (!gmcs_svc) {
|
||||
LOG_ERR("[B]GmcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(GMCS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(gmcs_svc);
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/audio/micp.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.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 struct inc_svc_inst inc_aics_insts[AICS_INST_COUNT];
|
||||
|
||||
struct inc_svc_inst *mics_not_included_inst(void)
|
||||
{
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
if (inc_aics_insts[i].included == false) {
|
||||
return &inc_aics_insts[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_mics_init(void *micp_inc)
|
||||
{
|
||||
struct bt_micp_included *micp_included;
|
||||
struct bt_gatt_service *mics_svc;
|
||||
int err;
|
||||
|
||||
LOG_DBG("[B]MicsInit");
|
||||
|
||||
mics_svc = lib_mics_svc_get();
|
||||
if (!mics_svc) {
|
||||
LOG_ERR("[B]MicsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Reset before the NULL check so a re-init with micp_included == NULL
|
||||
* doesn't iterate over stale entries from a previous non-NULL call. */
|
||||
inc_aics_svc_count = 0;
|
||||
|
||||
micp_included = micp_inc;
|
||||
|
||||
if (micp_included) {
|
||||
if (micp_included->aics_cnt > AICS_INST_COUNT) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(AICS_IN_PROGRESS);
|
||||
|
||||
/* MICS may include zero or more instances of AICS */
|
||||
for (size_t i = 0; i < micp_included->aics_cnt; i++) {
|
||||
inc_aics_insts[i].svc_p = lib_aics_svc_get(micp_included->aics[i]);
|
||||
if (!inc_aics_insts[i].svc_p) {
|
||||
LOG_ERR("[B]AicsSvcGetFail[%u]", i);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Reset included before svc_init: server.c sets it to true when
|
||||
* the include attribute is processed. Without this reset, a
|
||||
* re-init where the include attribute is missing would leave
|
||||
* the stale true from a previous init and mics_not_included_inst()
|
||||
* would falsely report all instances as included. */
|
||||
inc_aics_insts[i].included = false;
|
||||
|
||||
err = bt_le_bluedroid_svc_init(inc_aics_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit the count only after every instance initialized — a mid-loop
|
||||
* failure above leaves it at 0 (reset on entry) so mics_start() never
|
||||
* iterates partially-initialized entries. */
|
||||
inc_aics_svc_count = micp_included->aics_cnt;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(MICS_IN_PROGRESS);
|
||||
|
||||
err = bt_le_bluedroid_svc_init(mics_svc);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (mics_not_included_inst()) {
|
||||
LOG_ERR("[B]MicsAicsNotAllInc");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_mics_start(void)
|
||||
{
|
||||
struct bt_gatt_service *mics_svc;
|
||||
int err;
|
||||
|
||||
LOG_DBG("[B]MicsStart");
|
||||
|
||||
mics_svc = lib_mics_svc_get();
|
||||
if (!mics_svc) {
|
||||
LOG_ERR("[B]MicsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(AICS_IN_PROGRESS);
|
||||
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
err = bt_le_bluedroid_svc_start(inc_aics_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(MICS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(mics_svc);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_PACS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
int bt_le_bluedroid_pacs_init(void)
|
||||
{
|
||||
struct bt_gatt_service *pacs_svc;
|
||||
|
||||
LOG_DBG("[B]PacsInit");
|
||||
|
||||
pacs_svc = lib_pacs_svc_get();
|
||||
if (!pacs_svc) {
|
||||
LOG_ERR("[B]PacsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(PACS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_init(pacs_svc);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_pacs_start(void)
|
||||
{
|
||||
struct bt_gatt_service *pacs_svc;
|
||||
|
||||
LOG_DBG("[B]PacsStart");
|
||||
|
||||
pacs_svc = lib_pacs_svc_get();
|
||||
if (!pacs_svc) {
|
||||
LOG_ERR("[B]PacsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(PACS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(pacs_svc);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_TBS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
int bt_le_bluedroid_gtbs_init(void)
|
||||
{
|
||||
struct bt_gatt_service *gtbs_svc;
|
||||
|
||||
gtbs_svc = lib_gtbs_svc_get();
|
||||
if (!gtbs_svc) {
|
||||
LOG_ERR("[B]GtbsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(GTBS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_init(gtbs_svc);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_gtbs_start(void)
|
||||
{
|
||||
struct bt_gatt_service *gtbs_svc;
|
||||
|
||||
gtbs_svc = lib_gtbs_svc_get();
|
||||
if (!gtbs_svc) {
|
||||
LOG_ERR("[B]GtbsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(GTBS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(gtbs_svc);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_TMAS, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
int bt_le_bluedroid_tmas_init(void)
|
||||
{
|
||||
struct bt_gatt_service *tmas_svc;
|
||||
|
||||
LOG_DBG("[B]TmasInit");
|
||||
|
||||
tmas_svc = lib_tmas_svc_get();
|
||||
if (!tmas_svc) {
|
||||
LOG_ERR("[B]TmasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(TMAS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_init(tmas_svc);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_tmas_start(void)
|
||||
{
|
||||
struct bt_gatt_service *tmas_svc;
|
||||
|
||||
LOG_DBG("[B]TmasStart");
|
||||
|
||||
tmas_svc = lib_tmas_svc_get();
|
||||
if (!tmas_svc) {
|
||||
LOG_ERR("[B]TmasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(TMAS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(tmas_svc);
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/audio/vcp.h>
|
||||
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
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 struct inc_svc_inst inc_vocs_insts[VOCS_INST_COUNT];
|
||||
static struct inc_svc_inst inc_aics_insts[AICS_INST_COUNT];
|
||||
|
||||
struct inc_svc_inst *vcs_not_included_inst(void)
|
||||
{
|
||||
for (size_t i = 0; i < inc_vocs_svc_count; i++) {
|
||||
if (inc_vocs_insts[i].included == false) {
|
||||
return &inc_vocs_insts[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
if (inc_aics_insts[i].included == false) {
|
||||
return &inc_aics_insts[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_vcs_init(void *vcp_inc)
|
||||
{
|
||||
struct bt_vcp_included *vcp_included;
|
||||
struct bt_gatt_service *vcs_svc;
|
||||
int err;
|
||||
|
||||
LOG_DBG("[B]VcsInit");
|
||||
|
||||
vcs_svc = lib_vcs_svc_get();
|
||||
if (!vcs_svc) {
|
||||
LOG_ERR("[B]VcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Reset before the NULL check so a re-init with vcp_included == NULL
|
||||
* doesn't iterate over stale entries from a previous non-NULL call. */
|
||||
inc_vocs_svc_count = 0;
|
||||
inc_aics_svc_count = 0;
|
||||
|
||||
vcp_included = vcp_inc;
|
||||
|
||||
if (vcp_included) {
|
||||
if (vcp_included->vocs_cnt > VOCS_INST_COUNT ||
|
||||
vcp_included->aics_cnt > AICS_INST_COUNT) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inc_vocs_svc_count = vcp_included->vocs_cnt;
|
||||
inc_aics_svc_count = vcp_included->aics_cnt;
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(VOCS_IN_PROGRESS);
|
||||
|
||||
/* VCS may include zero or more instances of VOCS */
|
||||
for (size_t i = 0; i < inc_vocs_svc_count; i++) {
|
||||
inc_vocs_insts[i].svc_p = lib_vocs_svc_get(vcp_included->vocs[i]);
|
||||
if (!inc_vocs_insts[i].svc_p) {
|
||||
LOG_ERR("[B]VocsSvcGetFail[%u]", i);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Reset included before svc_init; see mics.c for rationale. */
|
||||
inc_vocs_insts[i].included = false;
|
||||
|
||||
err = bt_le_bluedroid_svc_init(inc_vocs_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(AICS_IN_PROGRESS);
|
||||
|
||||
/* VCS may include zero or more instances of AICS */
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
inc_aics_insts[i].svc_p = lib_aics_svc_get(vcp_included->aics[i]);
|
||||
if (!inc_aics_insts[i].svc_p) {
|
||||
LOG_ERR("[B]AicsSvcGetFail[%u]", i);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Reset included before svc_init; see mics.c for rationale. */
|
||||
inc_aics_insts[i].included = false;
|
||||
|
||||
err = bt_le_bluedroid_svc_init(inc_aics_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(VCS_IN_PROGRESS);
|
||||
|
||||
err = bt_le_bluedroid_svc_init(vcs_svc);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (vcs_not_included_inst()) {
|
||||
LOG_ERR("[B]VcsVocsAicsNotAllInc");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_vcs_start(void)
|
||||
{
|
||||
struct bt_gatt_service *vcs_svc;
|
||||
int err;
|
||||
|
||||
LOG_DBG("[B]VcsStart");
|
||||
|
||||
vcs_svc = lib_vcs_svc_get();
|
||||
if (!vcs_svc) {
|
||||
LOG_ERR("[B]VcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(VOCS_IN_PROGRESS);
|
||||
|
||||
for (size_t i = 0; i < inc_vocs_svc_count; i++) {
|
||||
err = bt_le_bluedroid_svc_start(inc_vocs_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(AICS_IN_PROGRESS);
|
||||
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
err = bt_le_bluedroid_svc_start(inc_aics_insts[i].svc_p);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
bt_le_bluedroid_set_svc_in_progress(VCS_IN_PROGRESS);
|
||||
|
||||
return bt_le_bluedroid_svc_start(vcs_svc);
|
||||
}
|
||||
@@ -0,0 +1,596 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/autoconf.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/audio/micp.h>
|
||||
#include <zephyr/bluetooth/audio/vcp.h>
|
||||
|
||||
#include <../host/conn_internal.h>
|
||||
|
||||
#include "bta/bta_gatt_api.h"
|
||||
|
||||
#include "bluedroid/gatt.h"
|
||||
#include "bluedroid/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
LOG_MODULE_REGISTER(LEA_GSRV, CONFIG_BT_ISO_LOG_LEVEL);
|
||||
|
||||
static uint8_t svc_in_progress;
|
||||
|
||||
static uint16_t inc_svc_handle;
|
||||
static uint16_t svc_handle;
|
||||
static uint16_t chrc_handle;
|
||||
|
||||
static bool is_primary_svc(void)
|
||||
{
|
||||
if (svc_in_progress == ASCS_IN_PROGRESS ||
|
||||
svc_in_progress == BASS_IN_PROGRESS ||
|
||||
svc_in_progress == CAS_IN_PROGRESS ||
|
||||
svc_in_progress == CSIS_IN_PROGRESS ||
|
||||
svc_in_progress == HAS_IN_PROGRESS ||
|
||||
svc_in_progress == GMCS_IN_PROGRESS ||
|
||||
svc_in_progress == MCS_IN_PROGRESS ||
|
||||
svc_in_progress == MICS_IN_PROGRESS ||
|
||||
svc_in_progress == PACS_IN_PROGRESS ||
|
||||
svc_in_progress == GTBS_IN_PROGRESS ||
|
||||
svc_in_progress == TBS_IN_PROGRESS ||
|
||||
svc_in_progress == TMAS_IN_PROGRESS ||
|
||||
svc_in_progress == VCS_IN_PROGRESS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_secondary_svc(void)
|
||||
{
|
||||
if (svc_in_progress == AICS_IN_PROGRESS ||
|
||||
svc_in_progress == VOCS_IN_PROGRESS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool any_included_svc(void)
|
||||
{
|
||||
if (svc_in_progress == CAS_IN_PROGRESS ||
|
||||
svc_in_progress == MICS_IN_PROGRESS ||
|
||||
svc_in_progress == VCS_IN_PROGRESS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_svc_uuid_valid(uint16_t uuid)
|
||||
{
|
||||
switch (svc_in_progress) {
|
||||
case AICS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_AICS_VAL);
|
||||
|
||||
case ASCS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_ASCS_VAL);
|
||||
|
||||
case BASS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_BASS_VAL);
|
||||
|
||||
case CAS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_CAS_VAL);
|
||||
|
||||
case CSIS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_CSIS_VAL);
|
||||
|
||||
case HAS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_HAS_VAL);
|
||||
|
||||
case GMCS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_GMCS_VAL);
|
||||
|
||||
case MCS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_MCS_VAL);
|
||||
|
||||
case MICS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_MICS_VAL);
|
||||
|
||||
case PACS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_PACS_VAL);
|
||||
|
||||
case GTBS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_GTBS_VAL);
|
||||
|
||||
case TBS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_TBS_VAL);
|
||||
|
||||
case TMAS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_TMAS_VAL);
|
||||
|
||||
case VCS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_VCS_VAL);
|
||||
|
||||
case VOCS_IN_PROGRESS:
|
||||
return (uuid == BT_UUID_VOCS_VAL);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void svc_create_cb(uint16_t service_id, uint16_t svc_instance,
|
||||
bool is_primary, uint8_t status, void *uuid)
|
||||
{
|
||||
int result = status;
|
||||
|
||||
if ((is_primary_svc() && is_primary == false) ||
|
||||
(is_secondary_svc() && is_primary == true) ||
|
||||
((tBT_UUID *)uuid)->len != 2 ||
|
||||
is_svc_uuid_valid(((tBT_UUID *)uuid)->uu.uuid16) == false) {
|
||||
/* uuid16 is only meaningful when len == 2; for 32/128-bit UUIDs the
|
||||
* union access would log the first 2 bytes of a wider value. */
|
||||
if (((tBT_UUID *)uuid)->len == 2) {
|
||||
LOG_ERR("[B]SvcCreateMismatch[%u][%u][2][0x%04x]",
|
||||
svc_in_progress, is_primary,
|
||||
((tBT_UUID *)uuid)->uu.uuid16);
|
||||
} else {
|
||||
LOG_ERR("[B]SvcCreateMismatch[%u][%u][%u][nonU16]",
|
||||
svc_in_progress, is_primary,
|
||||
((tBT_UUID *)uuid)->len);
|
||||
}
|
||||
result = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
svc_handle = service_id;
|
||||
|
||||
end:
|
||||
bt_le_bluedroid_gatts_sem_give(result);
|
||||
}
|
||||
|
||||
static void inc_svc_add_cb(uint16_t service_id, uint16_t attr_id, uint8_t status)
|
||||
{
|
||||
int result = status;
|
||||
|
||||
if (service_id != svc_handle) {
|
||||
LOG_ERR("[B]IncSvcAddMismatch[%u][%u][%u]",
|
||||
svc_in_progress, service_id, svc_handle);
|
||||
result = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
inc_svc_handle = attr_id;
|
||||
|
||||
end:
|
||||
bt_le_bluedroid_gatts_sem_give(result);
|
||||
}
|
||||
|
||||
static void chrc_add_cb(uint16_t service_id, uint16_t attr_id,
|
||||
uint8_t status, void *uuid)
|
||||
{
|
||||
int result = status;
|
||||
|
||||
if (service_id != svc_handle || ((tBT_UUID *)uuid)->len != 2) {
|
||||
/* uuid16 is only meaningful when len == 2; for 32/128-bit UUIDs the
|
||||
* union access would log the first 2 bytes of a wider value. */
|
||||
if (((tBT_UUID *)uuid)->len == 2) {
|
||||
LOG_ERR("[B]ChrcAddMismatch[%u][%u][%u][2][0x%04x]",
|
||||
svc_in_progress, service_id, svc_handle,
|
||||
((tBT_UUID *)uuid)->uu.uuid16);
|
||||
} else {
|
||||
LOG_ERR("[B]ChrcAddMismatch[%u][%u][%u][%u][nonU16]",
|
||||
svc_in_progress, service_id, svc_handle,
|
||||
((tBT_UUID *)uuid)->len);
|
||||
}
|
||||
result = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
chrc_handle = attr_id;
|
||||
|
||||
end:
|
||||
bt_le_bluedroid_gatts_sem_give(result);
|
||||
}
|
||||
|
||||
static void svc_start_cb(uint16_t service_id, uint8_t status)
|
||||
{
|
||||
int result = status;
|
||||
|
||||
if (service_id != svc_handle) {
|
||||
LOG_ERR("[B]SvcStartMismatch[%u][%u]", service_id, svc_handle);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_gatts_sem_give(result);
|
||||
}
|
||||
|
||||
static struct gatts_svc_cb svc_cb = {
|
||||
.svc_create_cb = svc_create_cb,
|
||||
.inc_svc_add_cb = inc_svc_add_cb,
|
||||
.chrc_add_cb = chrc_add_cb,
|
||||
.svc_start_cb = svc_start_cb,
|
||||
};
|
||||
|
||||
void bt_le_bluedroid_audio_gatts_init(void)
|
||||
{
|
||||
bt_le_bluedroid_gatts_svc_cb_register(&svc_cb);
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_set_svc_in_progress(uint8_t value)
|
||||
{
|
||||
if (value >= MAX_IN_PROGRESS) {
|
||||
LOG_ERR("[B]SvcInProgressInv[%u]", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
svc_in_progress = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_svc_attr_uuid_valid(uint16_t attr_uuid)
|
||||
{
|
||||
switch (svc_in_progress) {
|
||||
case AICS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_AICS_STATE_VAL ||
|
||||
attr_uuid == BT_UUID_AICS_GAIN_SETTINGS_VAL ||
|
||||
attr_uuid == BT_UUID_AICS_INPUT_TYPE_VAL ||
|
||||
attr_uuid == BT_UUID_AICS_INPUT_STATUS_VAL ||
|
||||
attr_uuid == BT_UUID_AICS_CONTROL_VAL ||
|
||||
attr_uuid == BT_UUID_AICS_DESCRIPTION_VAL);
|
||||
|
||||
case ASCS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_ASCS_ASE_SNK_VAL ||
|
||||
attr_uuid == BT_UUID_ASCS_ASE_SRC_VAL ||
|
||||
attr_uuid == BT_UUID_ASCS_ASE_CP_VAL);
|
||||
|
||||
case BASS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_BASS_CONTROL_POINT_VAL ||
|
||||
attr_uuid == BT_UUID_BASS_RECV_STATE_VAL);
|
||||
|
||||
case CAS_IN_PROGRESS:
|
||||
/* No characteristic in CAS */
|
||||
return false;
|
||||
|
||||
case CSIS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_CSIS_SIRK_VAL ||
|
||||
attr_uuid == BT_UUID_CSIS_SET_SIZE_VAL ||
|
||||
attr_uuid == BT_UUID_CSIS_SET_LOCK_VAL ||
|
||||
attr_uuid == BT_UUID_CSIS_RANK_VAL);
|
||||
|
||||
case HAS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_HAS_HEARING_AID_FEATURES_VAL ||
|
||||
attr_uuid == BT_UUID_HAS_PRESET_CONTROL_POINT_VAL ||
|
||||
attr_uuid == BT_UUID_HAS_ACTIVE_PRESET_INDEX_VAL);
|
||||
|
||||
case GMCS_IN_PROGRESS:
|
||||
case MCS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_MCS_PLAYER_NAME_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_ICON_OBJ_ID_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_ICON_URL_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_TRACK_CHANGED_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_TRACK_TITLE_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_TRACK_DURATION_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_TRACK_POSITION_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_PLAYBACK_SPEED_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_SEEKING_SPEED_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_TRACK_SEGMENTS_OBJ_ID_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_CURRENT_TRACK_OBJ_ID_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_NEXT_TRACK_OBJ_ID_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_PARENT_GROUP_OBJ_ID_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_CURRENT_GROUP_OBJ_ID_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_PLAYING_ORDER_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_PLAYING_ORDERS_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_MEDIA_STATE_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_MEDIA_CONTROL_POINT_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_MEDIA_CONTROL_OPCODES_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_SEARCH_RESULTS_OBJ_ID_VAL ||
|
||||
attr_uuid == BT_UUID_MCS_SEARCH_CONTROL_POINT_VAL ||
|
||||
attr_uuid == BT_UUID_CCID_VAL);
|
||||
|
||||
case MICS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_MICS_MUTE_VAL);
|
||||
|
||||
case PACS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_PACS_SNK_VAL ||
|
||||
attr_uuid == BT_UUID_PACS_SNK_LOC_VAL ||
|
||||
attr_uuid == BT_UUID_PACS_SRC_VAL ||
|
||||
attr_uuid == BT_UUID_PACS_SRC_LOC_VAL ||
|
||||
attr_uuid == BT_UUID_PACS_AVAILABLE_CONTEXT_VAL ||
|
||||
attr_uuid == BT_UUID_PACS_SUPPORTED_CONTEXT_VAL);
|
||||
|
||||
case GTBS_IN_PROGRESS:
|
||||
case TBS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_TBS_PROVIDER_NAME_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_UCI_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_TECHNOLOGY_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_URI_LIST_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_SIGNAL_STRENGTH_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_SIGNAL_INTERVAL_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_LIST_CURRENT_CALLS_VAL ||
|
||||
attr_uuid == BT_UUID_CCID_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_STATUS_FLAGS_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_INCOMING_URI_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_CALL_STATE_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_CALL_CONTROL_POINT_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_OPTIONAL_OPCODES_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_TERMINATE_REASON_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_INCOMING_CALL_VAL ||
|
||||
attr_uuid == BT_UUID_TBS_FRIENDLY_NAME_VAL);
|
||||
|
||||
case TMAS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_GATT_TMAPR_VAL);
|
||||
|
||||
case VCS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_VCS_STATE_VAL ||
|
||||
attr_uuid == BT_UUID_VCS_CONTROL_VAL ||
|
||||
attr_uuid == BT_UUID_VCS_FLAGS_VAL);
|
||||
|
||||
case VOCS_IN_PROGRESS:
|
||||
return (attr_uuid == BT_UUID_VOCS_STATE_VAL ||
|
||||
attr_uuid == BT_UUID_VOCS_LOCATION_VAL ||
|
||||
attr_uuid == BT_UUID_VOCS_CONTROL_VAL ||
|
||||
attr_uuid == BT_UUID_VOCS_DESCRIPTION_VAL);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct inc_svc_inst *get_not_included_inst(void)
|
||||
{
|
||||
switch (svc_in_progress) {
|
||||
#if CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER
|
||||
case CAS_IN_PROGRESS:
|
||||
extern struct inc_svc_inst *cas_not_included_inst(void);
|
||||
return cas_not_included_inst();
|
||||
#endif /* CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER */
|
||||
|
||||
#if CONFIG_BT_MICP_MIC_DEV
|
||||
case MICS_IN_PROGRESS:
|
||||
extern struct inc_svc_inst *mics_not_included_inst(void);
|
||||
return mics_not_included_inst();
|
||||
#endif /* CONFIG_BT_MICP_MIC_DEV */
|
||||
|
||||
#if CONFIG_BT_VCP_VOL_REND
|
||||
case VCS_IN_PROGRESS:
|
||||
extern struct inc_svc_inst *vcs_not_included_inst(void);
|
||||
return vcs_not_included_inst();
|
||||
#endif /* CONFIG_BT_VCP_VOL_REND */
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t get_svc_inst_id(uint16_t svc_uuid)
|
||||
{
|
||||
/* Note:
|
||||
* 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;
|
||||
|
||||
switch (svc_uuid) {
|
||||
case BT_UUID_AICS_VAL:
|
||||
return aics_count++;
|
||||
|
||||
case BT_UUID_CSIS_VAL:
|
||||
return csis_count++;
|
||||
|
||||
case BT_UUID_VOCS_VAL:
|
||||
return vocs_count++;
|
||||
|
||||
case BT_UUID_MCS_VAL:
|
||||
return mcs_count++;
|
||||
|
||||
case BT_UUID_OTS_VAL:
|
||||
return ots_count++;
|
||||
|
||||
case BT_UUID_TBS_VAL:
|
||||
return tbs_count++;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_svc_init(struct bt_gatt_service *svc)
|
||||
{
|
||||
struct bt_gatt_attr *curr_attr;
|
||||
struct bt_gatt_attr *next_attr;
|
||||
struct inc_svc_inst *inc_inst;
|
||||
struct bt_gatt_chrc *chrc;
|
||||
tBTA_GATT_PERM perm;
|
||||
uint16_t attr_uuid;
|
||||
uint8_t inst_id;
|
||||
tBT_UUID uuid;
|
||||
|
||||
assert(svc);
|
||||
|
||||
for (size_t i = 0; i < svc->attr_count; i++) {
|
||||
curr_attr = &svc->attrs[i];
|
||||
|
||||
attr_uuid = BT_UUID_16(curr_attr->uuid)->val;
|
||||
|
||||
switch (attr_uuid) {
|
||||
case BT_UUID_GATT_PRIMARY_VAL:
|
||||
if (is_primary_svc() == false) {
|
||||
LOG_ERR("[B]NotCreatingPrimary");
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(curr_attr->user_data);
|
||||
|
||||
bt_le_bluedroid_gatt_uuid_convert(curr_attr->user_data, &uuid);
|
||||
inst_id = get_svc_inst_id(uuid.uu.uuid16);
|
||||
|
||||
bt_le_bluedroid_gatts_sem_reset();
|
||||
BTA_GATTS_CreateService(bt_le_bluedroid_gatts_get_if(), &uuid, inst_id, svc->attr_count, true);
|
||||
|
||||
if (bt_le_bluedroid_gatts_sem_take()) {
|
||||
LOG_ERR("[B]PrimaryCreateFail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curr_attr->handle = svc_handle;
|
||||
|
||||
LOG_INF("[B]PrimarySvc[%s][0x%04x][%u][0x%04x][%d]",
|
||||
audio_svc_uuid_to_str(uuid.uu.uuid16), uuid.uu.uuid16,
|
||||
inst_id, curr_attr->perm, svc_handle);
|
||||
break;
|
||||
|
||||
case BT_UUID_GATT_SECONDARY_VAL:
|
||||
if (is_secondary_svc() == false) {
|
||||
LOG_ERR("[B]NotCreatingSecondary");
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(curr_attr->user_data);
|
||||
|
||||
bt_le_bluedroid_gatt_uuid_convert(curr_attr->user_data, &uuid);
|
||||
inst_id = get_svc_inst_id(uuid.uu.uuid16);
|
||||
|
||||
bt_le_bluedroid_gatts_sem_reset();
|
||||
BTA_GATTS_CreateService(bt_le_bluedroid_gatts_get_if(), &uuid, inst_id, svc->attr_count, false);
|
||||
|
||||
if (bt_le_bluedroid_gatts_sem_take()) {
|
||||
LOG_ERR("[B]SecondaryCreateFail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curr_attr->handle = svc_handle;
|
||||
|
||||
LOG_INF("[B]SecondarySvc[%s][0x%04x][%u][0x%04x][%d]",
|
||||
audio_svc_uuid_to_str(uuid.uu.uuid16), uuid.uu.uuid16,
|
||||
inst_id, curr_attr->perm, svc_handle);
|
||||
break;
|
||||
|
||||
case BT_UUID_GATT_INCLUDE_VAL:
|
||||
if (any_included_svc() == false) {
|
||||
LOG_ERR("[B]NoSvcToInc[%u]", svc_in_progress);
|
||||
return -1;
|
||||
}
|
||||
|
||||
inc_inst = get_not_included_inst();
|
||||
|
||||
if (inc_inst == NULL) {
|
||||
LOG_ERR("[B]IncSvcNotFound[%u]", svc_in_progress);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_gatts_sem_reset();
|
||||
BTA_GATTS_AddIncludeService(svc_handle, inc_inst->svc_p->attrs[0].handle);
|
||||
|
||||
if (bt_le_bluedroid_gatts_sem_take()) {
|
||||
LOG_ERR("[B]IncSvcAddFail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curr_attr->handle = inc_svc_handle;
|
||||
inc_inst->included = true; /* Mark the svc as included */
|
||||
|
||||
LOG_INF("[B]IncSvc[%s][0x%04x][0x%04x][%d]",
|
||||
audio_svc_uuid_to_str(BT_UUID_16(inc_inst->svc_p->attrs[0].user_data)->val),
|
||||
BT_UUID_16(inc_inst->svc_p->attrs[0].user_data)->val,
|
||||
curr_attr->perm, inc_svc_handle);
|
||||
break;
|
||||
|
||||
case BT_UUID_GATT_CHRC_VAL:
|
||||
/* Chrc declaration must be followed by its value attribute.
|
||||
* Standard BT_GATT_CHARACTERISTIC pairs them, but guard against
|
||||
* a malformed table where it is the last entry. */
|
||||
if (i + 1 >= svc->attr_count) {
|
||||
LOG_ERR("[B]ChrcDeclLastAttr[%u]", svc_in_progress);
|
||||
return -1;
|
||||
}
|
||||
|
||||
next_attr = &svc->attrs[i + 1];
|
||||
perm = bt_le_bluedroid_gatt_perm_convert(next_attr->perm);
|
||||
|
||||
assert(curr_attr->user_data);
|
||||
|
||||
chrc = curr_attr->user_data;
|
||||
bt_le_bluedroid_gatt_uuid_convert(chrc->uuid, &uuid);
|
||||
bt_le_bluedroid_gatts_sem_reset();
|
||||
BTA_GATTS_AddCharacteristic(svc_handle, &uuid, perm, chrc->properties, NULL, NULL);
|
||||
|
||||
if (bt_le_bluedroid_gatts_sem_take()) {
|
||||
LOG_ERR("[B]ChrcAddFail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Characteristic declaration handle and Characteristic value handle */
|
||||
curr_attr->handle = chrc_handle - 1;
|
||||
next_attr->handle = chrc_handle;
|
||||
|
||||
LOG_INF("[B]Chrc[%s][0x%04x][%u][%u][0x%04x][0x%02x]",
|
||||
audio_chrc_uuid_to_str(uuid.uu.uuid16), uuid.uu.uuid16,
|
||||
chrc_handle - 1, chrc_handle, next_attr->perm, chrc->properties);
|
||||
break;
|
||||
|
||||
case BT_UUID_GATT_CCC_VAL:
|
||||
perm = bt_le_bluedroid_gatt_perm_convert(curr_attr->perm);
|
||||
bt_le_bluedroid_gatt_uuid_convert(curr_attr->uuid, &uuid);
|
||||
bt_le_bluedroid_gatts_sem_reset();
|
||||
BTA_GATTS_AddCharDescriptor(svc_handle, perm, &uuid, NULL, NULL);
|
||||
|
||||
if (bt_le_bluedroid_gatts_sem_take()) {
|
||||
LOG_ERR("[B]ChrcCccdAddFail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curr_attr->handle = chrc_handle;
|
||||
|
||||
LOG_INF("[B]ChrcCccd[%u][0x%04x]", chrc_handle, curr_attr->perm);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (is_svc_attr_uuid_valid(attr_uuid) == false) {
|
||||
LOG_ERR("[B]InvSvcAttrUuid[0x%04x][%u]", attr_uuid, svc_in_progress);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_le_bluedroid_svc_start(struct bt_gatt_service *svc)
|
||||
{
|
||||
assert(svc);
|
||||
|
||||
svc_handle = svc->attrs[0].handle;
|
||||
|
||||
/* App may not register this svc (e.g. CAP Acceptor single mode keeps
|
||||
* unused capability built). Skip rather than fail audio_start.
|
||||
*/
|
||||
if (svc_handle == 0) {
|
||||
LOG_DBG("[B]SvcNotInit[%u]", svc_in_progress);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bt_le_bluedroid_gatts_sem_reset();
|
||||
BTA_GATTS_StartService(svc_handle, BTA_GATT_TRANSPORT_LE);
|
||||
|
||||
if (bt_le_bluedroid_gatts_sem_take()) {
|
||||
LOG_ERR("[B]SvcStartFail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -313,13 +313,18 @@ static int nimble_gatt_csis_init(struct bt_le_audio_start_info *info,
|
||||
}
|
||||
|
||||
csis_svc[count] = lib_csip_set_member_svc_get(info->csis_insts[i].svc_inst);
|
||||
assert(csis_svc[count]);
|
||||
if (!csis_svc[count]) {
|
||||
LOG_ERR("[N]CsisSvcGetFail[%u]", i);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (info->csis_insts[i].included_by_cas) {
|
||||
if (*inc_csis_svc == NULL) {
|
||||
*inc_csis_svc = csis_svc[count];
|
||||
} else {
|
||||
assert(0);
|
||||
/* CAS may include at most one CSIS — caller misconfigured. */
|
||||
LOG_ERR("[N]CsisMultiIncByCas");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -122,7 +122,10 @@ int bt_le_nimble_ascs_attr_handle_set(void)
|
||||
}
|
||||
|
||||
ascs_svc = lib_ascs_svc_get();
|
||||
assert(ascs_svc);
|
||||
if (!ascs_svc) {
|
||||
LOG_ERR("[N]AscsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
assert(ase_control_point_handle >= 2);
|
||||
start_handle = ase_control_point_handle - 2; /* server attr handle & char def handle */
|
||||
@@ -164,7 +167,10 @@ static int ascs_svc_check(void)
|
||||
*/
|
||||
|
||||
ascs_svc = lib_ascs_svc_get();
|
||||
assert(ascs_svc);
|
||||
if (!ascs_svc) {
|
||||
LOG_ERR("[N]AscsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]AscsSvcCheck");
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -98,7 +98,10 @@ int bt_le_nimble_bass_attr_handle_set(void)
|
||||
}
|
||||
|
||||
bass_svc = lib_bap_bass_svc_get();
|
||||
assert(bass_svc);
|
||||
if (!bass_svc) {
|
||||
LOG_ERR("[N]BassSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
assert(bass_control_point_handle >= 2);
|
||||
start_handle = bass_control_point_handle - 2; /* server attr handle & char def handle */
|
||||
@@ -134,7 +137,10 @@ static int bass_svc_check(void)
|
||||
*/
|
||||
|
||||
bass_svc = lib_bap_bass_svc_get();
|
||||
assert(bass_svc);
|
||||
if (!bass_svc) {
|
||||
LOG_ERR("[N]BassSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]BassSvcCheck");
|
||||
|
||||
|
||||
@@ -60,7 +60,10 @@ int bt_le_nimble_cas_attr_handle_set(void)
|
||||
}
|
||||
|
||||
cas_svc = lib_cas_svc_get();
|
||||
assert(cas_svc);
|
||||
if (!cas_svc) {
|
||||
LOG_ERR("[N]CasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]CasAttrHdlSet[%u][%u]", handle, cas_svc->attr_count);
|
||||
|
||||
@@ -113,7 +116,10 @@ int bt_le_nimble_cas_init(void *csis_svc_p)
|
||||
struct bt_gatt_service *cas_svc;
|
||||
|
||||
cas_svc = lib_cas_svc_get();
|
||||
assert(cas_svc);
|
||||
if (!cas_svc) {
|
||||
LOG_ERR("[N]CasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Insert CAS to the GATT db list */
|
||||
rc = bt_gatt_service_register_safe(cas_svc);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -120,7 +120,10 @@ int bt_le_nimble_has_attr_handle_set(void)
|
||||
}
|
||||
|
||||
has_svc = lib_has_svc_get();
|
||||
assert(has_svc);
|
||||
if (!has_svc) {
|
||||
LOG_ERR("[N]HasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
assert(has_svc->attr_count > 0);
|
||||
|
||||
end_handle = start_handle + has_svc->attr_count - 1;
|
||||
@@ -136,7 +139,7 @@ int bt_le_nimble_has_attr_handle_set(void)
|
||||
attr = has_svc->attrs + has_svc->attr_count - 1;
|
||||
|
||||
if (attr->handle != end_handle) {
|
||||
LOG_ERR("[N]HasMismatchAttrHdl (%u %u %u %u)",
|
||||
LOG_ERR("[N]HasMismatchAttrHdl[%u][%u][%u][%u]",
|
||||
start_handle, end_handle, attr->handle, has_svc->attr_count);
|
||||
return -1;
|
||||
}
|
||||
@@ -155,7 +158,10 @@ static int has_svc_check(void)
|
||||
*/
|
||||
|
||||
has_svc = lib_has_svc_get();
|
||||
assert(has_svc);
|
||||
if (!has_svc) {
|
||||
LOG_ERR("[N]HasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]HasSvcCheck");
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -403,7 +403,10 @@ int bt_le_nimble_gmcs_attr_handle_set(void)
|
||||
}
|
||||
|
||||
gmcs_svc = lib_mcs_svc_get();
|
||||
assert(gmcs_svc);
|
||||
if (!gmcs_svc) {
|
||||
LOG_ERR("[N]GmcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
end_handle = start_handle + gmcs_svc->attr_count - 1;
|
||||
|
||||
@@ -446,7 +449,10 @@ static int gmcs_svc_check(void)
|
||||
*/
|
||||
|
||||
gmcs_svc = lib_mcs_svc_get();
|
||||
assert(gmcs_svc);
|
||||
if (!gmcs_svc) {
|
||||
LOG_ERR("[N]GmcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]GmcsSvcCheck");
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -159,7 +159,10 @@ static int mics_svc_check(void)
|
||||
bool chr_found;
|
||||
|
||||
mics_svc = lib_mics_svc_get();
|
||||
assert(mics_svc);
|
||||
if (!mics_svc) {
|
||||
LOG_ERR("[N]MicsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]MicsSvcCheck");
|
||||
|
||||
@@ -244,7 +247,10 @@ int bt_le_nimble_mics_attr_handle_set(void)
|
||||
}
|
||||
|
||||
mics_svc = lib_mics_svc_get();
|
||||
assert(mics_svc);
|
||||
if (!mics_svc) {
|
||||
LOG_ERR("[N]MicsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
end_handle = start_handle + mics_svc->attr_count - 1;
|
||||
|
||||
@@ -379,6 +385,11 @@ int bt_le_nimble_mics_init(void *micp_inc)
|
||||
inc_aics_svc_init(&inc_aics_insts[i], &gatt_svc_inc_aics[i]);
|
||||
|
||||
inc_aics_insts[i].svc_p = lib_aics_svc_get(micp_included->aics[i]);
|
||||
if (!inc_aics_insts[i].svc_p) {
|
||||
LOG_ERR("[N]AicsSvcGetFail[%u]", i);
|
||||
rc = -ENODEV;
|
||||
goto free;
|
||||
}
|
||||
|
||||
mics_inc_svcs[i] = &gatt_svc_inc_aics[i];
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -166,7 +166,10 @@ int bt_le_nimble_pacs_attr_handle_set(void)
|
||||
uint16_t end_handle = 0;
|
||||
|
||||
pacs_svc = lib_pacs_svc_get();
|
||||
assert(pacs_svc);
|
||||
if (!pacs_svc) {
|
||||
LOG_ERR("[N]PacsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_PAC_SNK
|
||||
assert(pacs_snk_handle >= 2);
|
||||
@@ -214,7 +217,10 @@ static int pacs_svc_check(void)
|
||||
*/
|
||||
|
||||
pacs_svc = lib_pacs_svc_get();
|
||||
assert(pacs_svc);
|
||||
if (!pacs_svc) {
|
||||
LOG_ERR("[N]PacsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]PacsSvcCheck");
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -178,7 +178,10 @@ int bt_le_nimble_gtbs_attr_handle_set(void)
|
||||
}
|
||||
|
||||
gtbs_svc = lib_gtbs_svc_get();
|
||||
assert(gtbs_svc);
|
||||
if (!gtbs_svc) {
|
||||
LOG_ERR("[N]GtbsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]GtbsAttrHdlSet[%u][%u]", handle, gtbs_svc->attr_count);
|
||||
|
||||
@@ -200,7 +203,10 @@ static int gtbs_svc_check(void)
|
||||
*/
|
||||
|
||||
gtbs_svc = lib_gtbs_svc_get();
|
||||
assert(gtbs_svc);
|
||||
if (!gtbs_svc) {
|
||||
LOG_ERR("[N]GtbsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]GtbsSvcCheck");
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -71,7 +71,10 @@ int bt_le_nimble_tmas_attr_handle_set(void)
|
||||
}
|
||||
|
||||
tmas_svc = lib_tmas_svc_get();
|
||||
assert(tmas_svc);
|
||||
if (!tmas_svc) {
|
||||
LOG_ERR("[N]TmasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]TmasAttrHdlSet[%u][%u]", handle, tmas_svc->attr_count);
|
||||
|
||||
@@ -93,7 +96,10 @@ static int tmas_svc_check(void)
|
||||
*/
|
||||
|
||||
tmas_svc = lib_tmas_svc_get();
|
||||
assert(tmas_svc);
|
||||
if (!tmas_svc) {
|
||||
LOG_ERR("[N]TmasSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]TmasSvcCheck");
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "host/ble_gatt.h"
|
||||
#include "host/ble_hs_mbuf.h"
|
||||
|
||||
#include "nimble/profiles/server.h"
|
||||
#include "nimble/server.h"
|
||||
|
||||
#include "common/host.h"
|
||||
|
||||
@@ -261,7 +261,10 @@ static int vcs_svc_check(void)
|
||||
*/
|
||||
|
||||
vcs_svc = lib_vcs_svc_get();
|
||||
assert(vcs_svc);
|
||||
if (!vcs_svc) {
|
||||
LOG_ERR("[N]VcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
LOG_DBG("[N]VCSSvcCheck");
|
||||
|
||||
@@ -380,7 +383,10 @@ int bt_le_nimble_vcs_attr_handle_set(void)
|
||||
}
|
||||
|
||||
vcs_svc = lib_vcs_svc_get();
|
||||
assert(vcs_svc);
|
||||
if (!vcs_svc) {
|
||||
LOG_ERR("[N]VcsSvcGetFail");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
end_handle = start_handle + vcs_svc->attr_count - 1;
|
||||
|
||||
@@ -576,6 +582,11 @@ int bt_le_nimble_vcs_init(void *vcp_inc)
|
||||
inc_vocs_svc_init(&inc_vocs_insts[i], &gatt_svc_inc_vocs[i]);
|
||||
|
||||
inc_vocs_insts[i].svc_p = lib_vocs_svc_get(vcp_included->vocs[i]);
|
||||
if (!inc_vocs_insts[i].svc_p) {
|
||||
LOG_ERR("[N]VocsSvcGetFail[%u]", i);
|
||||
rc = -ENODEV;
|
||||
goto free;
|
||||
}
|
||||
|
||||
vcs_inc_svcs[i] = &gatt_svc_inc_vocs[i];
|
||||
}
|
||||
@@ -608,6 +619,11 @@ int bt_le_nimble_vcs_init(void *vcp_inc)
|
||||
inc_aics_svc_init(&inc_aics_insts[i], &gatt_svc_inc_aics[i]);
|
||||
|
||||
inc_aics_insts[i].svc_p = lib_aics_svc_get(vcp_included->aics[i]);
|
||||
if (!inc_aics_insts[i].svc_p) {
|
||||
LOG_ERR("[N]AicsSvcGetFail[%u]", i);
|
||||
rc = -ENODEV;
|
||||
goto free;
|
||||
}
|
||||
|
||||
vcs_inc_svcs[inc_vocs_svc_count + i] = &gatt_svc_inc_aics[i];
|
||||
}
|
||||
@@ -670,13 +686,17 @@ free:
|
||||
}
|
||||
|
||||
if (inc_aics_svc_count) {
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
free((void *)gatt_svc_inc_aics[i].characteristics);
|
||||
gatt_svc_inc_aics[i].characteristics = NULL;
|
||||
}
|
||||
/* A VOCS-phase failure reaches here with the count already set
|
||||
* but gatt_svc_inc_aics not yet allocated (still NULL). */
|
||||
if (gatt_svc_inc_aics) {
|
||||
for (size_t i = 0; i < inc_aics_svc_count; i++) {
|
||||
free((void *)gatt_svc_inc_aics[i].characteristics);
|
||||
gatt_svc_inc_aics[i].characteristics = NULL;
|
||||
}
|
||||
|
||||
free(gatt_svc_inc_aics);
|
||||
gatt_svc_inc_aics = NULL;
|
||||
free(gatt_svc_inc_aics);
|
||||
gatt_svc_inc_aics = NULL;
|
||||
}
|
||||
|
||||
inc_aics_svc_count = 0;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,11 @@
|
||||
#include <../host/conn_internal.h>
|
||||
#include <../host/hci_core.h>
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "bluedroid/init.h"
|
||||
#else
|
||||
#include "nimble/init.h"
|
||||
#endif
|
||||
|
||||
#include "../../../lib/include/audio.h"
|
||||
|
||||
@@ -2091,7 +2095,11 @@ int bt_le_audio_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_audio_init();
|
||||
#else
|
||||
return bt_le_nimble_audio_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BLE_AUDIO_SVC_DEFERRED_ADD
|
||||
@@ -2100,7 +2108,11 @@ int bt_le_ascs_init(void)
|
||||
{
|
||||
LOG_DBG("AscsInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_ascs_init();
|
||||
#else
|
||||
return bt_le_nimble_ascs_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_ASCS */
|
||||
|
||||
@@ -2109,7 +2121,11 @@ int bt_le_bass_init(void)
|
||||
{
|
||||
LOG_DBG("BassInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_bass_init();
|
||||
#else
|
||||
return bt_le_nimble_bass_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
|
||||
|
||||
@@ -2118,7 +2134,11 @@ int bt_le_tmas_init(void)
|
||||
{
|
||||
LOG_DBG("TmasInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_tmas_init();
|
||||
#else
|
||||
return bt_le_nimble_tmas_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_TMAP */
|
||||
|
||||
@@ -2127,7 +2147,11 @@ int bt_le_gtbs_init(void)
|
||||
{
|
||||
LOG_DBG("GtbsInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_gtbs_init();
|
||||
#else
|
||||
return bt_le_nimble_gtbs_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_TBS */
|
||||
|
||||
@@ -2136,7 +2160,11 @@ int bt_le_has_init(void)
|
||||
{
|
||||
LOG_DBG("HasInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_has_init();
|
||||
#else
|
||||
return bt_le_nimble_has_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_HAS */
|
||||
|
||||
@@ -2145,7 +2173,11 @@ int bt_le_media_proxy_pl_init(void)
|
||||
{
|
||||
LOG_DBG("MprxPlInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_media_proxy_pl_init();
|
||||
#else
|
||||
return bt_le_nimble_media_proxy_pl_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_MCS */
|
||||
|
||||
@@ -2154,7 +2186,11 @@ int bt_le_vcp_vol_rend_init(void)
|
||||
{
|
||||
LOG_DBG("VcpVolRendInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_vcp_vol_rend_init();
|
||||
#else
|
||||
return bt_le_nimble_vcp_vol_rend_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_VCP_VOL_REND */
|
||||
|
||||
@@ -2163,7 +2199,11 @@ int bt_le_micp_mic_dev_init(void)
|
||||
{
|
||||
LOG_DBG("MicpMicDevInit");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_micp_mic_dev_init();
|
||||
#else
|
||||
return bt_le_nimble_micp_mic_dev_init();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_MICP_MIC_DEV */
|
||||
#endif /* BLE_AUDIO_SVC_DEFERRED_ADD */
|
||||
@@ -2172,7 +2212,11 @@ int bt_le_audio_start(void *info)
|
||||
{
|
||||
LOG_DBG("AudioStart");
|
||||
|
||||
#if CONFIG_BT_BLUEDROID_ENABLED
|
||||
return bt_le_bluedroid_audio_start(info);
|
||||
#else
|
||||
return bt_le_nimble_audio_start(info);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ble_audio_lib_compressed_out(uint8_t log_level, uint32_t log_index, size_t arg_cnt, ...)
|
||||
|
||||
Reference in New Issue
Block a user