Skip to content

Commit

Permalink
nimble/services: add PACS
Browse files Browse the repository at this point in the history
This commit adds Published Audio Capabilities Service/Prifile. In pair
ble_audio_codec module is added, that supports registering supported
codecs with their corresponding configurations.
  • Loading branch information
KKopyscinski committed Jan 31, 2024
1 parent e5acfe0 commit daa4f27
Show file tree
Hide file tree
Showing 20 changed files with 1,268 additions and 10 deletions.
126 changes: 126 additions & 0 deletions nimble/host/include/host/ble_audio_codec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* 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_

#include "stdint.h"
#include "ble_audio_common.h"

#define BLE_AUDIO_CODEC_FLAG_SOURCE 0x01
#define BLE_AUDIO_CODEC_FLAG_SINK 0x02

/** 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;

/* Codec entry flags. It is any combination of following flags:
* - BLE_AUDIO_CODEC_FLAG_SOURCE
* - BLE_AUDIO_CODEC_FLAG_SINK
*/
uint8_t flags;
};

/** 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;

/* Codec entry flags. It is any combination of following flags:
* - BLE_AUDIO_CODEC_FLAG_SOURCE
* - BLE_AUDIO_CODEC_FLAG_SINK
*/
uint8_t flags;
};

/**
* @brief Register codec entry
*
* @param[in] params Pointer to a `ble_audio_codec_register_params`
* structure that defines Codec Specific Capabilities
* @param[in] cb Function used to parse Codec
* Specific Capabilities
* @param[in] cb_arg Optional callback argument.
* @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] cb Callback to be called on codec entries.
* @param[in] arg Optional callback argument.
* @param[in] flags Codec entry flags. It is any
* combination of following flags:
* - BLE_AUDIO_CODEC_FLAG_SOURCE
* - BLE_AUDIO_CODEC_FLAG_SINK
* This filters entries so the callback is called
* only on these that match the flag.
*
* @return 0 on success;
* A non-zero value on failure.
*/
int ble_audio_codec_foreach(uint8_t flags, ble_audio_codec_foreach_fn *cb, void *arg);

#endif /* H_BLE_AUDIO_CODEC_ */
106 changes: 96 additions & 10 deletions nimble/host/include/host/ble_audio_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,59 @@
#define BLE_AUDIO_LOCATION_LEFT_SURROUND (1ULL << 23)
#define BLE_AUDIO_LOCATION_RIGHT_SURROUND (1ULL << 24)

#define BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE 0x01
#define BLE_AUDIO_CODEC_FRAME_DURATION_TYPE 0x02
#define BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03
#define BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE 0x04
#define BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE 0x05
#define BLE_AUDIO_CODEC_CONF_SAMPLING_FREQ_TYPE 0x01
#define BLE_AUDIO_CODEC_CONF_FRAME_DURATION_TYPE 0x02
#define BLE_AUDIO_CODEC_CONF_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03
#define BLE_AUDIO_CODEC_CONF_OCTETS_PER_CODEC_FRAME_TYPE 0x04
#define BLE_AUDIO_CODEC_CONF_FRAME_BLOCKS_PER_SDU_TYPE 0x05

#define BLE_AUDIO_CODEC_CAPS_SAMPLING_FREQ_TYPE 0x01
#define BLE_AUDIO_CODEC_CAPS_FRAME_DURATION_TYPE 0x02
#define BLE_AUDIO_CODEC_CAPS_SUP_AUDIO_CHANNEL_COUNTS_TYPE 0x03
#define BLE_AUDIO_CODEC_CAPS_OCTETS_PER_CODEC_FRAME_TYPE 0x04
#define BLE_AUDIO_CODEC_CAPS_FRAMES_PER_SDU_TYPE 0x05

#define BLE_AUDIO_CONTEXT_TYPE_PROHIBITED 0x0000
#define BLE_AUDIO_CONTEXT_TYPE_UNSPECIFIED 0x0001
#define BLE_AUDIO_CONTEXT_TYPE_CONVERSATIONAL 0x0002
#define BLE_AUDIO_CONTEXT_TYPE_MEDIA 0x0004
#define BLE_AUDIO_CONTEXT_TYPE_GAME 0x0008
#define BLE_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL 0x0010
#define BLE_AUDIO_CONTEXT_TYPE_VOICE_ASSISTANTS 0x0020
#define BLE_AUDIO_CONTEXT_TYPE_LIVE 0x0040
#define BLE_AUDIO_CONTEXT_TYPE_SOUND_EFFECTS 0x0080
#define BLE_AUDIO_CONTEXT_TYPE_NOTIFICATIONS 0x0100
#define BLE_AUDIO_CONTEXT_TYPE_RINGTONE 0x0200
#define BLE_AUDIO_CONTEXT_TYPE_ALERTS 0x0400
#define BLE_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM 0x0800

#define BLE_AUDIO_CODEC_SUPPORTED_FRAME_DURATION_7_5_MS 0x0001
#define BLE_AUDIO_CODEC_SUPPORTED_FRAME_DURATION_10_MS 0x0002
#define BLE_AUDIO_CODEC_PREFERED_FRAME_DURATION_7_5_MS 0x0010
#define BLE_AUDIO_CODEC_PREFERED_FRAME_DURATION_10_MS 0x0020

#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_8000_HZ (1ULL)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_11025_HZ (1ULL << 1)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_16000_HZ (1ULL << 2)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_22050_HZ (1ULL << 3)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_24000_HZ (1ULL << 4)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_32000_HZ (1ULL << 5)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_44100_HZ (1ULL << 6)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_48000_HZ (1ULL << 7)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_88200_HZ (1ULL << 8)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_96000_HZ (1ULL << 9)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_176400_HZ (1ULL << 10)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_192000_HZ (1ULL << 11)
#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_384000_HZ (1ULL << 12)

#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_1 0x0001
#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_2 0x0002
#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_3 0x0004
#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_4 0x0008
#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_5 0x0010
#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_6 0x0020
#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_7 0x0040
#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_8 0x0080
/**
* @brief Helper macro used to build LTV array of Codec_Specific_Configuration.
*
Expand All @@ -117,16 +164,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_CAPS_SAMPLING_FREQ_TYPE, _sampling_freq, \
2, BLE_AUDIO_CODEC_CAPS_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 -
* single 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) \
}

struct ble_audio_codec_id {
/** Coding Fromat */
uint8_t format;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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_

#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 {
uint32_t audio_locations;
uint16_t supported_contexts;
};

int ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param);

int ble_svc_audio_pacs_set_avail_contexts(uint16_t conn_handle,
uint16_t sink_contexts,
uint16_t source_contexts);

#endif /* H_BLE_AUDIO_SVC_PACS_ */
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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_

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_ */
33 changes: 33 additions & 0 deletions nimble/host/services/audio/pacs/lc3/pkg.yml
Original file line number Diff line number Diff line change
@@ -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/services/audio/pacs/lc3
pkg.description: LC3 codec entry for Published Audio Capabilities Service
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
- ble
- bluetooth
- pacs
- nimble

pkg.deps:
- nimble/host/services/audio/pacs
- nimble/host

pkg.init:
ble_svc_audio_pacs_lc3_init: 'MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SYSINIT_STAGE)'
Loading

0 comments on commit daa4f27

Please sign in to comment.