From b5e0bab5d638739ecb08780ecb61faeb88f1a15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 28 Sep 2023 13:42:51 +0200 Subject: [PATCH] nimble/host: broadcast and Auracast API proposal This is proposal of API that could be used to create BASE configuration manage\ its broadcast (setup extended advertising, periodic advertising and BASE advertisements, stop, resume, terminate and modify them) --- .../host/include/host/ble_audio_broadcast.h | 247 ++++++++++++++++++ nimble/host/include/host/ble_audio_common.h | 180 +++++++++++++ nimble/host/include/host/ble_iso.h | 51 ++++ .../include/leaudio/auracast/auracast.h | 101 +++++++ 4 files changed, 579 insertions(+) create mode 100644 nimble/host/include/host/ble_audio_broadcast.h create mode 100644 nimble/host/include/host/ble_audio_common.h create mode 100644 nimble/host/include/host/ble_iso.h create mode 100644 nimble/host/services/leaudio/auracast/include/leaudio/auracast/auracast.h diff --git a/nimble/host/include/host/ble_audio_broadcast.h b/nimble/host/include/host/ble_audio_broadcast.h new file mode 100644 index 0000000000..7b08fde733 --- /dev/null +++ b/nimble/host/include/host/ble_audio_broadcast.h @@ -0,0 +1,247 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_AUDIO_BROADCAST_ +#define H_BLE_AUDIO_BROADCAST_ + +#include +#include "host/ble_gap.h" +#include "host/ble_iso.h" +#include "host/ble_audio_common.h" + +struct ble_broadcast_create_params { + /** BIG to broadcast */ + struct ble_audio_big *big; + + /** BLE address to use for advertising */ + ble_addr_t *addr; + + /** Parameters used to configure Extended advertising */ + struct ble_gap_ext_adv_params *extended_params; + + /** Parameters used to configure Periodic advertising */ + struct ble_gap_periodic_adv_params *periodic_params; + + /** Broadcast name - null terminated. + * Set NULL to not include in advertising + */ + const char *name; + + /** Advertising instance */ + uint8_t adv_instance; + + /** BIG parameters */ + struct ble_iso_big_params *big_params; + + /** Additional data to include in Extended Advertising */ + uint8_t *svc_data; +}; + +typedef int ble_audio_broadcast_destroy_fn(struct ble_audio_big *big, + void *args); + +/** BASE configuration describing broadcast advertisement */ +struct ble_broadcast_base_config { + /** Advertising instance used by broadcast */ + uint8_t adv_instance; + + /** Pointer to BIG configuration */ + struct ble_audio_big *big; + + /** BIG parameters */ + struct ble_iso_big_params *big_params; + + /** + * Optional callback associated with broadcasting instance, called on + * destroying broadcast + */ + ble_audio_broadcast_destroy_fn *destroy_cb; + + /** Pointer to args for `destroy_cb` */ + void *args; +}; + +/** + * @brief Create Broadcast Audio Source Endpoint and configure advertising + * instance + * + * This function configures advertising instance for extended and periodic + * advertisements to be ready for broadcast with BASE configuration. + * + * @param[in] params Pointer to a `ble_broadcast_base_params` + * structure that defines BIG, extended + * advertising and periodic advertising + * configuration. + * @param[out] config_out Pointer to a `ble_broadcast_base_config` + * structure to return configuration of created + * BASE advertisement. + * @param[in] destroy_cb Optional callback to be called when BASE + * advertisement is destroyed. + * @param[in] args Optional arguments to be passed to `destroy_cb` + * @param[in] gap_cb GAP event callback to be associated with BASE + * advertisement. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_create(const struct ble_broadcast_create_params + *params, + struct ble_broadcast_base_config *config_out, + ble_audio_broadcast_destroy_fn *destroy_cb, + const void *args, + ble_gap_event_fn *gap_cb); + +/** + * @brief Start advertisements for given BASE configuration + * + * This function starts BASE advertisement on by enabling extended and periodic + * advertising and creates BIG for this instance. + * + * @param[in] base_config Pointer to a `ble_broadcast_base_config` + * struct that shall be used for broadcast. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_start(const struct ble_broadcast_base_config + *base_config); + +/** + * @brief Stop advertisements for given BASE configuration + * + * This function stops BASE advertisement by disabling extended and periodic + * advertising. Advertising instance is still configured and ready for resume. + * BIG will be terminated. + * + * @param[in] base_config Pointer to a `ble_broadcast_base_config` + * struct that broadcast shall be stopped for. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_stop(const struct ble_broadcast_base_config + *base_config); + +/** + * @brief Destroy advertisements for given BASE configuration + * + * This function stops BASE advertisement by disabling extended and periodic + * advertising and terminates them. After return advertising instance is free + * and must be configured again for future advertisements. + * + * @param[in] base_config Pointer to a `ble_broadcast_base_config` + * struct that broadcast shall be terminated for. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_destroy(const struct ble_broadcast_base_config *base_config); + +/** + * @brief Update advertisements for given BASE configuration + * + * This function can be used to update extended advertisements. This function + * cannot be used to update BASE configuration itself, because BIG cannot be + * changed during it's lifetime. To modify BASE configuration destroy it using + * `ble_audio_broadcast_destroy` and recreate with `ble_audio_broadcast_create` + * + * @param[in] svc_data Pointer to additional service data for + * broadcast advertisement + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_update(const uint8_t *svc_data); + +/** BIG Subgroup parameters */ +struct ble_broadcast_subgroup_params { + /** Subgroup level Codec information */ + struct ble_audio_codec_id *codec_info; + + /** Subgroup level Codec Specific Configuration */ + uint8_t *codec_spec_config; + + /** Subgroup level Codec Specific Configuration length */ + uint8_t codec_spec_config_len; + + /** Subgroup Metadata */ + uint8_t *metadata; + + /** Subgroup Metadata length*/ + uint8_t metadata_len; +}; + +/** + * @brief Build BIG subgroup structure + * + * This is a helper function can be used to fill out `ble_broadcast_subgroup` + * structure. Created subgroup extends subgroup list in provided BIG. + * This function increases `num_subgroups` in BIG structure. + * + * @param[in] big Pointer to a `ble_audio_big` structure, + * that will be extended by the new subgroup + * @param[in] sub Pointer to a `ble_broadcast_subgroup` + * structure, that will be filled out with + * supplied configuration + * @param[in] params Pointer to a `ble_broadcast_subgroup_params` + * structure, containing information about new + * subgroup + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_build_sub(const struct ble_audio_big *big, + const struct ble_audio_subgroup *sub, + const struct ble_broadcast_subgroup_params + *params); + +/** BIS parameters */ +struct ble_broadcast_bis_params { + /** BIS index */ + uint8_t idx; + + /** BIS level Codec Specific Configuration */ + uint8_t *codec_spec_config; + + /** BIS level Codec Specific Configuration length */ + uint8_t codec_spec_config_len; +}; + +/** + * @brief Build BIS structure + * + * This is a helper function can be used to fill out `ble_broadcast_bis` + * structure. Created BIS extends BIS list in provided subgroup. + * This function increases `bis_cnt` in subgroup structure. + * + * @param[in] sub Pointer to a `ble_broadcast_subgroup` structure, + * that will be extended by the new BIS + * @param[in] bis Pointer to a `ble_broadcast_bis` + * structure, that will be filled out with + * supplied configuration + * @param[in] params Pointer to a `ble_broadcast_bis_params` + * structure, containing information about new + * BIS + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_build_bis(struct ble_audio_subgroup *sub, + struct ble_audio_bis *bis, + struct ble_broadcast_bis_params params); +#endif diff --git a/nimble/host/include/host/ble_audio_common.h b/nimble/host/include/host/ble_audio_common.h new file mode 100644 index 0000000000..c6d033a6ef --- /dev/null +++ b/nimble/host/include/host/ble_audio_common.h @@ -0,0 +1,180 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_AUDIO_COMMON_ +#define H_BLE_AUDIO_COMMON_ + +#include "stdint.h" +#include "os/queue.h" + +#define BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1852 + +#define BLE_BROADCAST_SAMPLING_RATE_8000_HZ BIT(0) +#define BLE_BROADCAST_SAMPLING_RATE_11025_HZ BIT(1) +#define BLE_BROADCAST_SAMPLING_RATE_16000_HZ BIT(2) +#define BLE_BROADCAST_SAMPLING_RATE_22050_HZ BIT(3) +#define BLE_BROADCAST_SAMPLING_RATE_24000_HZ BIT(4) +#define BLE_BROADCAST_SAMPLING_RATE_32000_HZ BIT(5) +#define BLE_BROADCAST_SAMPLING_RATE_44100_HZ BIT(6) +#define BLE_BROADCAST_SAMPLING_RATE_48000_HZ BIT(7) +#define BLE_BROADCAST_SAMPLING_RATE_88200_HZ BIT(8) +#define BLE_BROADCAST_SAMPLING_RATE_96000_HZ BIT(9) +#define BLE_BROADCAST_SAMPLING_RATE_176400_HZ BIT(10) +#define BLE_BROADCAST_SAMPLING_RATE_192000_HZ BIT(11) +#define BLE_BROADCAST_SAMPLING_RATE_384000_HZ BIT(12) + +#define BLE_BROADCAST_SUPPORTED_FRAME_DURATION_7_5_MS BIT(0) +#define BLE_BROADCAST_SUPPORTED_FRAME_DURATION_10_MS BIT(1) + +#define BLE_BROADCAST_AUDIO_LOCATION_FRONT_LEFT BIT(0) +#define BLE_BROADCAST_AUDIO_LOCATION_FRONT_RIGHT BIT(1) +#define BLE_BROADCAST_AUDIO_LOCATION_FRONT_CENTER BIT(2) +#define BLE_BROADCAST_AUDIO_LOCATION_LOW_FREQ_EFFECTS_1 BIT(3) +#define BLE_BROADCAST_AUDIO_LOCATION_BACK_LEFT BIT(4) +#define BLE_BROADCAST_AUDIO_LOCATION_FRONT_LEFT_CENTER BIT(5) +#define BLE_BROADCAST_AUDIO_LOCATION_FRONT_RIGHT_CENTER BIT(6) +#define BLE_BROADCAST_AUDIO_LOCATION_BACK_CENTER BIT(7) +#define BLE_BROADCAST_AUDIO_LOCATION_LOW_FREQ_EFFECTS_2 BIT(8) +#define BLE_BROADCAST_AUDIO_LOCATION_SIDE_LEFT BIT(9) +#define BLE_BROADCAST_AUDIO_LOCATION_SIDE_RIGHT BIT(10) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_FRONT_LEFT BIT(11) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_FRONT_RIGHT BIT(12) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_FRONT_CENTER BIT(13) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_CENTER BIT(14) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_BACK_LEFT BIT(15) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_BACK_RIGHT BIT(16) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_SIDE_LEFT BIT(17) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_SIDE_RIGHT BIT(18) +#define BLE_BROADCAST_AUDIO_LOCATION_TOP_BACK_CENTER BIT(19) +#define BLE_BROADCAST_AUDIO_LOCATION_BOTTOM_FRONT_CENTER BIT(20) +#define BLE_BROADCAST_AUDIO_LOCATION_BOTTOM_FRONT_LEFT BIT(21) +#define BLE_BROADCAST_AUDIO_LOCATION_BOTTOM_FRONT_RIGHT BIT(22) +#define BLE_BROADCAST_AUDIO_LOCATION_LEFT_SURROUND BIT(23) +#define BLE_BROADCAST_AUDIO_LOCATION_RIGHT_SURROUND BIT(24) + +struct ble_audio_codec_id { + /** Coding Fromat */ + uint8_t format; + + /** Company ID */ + uint16_t company_id; + + /** Vendor Specific Codec ID */ + uint16_t vendor_specific; +}; + +struct ble_audio_bis { + /** Pointer to next BIS in subgroup */ + STAILQ_ENTRY(ble_audio_bis) next; + + /** BIS index */ + uint8_t idx; + + /** BIS level Codec Specific Configuration */ + uint8_t codec_spec_config_len; + + /** BIS level Codec Specific Configuration length */ + uint8_t *codec_spec_config; +}; + +struct ble_audio_subgroup { + /** Pointer to next subgroup in BIG */ + STAILQ_ENTRY(ble_audio_subgroup) next; + + /** Number of BISes in subgroup */ + uint8_t bis_cnt; + + /** Codec ID */ + struct ble_audio_codec_id codec_id; + + /** Subgroup level Codec Specific Configuration */ + uint8_t *codec_spec_config; + + /** Subgroup level Codec Specific Configuration length */ + uint8_t codec_spec_config_len; + + /** Subgroup Metadata */ + uint8_t *metadata; + + /** Subgroup Metadata length*/ + uint8_t metadata_len; + + /** Link list of BISes */ + STAILQ_HEAD(, ble_audio_bis) bises; +}; + +struct ble_audio_big { + /** Broadcast ID */ + uint32_t broadcast_id; + + /** Presentation Delay */ + uint8_t presentation_delay[3]; + + /** Number of subgroups in BIG */ + uint8_t num_subgroups; + + /** Link list of subgroups */ + STAILQ_HEAD(, ble_audio_subgroup) subs; +}; + +struct ble_audio_codec_config_params { + /** Mandatory field, codec sampling frequency. */ + uint8_t sampling_freq; + + /** Mandatory field, codec frame duration. */ + uint8_t frame_duration; + + /** + * Optional field, bitfield with mapped Audio Locations. + * Set to 0 to omit in Codec Specific Configuration LTV construction. + */ + uint32_t audio_channel_alloc; + + /** Mandatory field, codec frame duration. */ + uint16_t octets_per_codec_frame; + + /** + * Optional field, codec frame duration. + * Set to 0 to omit in Codec Specific Configuration LTV construction. + */ + uint8_t codec_frame_blocks_per_sdu; +}; + +/** + * @brief Build Codec Specific Configuration LTV structure + * + * This function packs Codec Specific Configuration settings into LTV format. + * + * @param params Pointer to a `ble_audio_codec_config_params` + * struct that contains Codec Specific + * Configuration. + * @param codec_config_out Pointer to a memory that will be filled with + * Codec Specific Configuration LTV structure. + * Memory size must be sufficient to fit + * expected LTV structure size. + * @param codec_config_out_len Total length of constructed Codec Specific + * Configuration. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_build_codec_config(struct ble_audio_codec_config_params *params, + uint8_t *codec_config_out, + uint8_t codec_config_out_len); +#endif /* H_BLE_AUDIO_COMMON_ */ diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h new file mode 100644 index 0000000000..ff9c702ce6 --- /dev/null +++ b/nimble/host/include/host/ble_iso.h @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_ISO_ +#define H_BLE_ISO_ +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_ISO) + +#include + +struct ble_iso_big_params { + uint32_t sdu_interval; + uint16_t max_sdu; + uint16_t max_transport_latency; + uint8_t rtn; + uint8_t phy; + uint8_t packing; + uint8_t framing; + uint8_t encryption; + const char *broadcast_code; +}; + +struct ble_iso_create_big_params { + uint16_t adv_handle; + uint8_t bis_cnt; +}; + +int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, + const struct ble_iso_big_params *big_params, + uint8_t *big_id); + +int ble_iso_terminate_big(uint8_t big_id); +#endif +#endif diff --git a/nimble/host/services/leaudio/auracast/include/leaudio/auracast/auracast.h b/nimble/host/services/leaudio/auracast/include/leaudio/auracast/auracast.h new file mode 100644 index 0000000000..010010e14e --- /dev/null +++ b/nimble/host/services/leaudio/auracast/include/leaudio/auracast/auracast.h @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "host/ble_gap.h" +#include "host/ble_audio_common.h" +#include "host/ble_audio_broadcast.h" + +struct ble_svc_auracast_create_params { + struct ble_broadcast_big *big; + struct ble_iso_big_params *big_params; + const uint8_t *name; + uint8_t name_len; + uint8_t adv_instance; +}; + +/** + * @brief Create Auracast Endpoint and configure advertising instance + * + * This function configures advertising instance for extended and periodic + * advertisements to be ready for Auracast broadcast. + * + * @param[in] params Pointer to a `ble_svc_auracast_create_params` + * structure that defines BIG and broadcast name. + * @param[out] config_out Pointer to a `ble_broadcast_base_config` + * structure to return configuration of created + * Auracast advertisement. + * @param[in] destroy_cb Optional callback to be called when Auracast + * advertisement is destroyed. + * @param[in] args Optional arguments to be passed to `destroy_cb` + * @param[in] gap_cb GAP event callback to be associated with + * Auracast advertisement. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_create(const struct + ble_svc_auracast_create_params *params, + const struct ble_broadcast_base_config *config_out, + ble_audio_broadcast_destroy_fn *destroy_cb, + void *args, + ble_gap_event_fn *gap_cb); +/** + * @brief Terminate all active advertisements and free resources associated + * with given Auracast broadcast. + * + * This function stops Auracast advertisement by disabling extended and + * periodic advertising and terminates them. After return advertising instance + * is free and must be configured again for future advertisements. + * + * @param[in] base_config Pointer to a `ble_broadcast_base_config` + * struct that broadcast shall be terminated for. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_terminate(const struct ble_broadcast_base_config *base_config); + +/** + * @brief Start advertisements for given Auracast broadcast + * + * This function starts Auracast broadcast on by enabling extended and periodic + * advertising. + * + * @param[in] base_config Pointer to a `ble_broadcast_base_config` + * struct that shall be used for broadcast. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_start(const struct ble_broadcast_base_config *base_config); + +/** + * @brief Stop advertisements for given Auracast broadcast + * + * This function stops Auracast broadcast by disabling extended and periodic + * advertising. Advertising instance is still configured and ready for resume. + * + * @param[in] base_config Pointer to a `ble_broadcast_base_config` + * struct that broadcast shall be stopped for. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_stop(const struct ble_broadcast_base_config *base_config);