diff --git a/.github/test_build_apps_syscfg.yml b/.github/test_build_apps_syscfg.yml index aabcc2979d..9887918b43 100644 --- a/.github/test_build_apps_syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -54,6 +54,7 @@ syscfg.vals: BLE_EATT_CHAN_NUM: 2 BLE_PHY_2M: 1 BLE_PHY_CODED: 1 + BLE_AUDIO_MAX_CODEC_RECORDS: 2 # controller BLE_LL_CFG_FEAT_LL_PRIVACY: 1 diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index c1ce1dc9c8..1de78a0478 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -208,19 +208,184 @@ */ /** LE Audio Codec Config Type: Sampling Frequency. */ -#define BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE 0x01 +#define BLE_AUDIO_CODEC_CONF_SAMPLING_FREQ_TYPE 0x01 /** LE Audio Codec Config Type: Frame Duration. */ -#define BLE_AUDIO_CODEC_FRAME_DURATION_TYPE 0x02 +#define BLE_AUDIO_CODEC_CONF_FRAME_DURATION_TYPE 0x02 /** LE Audio Codec Config Type: Channel Allocation. */ -#define BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03 +#define BLE_AUDIO_CODEC_CONF_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03 /** LE Audio Codec Config Type: Octets Per Codec Frame. */ -#define BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE 0x04 +#define BLE_AUDIO_CODEC_CONF_OCTETS_PER_CODEC_FRAME_TYPE 0x04 /** LE Audio Codec Config Type: Frame Blocks Per SDU. */ -#define BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE 0x05 +#define BLE_AUDIO_CODEC_CONF_FRAME_BLOCKS_PER_SDU_TYPE 0x05 + +/** @} */ + +/** + * @defgroup ble_audio_codec_config Bluetooth Low Energy Audio Codec Specific Capabilities + * @{ + */ + + +/** LE Audio Codec Specific Capability: Supported Sampling Frequencies. */ +#define BLE_AUDIO_CODEC_CAPS_SAMPLING_FREQ_TYPE 0x01 + +/** LE Audio Codec Specific Capability: Supported Frame Durations. */ +#define BLE_AUDIO_CODEC_CAPS_FRAME_DURATION_TYPE 0x02 + +/** LE Audio Codec Specific Capability: Supported Audio Channel Counts. */ +#define BLE_AUDIO_CODEC_CAPS_SUP_AUDIO_CHANNEL_COUNTS_TYPE 0x03 + +/** LE Audio Codec Specific Capability: Supported Octets Per Codec Frame. */ +#define BLE_AUDIO_CODEC_CAPS_OCTETS_PER_CODEC_FRAME_TYPE 0x04 + +/** LE Audio Codec Specific Capability: Supported Codec Frames Per SDU. */ +#define BLE_AUDIO_CODEC_CAPS_FRAMES_PER_SDU_TYPE 0x05 + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Context Types + * @{ + */ + +/** LE Audio Codec Context Type: Prohibited. */ +#define BLE_AUDIO_CONTEXT_TYPE_PROHIBITED 0x0000 + +/** LE Audio Codec Context Type: Unspecified. */ +#define BLE_AUDIO_CONTEXT_TYPE_UNSPECIFIED 0x0001 + +/** LE Audio Codec Context Type: Conversational. */ +#define BLE_AUDIO_CONTEXT_TYPE_CONVERSATIONAL 0x0002 + +/** LE Audio Codec Context Type: Media. */ +#define BLE_AUDIO_CONTEXT_TYPE_MEDIA 0x0004 + +/** LE Audio Codec Context Type: Game. */ +#define BLE_AUDIO_CONTEXT_TYPE_GAME 0x0008 + +/** LE Audio Codec Context Type: Instructional. */ +#define BLE_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL 0x0010 + +/** LE Audio Codec Context Type: Voice Assistants. */ +#define BLE_AUDIO_CONTEXT_TYPE_VOICE_ASSISTANTS 0x0020 + +/** LE Audio Codec Context Type: Live. */ +#define BLE_AUDIO_CONTEXT_TYPE_LIVE 0x0040 + +/** LE Audio Codec Context Type: Sound Effects. */ +#define BLE_AUDIO_CONTEXT_TYPE_SOUND_EFFECTS 0x0080 + +/** LE Audio Codec Context Type: Notifications. */ +#define BLE_AUDIO_CONTEXT_TYPE_NOTIFICATIONS 0x0100 + +/** LE Audio Codec Context Type: Ringtone. */ +#define BLE_AUDIO_CONTEXT_TYPE_RINGTONE 0x0200 + +/** LE Audio Codec Context Type: Alerts. */ +#define BLE_AUDIO_CONTEXT_TYPE_ALERTS 0x0400 + +/** LE Audio Codec Context Type: EmergencyAlarm. */ +#define BLE_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM 0x0800 + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Frame Durations + * @{ + */ + +/** LE Audio Codec Supported Frame Duration: 7.5 ms frame duration. */ +#define BLE_AUDIO_CODEC_SUPPORTED_FRAME_DURATION_7_5_MS 0x0001 + +/** LE Audio Codec Supported Frame Duration: 10 ms frame duration. */ +#define BLE_AUDIO_CODEC_SUPPORTED_FRAME_DURATION_10_MS 0x0002 + +/** LE Audio Codec Supported Frame Duration: 7.5 ms preferred. */ +#define BLE_AUDIO_CODEC_PREFERED_FRAME_DURATION_7_5_MS 0x0010 + +/** LE Audio Codec Supported Frame Duration: 10 ms preferred. */ +#define BLE_AUDIO_CODEC_PREFERED_FRAME_DURATION_10_MS 0x0020 + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Sampling Frequencies + * @{ + */ + +/** LE Audio Codec Supported Sampling Frequency: 8000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_8000_HZ (1ULL << 0) + +/** LE Audio Codec Supported Sampling Frequency: 11025 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_11025_HZ (1ULL << 1) + +/** LE Audio Codec Supported Sampling Frequency: 16000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_16000_HZ (1ULL << 2) + +/** LE Audio Codec Supported Sampling Frequency: 22050 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_22050_HZ (1ULL << 3) + +/** LE Audio Codec Supported Sampling Frequency: 24000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_24000_HZ (1ULL << 4) + +/** LE Audio Codec Supported Sampling Frequency: 32000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_32000_HZ (1ULL << 5) + +/** LE Audio Codec Supported Sampling Frequency: 44100 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_44100_HZ (1ULL << 6) + +/** LE Audio Codec Supported Sampling Frequency: 48000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_48000_HZ (1ULL << 7) + +/** LE Audio Codec Supported Sampling Frequency: 88200 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_88200_HZ (1ULL << 8) + +/** LE Audio Codec Supported Sampling Frequency: 96000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_96000_HZ (1ULL << 9) + +/** LE Audio Codec Supported Sampling Frequency: 176400 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_176400_HZ (1ULL << 10) + +/** LE Audio Codec Supported Sampling Frequency: 192000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_192000_HZ (1ULL << 11) + +/** LE Audio Codec Supported Sampling Frequency: 384000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_384000_HZ (1ULL << 12) + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Channel Counts + * @{ + */ + +/** LE Audio Codec Supported Channel Count: 1. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_1 0x0001 + +/** LE Audio Codec Supported Channel Count: 2. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_2 0x0002 + +/** LE Audio Codec Supported Channel Count: 3. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_3 0x0004 + +/** LE Audio Codec Supported Channel Count: 4. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_4 0x0008 + +/** LE Audio Codec Supported Channel Count: 5. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_5 0x0010 + +/** LE Audio Codec Supported Channel Count: 6. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_6 0x0020 + +/** LE Audio Codec Supported Channel Count: 7. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_7 0x0040 + +/** LE Audio Codec Supported Channel Count: 8. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_8 0x0080 /** @} */ @@ -244,16 +409,55 @@ _octets_per_codec_frame, \ _codec_frame_blocks_per_sdu) \ { \ - 2, BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE, _sampling_freq, \ - 2, BLE_AUDIO_CODEC_FRAME_DURATION_TYPE, _frame_duration, \ - OPTIONAL_FIELD(5, BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE, \ + 2, BLE_AUDIO_CODEC_CONF_SAMPLING_FREQ_TYPE, _sampling_freq, \ + 2, BLE_AUDIO_CODEC_CONF_FRAME_DURATION_TYPE, _frame_duration, \ + OPTIONAL_FIELD(5, BLE_AUDIO_CODEC_CONF_AUDIO_CHANNEL_ALLOCATION_TYPE, \ _audio_channel_alloc) \ - 3, BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE, \ + 3, BLE_AUDIO_CODEC_CONF_OCTETS_PER_CODEC_FRAME_TYPE, \ (_octets_per_codec_frame), ((_octets_per_codec_frame) >> 8), \ - OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE, \ + OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_CONF_FRAME_BLOCKS_PER_SDU_TYPE, \ _codec_frame_blocks_per_sdu) \ } +/** + * @brief Helper macro used to build LTV array of Codec_Specific_Capabilities. + * + * @param _sampling_freq Supported_Sampling_Frequencies - + * two octet value + * @param _frame_duration Supported_Frame_Durations - single + * octet value + * @param _audio_channel_counts Supported_Audio_Channel_Counts - + * single octet value + * @param _min_octets_per_codec_frame minimum value of + * Supported_Octets_Per_Codec_Frame - + * two octet value + * @param _max_octets_per_codec_frame maximum value of + * Supported_Octets_Per_Codec_Frame - + * two octet value + * @param _codec_frames_per_sdu Supported_Max_Codec_Frames_Per_SDU - + * single octet value + * + * @return Pointer to a `ble_uuid16_t` structure. + */ +#define BLE_AUDIO_BUILD_CODEC_CAPS(_sampling_freq, \ + _frame_duration, \ + _audio_channel_counts, \ + _min_octets_per_codec_frame, \ + _max_octets_per_codec_frame, \ + _codec_frames_per_sdu) \ + { \ + 3, BLE_AUDIO_CODEC_CAPS_SAMPLING_FREQ_TYPE, \ + (_sampling_freq), ((_sampling_freq) >> 8), \ + 2, BLE_AUDIO_CODEC_CAPS_FRAME_DURATION_TYPE, _frame_duration, \ + OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_CAPS_SUP_AUDIO_CHANNEL_COUNTS_TYPE, \ + _audio_channel_counts) \ + 5, BLE_AUDIO_CODEC_CAPS_OCTETS_PER_CODEC_FRAME_TYPE, \ + (_min_octets_per_codec_frame), ((_min_octets_per_codec_frame) >> 8), \ + (_max_octets_per_codec_frame), ((_max_octets_per_codec_frame) >> 8), \ + OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_CAPS_FRAMES_PER_SDU_TYPE, \ + _codec_frames_per_sdu) \ + } + /** Codec Information */ struct ble_audio_codec_id { /** Coding Format */ @@ -306,6 +510,9 @@ struct ble_audio_broadcast_name { /** BLE Audio event: Broadcast Announcement */ #define BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT 0 +/** BLE Audio event: Codec Changed */ +#define BLE_AUDIO_EVENT_CODEC_CHANGED 1 + /** @} */ /** @brief Broadcast Announcement */ @@ -329,6 +536,18 @@ struct ble_audio_event_broadcast_announcement { struct ble_audio_broadcast_name *name; }; +/** @brief Codec Registered */ +struct ble_audio_event_codec_changed { + /** Change type */ + enum { + CODEC_REGISTERED, + CODEC_UNREGISTERED, + } change; + + /** Codec Record */ + const struct ble_audio_codec_record *record; +}; + /** * Represents a BLE Audio related event. When such an event occurs, the host * notifies the application by passing an instance of this structure to an @@ -352,6 +571,13 @@ struct ble_audio_event { * Represents a received Broadcast Announcement. */ struct ble_audio_event_broadcast_announcement broadcast_announcement; + + /** + * @ref BLE_AUDIO_EVENT_CODEC_REGISTERED + * + * Represents a codec registration. + */ + struct ble_audio_event_codec_changed codec_changed; }; }; diff --git a/nimble/host/audio/include/audio/ble_audio_codec.h b/nimble/host/audio/include/audio/ble_audio_codec.h new file mode 100644 index 0000000000..dcb1df9d34 --- /dev/null +++ b/nimble/host/audio/include/audio/ble_audio_codec.h @@ -0,0 +1,146 @@ +/* + * 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_CODEC_ +#define H_BLE_AUDIO_CODEC_ + +/** + * @file ble_audio_codec.h + * + * @brief Bluetooth LE Audio Codec + * + * This header file provides the public API for managing LE Audio Codecs + * + * @defgroup ble_audio_codec Bluetooth LE Audio Codec + * @ingroup bt_host + * @{ + * + * This API allows to create and manage list of LE Audio codecs with their capabilities and + * metadata. This list can be used by higher level services, like PACS. Memory management of + * codec entries is left to application and neither static nor dynamic allocation is enforced. + * + */ + +#include "stdint.h" +#include "ble_audio.h" + +/** Bit describing direction of codec configuration - source */ +#define BLE_AUDIO_CODEC_DIR_SOURCE_BIT (1 << 0) +/** Bit describing direction of codec configuration - sink */ +#define BLE_AUDIO_CODEC_DIR_SINK_BIT (1 << 1) + +/** Codec list entry */ +struct ble_audio_codec_record { + /* Pointer to next codec list entry */ + STAILQ_ENTRY(ble_audio_codec_record) next; + + /* Codec ID */ + struct ble_audio_codec_id codec_id; + + /* Length of Codec Specific Capabilities */ + uint8_t codec_spec_caps_len; + + /* Codec Specific Capabilities data */ + const uint8_t *codec_spec_caps; + + /* Metadata length */ + uint8_t metadata_len; + + /* Metadata */ + const uint8_t *metadata; + + /* Bitfield describing direction that codec is acting on. It is a logical OR of: + * - BLE_AUDIO_CODEC_DIR_SOURCE_BIT + * - BLE_AUDIO_CODEC_DIR_SINK_BIT + */ + uint8_t direction; +}; + +/** Type definition codec iteration callback function. */ +typedef int ble_audio_codec_foreach_fn(const struct ble_audio_codec_record *record, void *arg); + +struct ble_audio_codec_register_params { + /* Codec ID structure */ + struct ble_audio_codec_id codec_id; + + /* Codec Specific Capabilities length */ + uint8_t codec_spec_caps_len; + + /* Codec Specific Capabilities data */ + uint8_t *codec_spec_caps; + + /* Metadata length */ + uint8_t metadata_len; + + /* Metadata */ + uint8_t *metadata; + + /* Bitfield describing direction that codec is acting on. It is a logical OR of: + * - BLE_AUDIO_CODEC_DIR_SOURCE_BIT + * - BLE_AUDIO_CODEC_DIR_SINK_BIT + */ + uint8_t direction; +}; + +/** + * @brief Register codec entry + * + * @param[in] params Pointer to a `ble_audio_codec_register_params` + * structure that defines Codec Specific Capabilities + * @param[out] out_record Pointer to registered codec entry. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_codec_register(const struct ble_audio_codec_register_params + *params, + struct ble_audio_codec_record *out_record); +/** + * @brief Remove codec entry from register + * + * @param[in] codec_record Pointer to registered codec entry. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_codec_unregister(struct ble_audio_codec_record *codec_record); + +/** + * @brief Iterate through all registered codecs and call function on every + * one of them. + * + * @param[in] direction Codec entry direction. It is any + * combination of following bits: + * - BLE_AUDIO_CODEC_DIR_SOURCE_BIT + * - BLE_AUDIO_CODEC_DIR_SINK_BIT + * This filters entries so the callback is called + * only on these have matching direction bit set. + * @param[in] cb Callback to be called on codec entries. + * @param[in] arg Optional callback argument. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_codec_foreach(uint8_t direction, ble_audio_codec_foreach_fn *cb, void *arg); + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_CODEC_ */ diff --git a/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h new file mode 100644 index 0000000000..fdbcbeef9f --- /dev/null +++ b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h @@ -0,0 +1,95 @@ +/* + * 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_SVC_PACS_ +#define H_BLE_AUDIO_SVC_PACS_ + +/** + * @file ble_audio_svc_pacs.h + * + * @brief Bluetooth LE Audio PAC Service + * + * This header file provides the public API for interacting with the PACS package. + * + * @defgroup ble_audio_svc_pacs Bluetooth LE Audio PACS package + * @ingroup bt_host + * @{ + * + * This package is used to setup PACS for codecs registered with @ref ble_audio_codec. + * To register a codec create it's definition as `ble_audio_codec_record` structure and register it + * using `ble_audio_codec_register()`. Up to BLE_AUDIO_MAX_CODEC_RECORDS entries may be registered. + * Registering and unregistering codecs, as well as setting PACS parameters will trigger sending + * notifications, if their support is enabled (see pacs/syscfg.yml). + * + */ + +#define BLE_SVC_AUDIO_PACS_UUID16 0x1850 +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC 0x2BC9 +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS 0x2BCA +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC 0x2BCB +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS 0x2BCC +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS 0x2BCD +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS 0x2BCE + + +struct ble_svc_audio_pacs_set_param { + /* Supported Audio Locations */ + uint32_t audio_locations; + + /* Supported Contexts */ + uint16_t supported_contexts; +}; + +/** + * @brief Set PACS params. + * + * Set device capabilities reported in Published Audio Capabilities Service. + * + * @param[in] flags Flags that define if capabilities being set are for + * Sink or Source. Valid values are either + * `BLE_AUDIO_CODEC_FLAG_SOURCE` or `BLE_AUDIO_CODEC_FLAG_SINK` + * @param[in] param Pointer to a `ble_svc_audio_pacs_set_param` + * structure that defines capabilities supported by + * device. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param); + +/** + * @brief Set available context types. + * + * @param[in] conn_handle Connection handle identifying connection for which contexts + * being set + * @param[in] sink_contexts Available Sink Contexts + * @param[in] source_contexts Available Source Contexts + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_audio_pacs_avail_contexts_set(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts); + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_SVC_PACS_ */ diff --git a/nimble/host/audio/services/pacs/lc3/include/services/pacs/ble_audio_svc_pacs_lc3.h b/nimble/host/audio/services/pacs/lc3/include/services/pacs/ble_audio_svc_pacs_lc3.h new file mode 100644 index 0000000000..ddd6f546c2 --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/include/services/pacs/ble_audio_svc_pacs_lc3.h @@ -0,0 +1,63 @@ +/* + * 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_SVC_PACS_LC3_ +#define H_BLE_AUDIO_SVC_PACS_LC3_ + + +/** + * @file ble_audio_svc_pacs_lc3.h + * + * @brief Bluetooth PAC Service for LC3 Codec + * + * This header file provides the public API for interacting with the PACS LC3 package, that + * registers PAC entry for LC3 codec with configurations contained in system configuration file + * + * @defgroup ble_audio_svc_pacs_lc3 Bluetooth LE Audio PACS LC3 package + * @ingroup ble_audio_svc_pacs + * @{ + * + * This package is an example how to register codec entry that PACS can use to construct its entries + * for GATT database. This is high level package that can be used to construct basic PACS setup for + * LC3 codec. This package creates only single PAC entry per source and sink. If more PAC entries + * need to be created, with more advanced setup, @ref ble_audio_svc_pacs service shall be used in + * combination with @ref ble_audio_codec API. + * + */ + +/** + * @brief Set available context types. + * + * @param[in] conn_handle Connection handle identifying connection for which contexts + * being set + * @param[in] sink_contexts Available Sink Contexts + * @param[in] source_contexts Available Source Contexts + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_audio_pacs_lc3_set_avail_contexts(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts); + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_SVC_PACS_LC3_ */ diff --git a/nimble/host/audio/services/pacs/lc3/pkg.yml b/nimble/host/audio/services/pacs/lc3/pkg.yml new file mode 100644 index 0000000000..557ebebe39 --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/pkg.yml @@ -0,0 +1,35 @@ +# 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. + +pkg.name: nimble/host/audio/services/pacs/lc3 +pkg.description: LC3 codec entry for Published Audio Capabilities Service +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - pacs + - nimble + +pkg.deps: + - nimble/host/audio/services/pacs + - nimble/host + +pkg.init: +# ble_svc_audio_pacs_lc3_init: 'MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SYSINIT_STAGE)' + ble_svc_audio_pacs_lc3_init: + - $after:ble_svc_audio_pacs_init diff --git a/nimble/host/audio/services/pacs/lc3/src/ble_audio_svc_pacs_lc3.c b/nimble/host/audio/services/pacs/lc3/src/ble_audio_svc_pacs_lc3.c new file mode 100644 index 0000000000..61c703629c --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/src/ble_audio_svc_pacs_lc3.c @@ -0,0 +1,153 @@ +/* + * 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 "audio/ble_audio_codec.h" +#include "services/pacs/ble_audio_svc_pacs.h" +#include "syscfg/syscfg.h" +#include "host/ble_hs.h" + +/* Below is to unmangle comma separated Metadata octets from MYNEWT_VAL */ +#define _Args(...) __VA_ARGS__ +#define STRIP_PARENS(X) X +#define UNMANGLE_MYNEWT_VAL(X) STRIP_PARENS(_Args X) + +#define BLE_SVC_AUDIO_PACS_LC3_CODEC_ID 0x06 + +static uint8_t ble_svc_audio_pacs_lc3_src_codec_spec_caps[] = BLE_AUDIO_BUILD_CODEC_CAPS( + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_SAMPLING_FREQUENCIES), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_FRAME_DURATIONS), +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS), +#else + , +#endif + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MIN_OCTETS_PER_CODEC_FRAME), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME), +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU), +#endif +); + +static uint8_t ble_svc_audio_pacs_lc3_snk_codec_spec_caps[] = BLE_AUDIO_BUILD_CODEC_CAPS( + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SAMPLING_FREQUENCIES), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_FRAME_DURATIONS), + #ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_AUDIO_CHANNEL_COUNTS), + #else + , + #endif + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_MIN_OCTETS_PER_CODEC_FRAME), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME), + #ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_CODEC_FRAMES_PER_SDU), + #endif +); + +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA +static uint8_t ble_svc_audio_pacs_lc3_src_metadata[] = +{ UNMANGLE_MYNEWT_VAL(MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA)) }; +#endif + +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA +static uint8_t ble_svc_audio_pacs_lc3_snk_metadata[] = +{ UNMANGLE_MYNEWT_VAL(MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA)) }; +#endif + +static struct ble_audio_codec_register_params src_codec_params = { + .codec_id = { + .format = BLE_SVC_AUDIO_PACS_LC3_CODEC_ID, + .company_id = 0x00, + .vendor_specific = 0x00 + }, + .codec_spec_caps_len = sizeof(ble_svc_audio_pacs_lc3_src_codec_spec_caps), + .codec_spec_caps = ble_svc_audio_pacs_lc3_src_codec_spec_caps, +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA + .metadata_len = sizeof(ble_svc_audio_pacs_lc3_src_metadata), + .metadata = ble_svc_audio_pacs_lc3_src_metadata, +#else + .metadata_len = 0, +#endif + .direction = BLE_AUDIO_CODEC_DIR_SOURCE_BIT +}; + +static struct ble_audio_codec_register_params snk_codec_params = { + .codec_id = { + .format = BLE_SVC_AUDIO_PACS_LC3_CODEC_ID, + .company_id = 0x00, + .vendor_specific = 0x00 + }, + .codec_spec_caps_len = sizeof(ble_svc_audio_pacs_lc3_snk_codec_spec_caps), + .codec_spec_caps = ble_svc_audio_pacs_lc3_snk_codec_spec_caps, +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA + .metadata_len = sizeof(ble_svc_audio_pacs_lc3_snk_metadata), + .metadata = ble_svc_audio_pacs_lc3_snk_metadata, +#else + .metadata_len = 0, +#endif + + .direction = BLE_AUDIO_CODEC_DIR_SINK_BIT +}; + +static int +codec_register(void) +{ + int rc; + + rc = ble_audio_codec_register(&src_codec_params, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_audio_codec_register(&snk_codec_params, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} + +int +ble_svc_audio_pacs_lc3_set_avail_contexts(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts) +{ + return ble_svc_audio_pacs_avail_contexts_set(conn_handle, sink_contexts, + source_contexts); +} + +void +ble_svc_audio_pacs_lc3_init(void) +{ + struct ble_svc_audio_pacs_set_param src_params = { + .audio_locations = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_LOCATIONS), + .supported_contexts = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_SUP_CONTEXTS) + }; + struct ble_svc_audio_pacs_set_param snk_params = { + .audio_locations = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_AUDIO_LOCATIONS), + .supported_contexts = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_CONTEXTS) + }; + int rc; + + rc = codec_register(); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SOURCE_BIT, &src_params); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SINK_BIT, &snk_params); + SYSINIT_PANIC_ASSERT(rc == 0); + + (void)rc; +} diff --git a/nimble/host/audio/services/pacs/lc3/syscfg.yml b/nimble/host/audio/services/pacs/lc3/syscfg.yml new file mode 100644 index 0000000000..f2a2ff0685 --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/syscfg.yml @@ -0,0 +1,131 @@ +# 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. + +syscfg.defs: + BLE_SVC_AUDIO_PACS_LC3_SRC_SAMPLING_FREQUENCIES: + description: > + Sampling frequencies supported by LC3 codec, as source. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.1. + Default value: 48000Hz + value: 0x80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_FRAME_DURATIONS: + description: > + Frame Durations supported by LC3 codec, as source. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.2. + Default value: 7.5ms and 10ms supported, 10ms preferred. + value: 0x23 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS: + description: > + Audio Channel Counts supported by LC3 codec, as source. This setting is optional. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.3. + value: + BLE_SVC_AUDIO_PACS_LC3_SRC_MIN_OCTETS_PER_CODEC_FRAME: + description: > + Minimum number of Octets Per Codec Frame supported by LC3 codec, as source. + This setting is mandatory. Default value: 80 + value: 80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME: + description: > + Maximum number of Octets Per Codec Frame supported by LC3 codec, as source. + This setting is mandatory. Default value: 120 + value: 120 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU: + description: > + Maximum number of Codec Frames Per SDU supported by LC3 codec, as source. + This setting is optional. + value: + BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA: + description: > + Optional Metadata to be attached to source codec capabilities. This value shall be in + form of bytes forming LTVs of Metadata. Example: '0x03, 0x01, 0x00, 0x08' + (lenght = 3, type = 0x01 (Preferred_Audio_Contexts), 0x00, 0x04 (Media)) + value: + BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_LOCATIONS: + description: > + Audio Locations supported by source codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.1. Default: Front Left and Front Right + value: 0x00000003 + BLE_SVC_AUDIO_PACS_LC3_SRC_SUP_CONTEXTS: + description: > + Audio Locations supported by source codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.3. Default: Media + value: 0x0004 + + BLE_SVC_AUDIO_PACS_LC3_SNK_SAMPLING_FREQUENCIES: + description: > + Sampling frequencies supported by LC3 codec, as sink. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.1. + Default value: 48000Hz + value: 0x80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_FRAME_DURATIONS: + description: > + Frame Durations supported by LC3 codec, as sink. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.2. + Default value: 7.5ms and 10ms supported, 10ms preferred. + value: 0x23 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_AUDIO_CHANNEL_COUNTS: + description: > + Audio Channel Counts supported by LC3 codec, as sink. This setting is optional. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.3. + value: + BLE_SVC_AUDIO_PACS_LC3_SNK_MIN_OCTETS_PER_CODEC_FRAME: + description: > + Minimum number of Octets Per Codec Frame supported by LC3 codec, as source. + This setting is mandatory. Default value: 80 + value: 80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_OCTETS_PER_CODEC_FRAME: + description: > + Maximum number of Octets Per Codec Frame supported by LC3 codec, as sink. + This setting is mandatory. Default value: 120 + value: 120 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_CODEC_FRAMES_PER_SDU: + description: > + Maximum number of Codec Frames Per SDU supported by LC3 codec, as sink. + This setting is optional. + value: + BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA: + description: > + Optional Metadata to be attached to sink codec capabilities. This value shall be in + form of bytes forming LTVs of Metadata. Example: '0x03, 0x01, 0x00, 0x08' + (lenght = 3, type = 0x01 (Preferred_Audio_Contexts), 0x00, 0x04 (Media)) + value: + BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_AUDIO_LOCATIONS: + description: > + Audio Locations supported by sink codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.1. Default: Front Left and Front Right + value: 0x00000003 + BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_CONTEXTS: + description: > + Audio Locations supported by sink codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.3. Default: Media + value: 0x0004 diff --git a/nimble/host/audio/services/pacs/pkg.yml b/nimble/host/audio/services/pacs/pkg.yml new file mode 100644 index 0000000000..799378d7e7 --- /dev/null +++ b/nimble/host/audio/services/pacs/pkg.yml @@ -0,0 +1,33 @@ +# 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. + +pkg.name: nimble/host/audio/services/pacs +pkg.description: Published Audio Capabilities Service +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - pacs + - nimble + +pkg.deps: + - nimble/host + - nimble/host/services/gatt + +pkg.init: + ble_svc_audio_pacs_init: 'MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SYSINIT_STAGE)' diff --git a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c new file mode 100644 index 0000000000..669ac30bde --- /dev/null +++ b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c @@ -0,0 +1,472 @@ +/* + * 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 "audio/ble_audio.h" +#include "host/ble_hs.h" +#include "host/ble_gatt.h" +#include "audio/ble_audio_codec.h" +#include "services/pacs/ble_audio_svc_pacs.h" + +static uint32_t ble_svc_audio_pacs_sink_audio_locations; +static uint32_t ble_svc_audio_pacs_source_audio_locations; +static struct available_ctx { + uint16_t conn_handle; + uint16_t ble_svc_audio_pacs_avail_sink_contexts; + uint16_t ble_svc_audio_pacs_avail_source_contexts; +} ble_svc_audio_pacs_avail_contexts[MYNEWT_VAL(BLE_MAX_CONNECTIONS)] = { + [0 ... MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1] = { + .conn_handle = BLE_HS_CONN_HANDLE_NONE, + .ble_svc_audio_pacs_avail_sink_contexts = 0, + .ble_svc_audio_pacs_avail_source_contexts = 0 + } +}; +static uint16_t ble_svc_audio_pacs_sup_sink_contexts; +static uint16_t ble_svc_audio_pacs_sup_source_contexts; + +static struct ble_gap_event_listener ble_pacs_listener; +static struct ble_audio_event_listener ble_audio_listener; + +struct pac_read_cb_arg { + struct os_mbuf *om; + uint8_t pac_count; +}; + +static int +ble_svc_audio_pacs_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static const struct ble_gatt_svc_def ble_svc_audio_pacs_defs[] = { + { /*** Service: Published Audio Capabilities Service (PACS) */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_PACS_UUID16), + .characteristics = (struct ble_gatt_chr_def[]) { +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_PAC) + { + .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_PAC_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS) + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_PAC) + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_PAC_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS) + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SUP_AUDIO_CTX_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, { + 0, /* No more characteristics in this service */ + } + } + }, + { + 0, /* No more services. */ + }, +}; + +static int +codec_record_to_pacs_entry(const struct ble_audio_codec_record *record, void *arg) +{ + struct pac_read_cb_arg *cb_arg = (struct pac_read_cb_arg *)arg; + uint8_t *buf; + int rc; + + rc = os_mbuf_append(cb_arg->om, &record->codec_id.format, sizeof(uint8_t)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + buf = os_mbuf_extend(cb_arg->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + put_le16(buf + 0, record->codec_id.company_id); + put_le16(buf + 2, record->codec_id.vendor_specific); + + rc = os_mbuf_append(cb_arg->om, &record->codec_spec_caps_len, sizeof(uint8_t)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + rc = os_mbuf_append(cb_arg->om, record->codec_spec_caps, record->codec_spec_caps_len); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + rc = os_mbuf_append(cb_arg->om, &record->metadata_len, sizeof(uint8_t)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + rc = os_mbuf_append(cb_arg->om, record->metadata, record->metadata_len); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + cb_arg->pac_count++; + + return 0; +} + +static int +ble_svc_audio_pacs_sink_pac_read_access(struct ble_gatt_access_ctxt *ctxt) +{ + struct pac_read_cb_arg cb_arg = { + .om = ctxt->om, + .pac_count = 0 + }; + int rc; + uint8_t *pac_count; + + pac_count = os_mbuf_extend(ctxt->om, sizeof(uint8_t)); + rc = ble_audio_codec_foreach(BLE_AUDIO_CODEC_DIR_SINK_BIT, + codec_record_to_pacs_entry, (void *)&cb_arg); + + *pac_count = cb_arg.pac_count; + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +} + +static int +ble_svc_audio_pacs_source_pac_read_access(struct ble_gatt_access_ctxt *ctxt) +{ + struct pac_read_cb_arg cb_arg = { + .om = ctxt->om, + .pac_count = 0 + }; + int rc; + uint8_t *pac_count; + + pac_count = os_mbuf_extend(ctxt->om, sizeof(uint8_t)); + rc = ble_audio_codec_foreach(BLE_AUDIO_CODEC_DIR_SOURCE_BIT, + codec_record_to_pacs_entry, (void *)&cb_arg); + + *pac_count = cb_arg.pac_count; + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +} + +static int +ble_svc_audio_pacs_sink_audio_loc_read_access(struct ble_gatt_access_ctxt * + ctxt) +{ + uint8_t *buf; + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le32(buf + 0, ble_svc_audio_pacs_sink_audio_locations); + + return 0; +} + +static int +ble_svc_audio_pacs_source_audio_loc_read_access(struct ble_gatt_access_ctxt * + ctxt) +{ + uint8_t *buf; + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le32(buf + 0, ble_svc_audio_pacs_source_audio_locations); + + return 0; +} + +static struct available_ctx * +ble_svc_audio_pacs_find_avail_ctx(uint16_t conn_handle) +{ + int i; + + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { + if (ble_svc_audio_pacs_avail_contexts[i].conn_handle == conn_handle) { + return &ble_svc_audio_pacs_avail_contexts[i]; + } + } + return NULL; +} + +static int +ble_svc_audio_pacs_avail_audio_ctx_read_access(uint16_t conn_handle, + struct ble_gatt_access_ctxt *ctxt) +{ + struct available_ctx *avail_ctx; + uint8_t *buf; + + avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le16(buf + 0, avail_ctx->ble_svc_audio_pacs_avail_sink_contexts); + put_le16(buf + 2, avail_ctx->ble_svc_audio_pacs_avail_source_contexts); + + return 0; +} + +static int +ble_svc_audio_pacs_sup_audio_ctx_read_access(struct ble_gatt_access_ctxt + *ctxt) +{ + uint8_t *buf; + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le16(buf + 0, ble_svc_audio_pacs_sup_sink_contexts); + put_le16(buf + 2, ble_svc_audio_pacs_sup_source_contexts); + + return 0; +} + +static int +ble_svc_audio_pacs_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid); + int rc; + + switch (uuid16) { + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_sink_pac_read_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_sink_audio_loc_read_access(ctxt); + } else { + rc = BLE_ATT_ERR_REQ_NOT_SUPPORTED; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_source_pac_read_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_source_audio_loc_read_access(ctxt); + } else { + rc = BLE_ATT_ERR_REQ_NOT_SUPPORTED; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_avail_audio_ctx_read_access(conn_handle, + ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_sup_audio_ctx_read_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} + +static int +pac_notify(uint16_t chrc_uuid) +{ + uint16_t chr_val_handle; + int rc; + + if (!ble_hs_is_enabled()) { + /* Do not notify if host has not started yet */ + return 0; + } + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BLE_SVC_AUDIO_PACS_UUID16), + BLE_UUID16_DECLARE(chrc_uuid), NULL, &chr_val_handle); + + if (!rc) { + ble_gatts_chr_updated(chr_val_handle); + } + + return rc; +} + +int +ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param) +{ + int rc; + + if (flags & BLE_AUDIO_CODEC_DIR_SOURCE_BIT) { + ble_svc_audio_pacs_source_audio_locations = param->audio_locations; + ble_svc_audio_pacs_sup_source_contexts = param->supported_contexts; + rc = pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS); + if (rc != 0) { + return rc; + } + } + + if (flags & BLE_AUDIO_CODEC_DIR_SINK_BIT) { + ble_svc_audio_pacs_sink_audio_locations = param->audio_locations; + ble_svc_audio_pacs_sup_sink_contexts = param->supported_contexts; + rc = pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS); + if (rc != 0) { + return rc; + } + } + + return pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS); +} + +int +ble_svc_audio_pacs_avail_contexts_set(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts) +{ + struct available_ctx *avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); + + avail_ctx->ble_svc_audio_pacs_avail_sink_contexts = sink_contexts; + avail_ctx->ble_svc_audio_pacs_avail_source_contexts = source_contexts; + + return pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS); +} + +static int +ble_pacs_audio_event(struct ble_audio_event *event, void *arg) +{ + if (event->type == BLE_AUDIO_EVENT_CODEC_CHANGED) { + if (event->codec_changed.record->direction & BLE_AUDIO_CODEC_DIR_SOURCE_BIT) { + pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC); + } + + if (event->codec_changed.record->direction & BLE_AUDIO_CODEC_DIR_SINK_BIT) { + pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC); + } + } + + return 0; +} + +static int +ble_pacs_gap_event(struct ble_gap_event *event, void *arg) +{ + struct available_ctx *avail_ctx; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + if (event->connect.status != 0) { + break; + } + avail_ctx = ble_svc_audio_pacs_find_avail_ctx(BLE_HS_CONN_HANDLE_NONE); + avail_ctx->conn_handle = event->connect.conn_handle; + break; + case BLE_GAP_EVENT_DISCONNECT: + avail_ctx = ble_svc_audio_pacs_find_avail_ctx(event->disconnect.conn.conn_handle); + if (avail_ctx >= 0) { + avail_ctx->conn_handle = BLE_HS_CONN_HANDLE_NONE; + } + break; + default: + break; + } + return 0; +} + +void +ble_svc_audio_pacs_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = ble_gatts_count_cfg(ble_svc_audio_pacs_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gatts_add_svcs(ble_svc_audio_pacs_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gap_event_listener_register(&ble_pacs_listener, + ble_pacs_gap_event, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_audio_event_listener_register(&ble_audio_listener, ble_pacs_audio_event, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + (void)rc; +} diff --git a/nimble/host/audio/services/pacs/syscfg.yml b/nimble/host/audio/services/pacs/syscfg.yml new file mode 100644 index 0000000000..01481c0cee --- /dev/null +++ b/nimble/host/audio/services/pacs/syscfg.yml @@ -0,0 +1,69 @@ +# 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. + +syscfg.defs: + BLE_SVC_AUDIO_PACS_SYSINIT_STAGE: + description: > + Sysinit stage for Published Audio Capabilities Service. + value: 303 + BLE_SVC_AUDIO_PACS_SINK_PAC: + description: > + Enable Sink PAC characteristic. + If disabled, BLE_SVC_AUDIO_PACS_SOURCE_PAC must be enabled. + value: 1 + BLE_SVC_AUDIO_PACS_SINK_PAC_NOTIFY: + description: > + Enable Sink PAC characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SINK_PAC + BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS: + description: > + Enable SOURCE Sink Audio Locations characteristic. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SINK_PAC + BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS_NOTIFY: + description: > + Enable SOURCE Sink Audio Locations characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS + BLE_SVC_AUDIO_PACS_SOURCE_PAC: + description: > + Enable Source PAC characteristic. + If disabled, BLE_SVC_AUDIO_PACS_SINK_PAC must be enabled. + value: 1 + BLE_SVC_AUDIO_PACS_SOURCE_PAC_NOTIFY: + description: > + Enable Source PAC characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SOURCE_PAC + BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS: + description: > + Enable Source Audio Locations characteristic. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SOURCE_PAC + BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS_NOTIFY: + description: > + Enable Source Audio Locations characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS + BLE_SVC_AUDIO_PACS_SUP_AUDIO_CTX_NOTIFY: + description: > + Enable Supported Audio Contexts characteristic notifications. + value: 1 + +syscfg.restrictions: + - 'BLE_SVC_AUDIO_PACS_SINK_PAC == 1 || BLE_SVC_AUDIO_PACS_SOURCE_PAC == 1' diff --git a/nimble/host/audio/src/ble_audio_codec.c b/nimble/host/audio/src/ble_audio_codec.c new file mode 100644 index 0000000000..dcfe5c0d83 --- /dev/null +++ b/nimble/host/audio/src/ble_audio_codec.c @@ -0,0 +1,137 @@ +/* + * 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 "os/os.h" +#include "audio/ble_audio.h" +#include "audio/ble_audio_codec.h" +#include "ble_audio_priv.h" +#include "host/ble_hs.h" +#include "syscfg/syscfg.h" +#include "sysinit/sysinit.h" + +static STAILQ_HEAD(, ble_audio_codec_record) ble_audio_codec_records; +static struct os_mempool ble_audio_codec_pool; + +static os_membuf_t ble_audio_svc_pacs_pac_elem_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS), + sizeof (struct ble_audio_codec_record)) +]; + +int +ble_audio_codec_register(const struct ble_audio_codec_register_params *params, + struct ble_audio_codec_record *out_record) +{ + struct ble_audio_event codec_event = { + .type = BLE_AUDIO_EVENT_CODEC_CHANGED + }; + + struct ble_audio_codec_record *record = + os_memblock_get(&ble_audio_codec_pool); + if (!record) { + return BLE_HS_ENOMEM; + } + + record->codec_id = params->codec_id; + record->codec_spec_caps_len = params->codec_spec_caps_len; + record->codec_spec_caps = params->codec_spec_caps; + record->metadata_len = params->metadata_len; + record->metadata = params->metadata; + record->direction = params->direction; + + if (STAILQ_EMPTY(&ble_audio_codec_records)) { + STAILQ_INSERT_HEAD(&ble_audio_codec_records, record, next); + } else { + STAILQ_INSERT_TAIL(&ble_audio_codec_records, record, next); + } + + out_record = record; + + codec_event.codec_changed.record = record; + codec_event.codec_changed.change = CODEC_REGISTERED; + (void)ble_audio_event_listener_call(&codec_event); + + return 0; +} + +int +ble_audio_codec_unregister(struct ble_audio_codec_record *codec_record) +{ + struct ble_audio_event codec_event = { + .type = BLE_AUDIO_EVENT_CODEC_CHANGED + }; + + STAILQ_REMOVE(&ble_audio_codec_records, codec_record, + ble_audio_codec_record, next); + + codec_event.codec_changed.record = codec_record; + codec_event.codec_changed.change = CODEC_UNREGISTERED; + (void)ble_audio_event_listener_call(&codec_event); + + return 0; +} + +int +ble_audio_codec_foreach(uint8_t flags, ble_audio_codec_foreach_fn *cb, void *arg) +{ + struct ble_audio_codec_record *record; + int rc; + + STAILQ_FOREACH(record, &ble_audio_codec_records, next) { + if (record->direction & flags) { + rc = cb(record, arg); + if (rc != 0) { + return rc; + } + } + } + return 0; +} + +struct ble_audio_codec_record * +ble_audio_codec_find(struct ble_audio_codec_id codec_id, uint8_t flag) +{ + struct ble_audio_codec_record *record; + + STAILQ_FOREACH(record, &ble_audio_codec_records, next) { + if (!memcmp(&record->codec_id, &codec_id, + sizeof(struct ble_audio_codec_id)) && + (flag ? (record->direction & flag) : 1)) { + return record; + } + } + + return NULL; +} + +int +ble_audio_codec_init(void) +{ + int rc; + + STAILQ_INIT(&ble_audio_codec_records); + + rc = os_mempool_init(&ble_audio_codec_pool, + MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS), + sizeof(struct ble_audio_codec_record), + ble_audio_svc_pacs_pac_elem_mem, + "ble_audio_codec_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} diff --git a/nimble/host/audio/syscfg.yml b/nimble/host/audio/syscfg.yml index d7af13d1a0..5f0269e0ab 100644 --- a/nimble/host/audio/syscfg.yml +++ b/nimble/host/audio/syscfg.yml @@ -17,5 +17,9 @@ # syscfg.defs: + BLE_AUDIO_MAX_CODEC_RECORDS: + description: > + Maximum number of registered audio codecs. + value: 0 syscfg.logs: diff --git a/nimble/host/src/ble_audio_codec_priv.h b/nimble/host/src/ble_audio_codec_priv.h new file mode 100644 index 0000000000..64e999efeb --- /dev/null +++ b/nimble/host/src/ble_audio_codec_priv.h @@ -0,0 +1,25 @@ +/* + * 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_CODEC_PRIV_ +#define H_BLE_AUDIO_CODEC_PRIV_ + +int ble_audio_codec_init(void); + +#endif /* H_BLE_AUDIO_CODEC_PRIV_ */ diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 147837d9f3..072e3120d6 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -765,6 +765,11 @@ ble_hs_init(void) #endif #endif +#if MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS) + rc = ble_audio_codec_init(); + SYSINIT_PANIC_ASSERT(rc == 0); +#endif + ble_hs_stop_init(); ble_mqueue_init(&ble_hs_rx_q, ble_hs_event_rx_data, NULL); diff --git a/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index 393b4d4323..49022b17b7 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/nimble/host/src/ble_hs_priv.h @@ -26,6 +26,7 @@ #include "ble_att_priv.h" #include "ble_eatt_priv.h" #include "ble_gap_priv.h" +#include "ble_audio_codec_priv.h" #include "ble_gatt_priv.h" #include "ble_hs_hci_priv.h" #include "ble_hs_atomic_priv.h" diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 6571329582..e4d2d3a46f 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -599,6 +599,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 8321199654..3919eb1eb0 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -600,6 +600,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index af7f7992cb..16cdc6c005 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -599,6 +599,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index c62bb02c50..4054f14403 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -598,6 +598,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 27047feb56..1c46e12a63 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1515,6 +1515,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif