Skip to content

Commit

Permalink
Bluetooth: GMAP: Add initial implementation of GMAP
Browse files Browse the repository at this point in the history
Add initial implementation of GMAP.

Signed-off-by: Emil Gydesen <[email protected]>
  • Loading branch information
Thalley committed Jun 28, 2023
1 parent bbec614 commit 79b774f
Show file tree
Hide file tree
Showing 41 changed files with 4,589 additions and 137 deletions.
123 changes: 123 additions & 0 deletions include/zephyr/bluetooth/audio/gmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/** @file
* @brief Header for Bluetooth GMAP.
*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_
#define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_

#include <zephyr/bluetooth/conn.h>
#include <zephyr/sys/util_macro.h>

/**
* @brief Bluetooth Gaming Profile (GMAP)
* @defgroup bt_gmap Bluetooth Gaming Profile
* @ingroup bluetooth
* @{
*/

/** Gaming Role bitfield */
enum bt_gmap_role {
/** Gaming Role Unicast Game Gateway */
BT_GMAP_ROLE_UGG = BIT(0),
/** Gaming Role Unicast Game Terminal */
BT_GMAP_ROLE_UGT = BIT(1),
/** Gaming Role Broadcast Game Sender */
BT_GMAP_ROLE_BGS = BIT(2),
/** Gaming Role Broadcast Game Receiver */
BT_GMAP_ROLE_BGR = BIT(3),
};

/* TBD: Should we declare a single enum for feature supported, and then transform from the spec
* defined values to Zephyr define values
*/

/** Unicast Game Gateway Feature bitfield */
enum bt_gmap_ugg_feat {
/** Multiplex support */
BT_GMAP_UGG_FEAT_MULTIPLEX = BIT(0),
/** 96 kbps support */
BT_GMAP_UGG_FEAT_96KBPS = BIT(1),
/** Multisink support */
BT_GMAP_UGG_FEAT_MULTISINK = BIT(2),
};

/** Unicast Game Terminal Feature bitfield */
enum bt_gmap_ugt_feat {
/** Source support */
BT_GMAP_UGT_FEAT_SOURCE = BIT(0),
/** 80 kbps source support */
BT_GMAP_UGT_FEAT_80KBPS_SOURCE = BIT(1),
/** Sink support */
BT_GMAP_UGT_FEAT_SINK = BIT(2),
/** 64 kbps sink support */
BT_GMAP_UGT_FEAT_64KBPS_SINK = BIT(3),
/** Multiplex support */
BT_GMAP_UGT_FEAT_MULTIPLEX = BIT(4),
/** Multisink support */
BT_GMAP_UGT_FEAT_MULTISINK = BIT(5),
/** Multisource support */
BT_GMAP_UGT_FEAT_MULTISOURCE = BIT(6),
};

/** Broadcast Game Sender Feature bitfield */
enum bt_gmap_bgs_feat {
/** 96 kbps support */
BT_GMAP_BGS_FEAT_96KBPS = BIT(0),
};

/** Broadcast Game Receiver Feature bitfield */
enum bt_gmap_bgr_feat {
/** Multisink support */
BT_GMAP_BGR_FEAT_MULTISINK = BIT(0),
/** Multiplex support */
BT_GMAP_BGR_FEAT_MULTIPLEX = BIT(1),
};

/** @brief Hearing Access Service Client callback structure. */
struct bt_gmap_cb {
/**
* @brief Callback function for bt_has_discover.
*
* This callback is called when discovery procedure is complete.
*
* @param conn Bluetooth connection object.
* @param err 0 on success, ATT error or negative errno otherwise.
* @param role Role of remote device. 0 on failure.
* @param ugg_feat Remote Unicast Game Gateway features. 0 if not supported or on error.
* @param ugt_feat Remote Unicast Game Terminal features. 0 if not supported or on error.
* @param bgs_feat Remote Broadcast Game Sender features. 0 if not supported or on error.
* @param bgr_feat Remote Broadcast Game Receiver features. 0 if not supported or on error.
*/
void (*discover)(struct bt_conn *conn, int err, enum bt_gmap_role role,
enum bt_gmap_ugg_feat ugg_feat, enum bt_gmap_ugt_feat ugt_feat,
enum bt_gmap_bgs_feat bgs_feat, enum bt_gmap_bgr_feat bgr_feat);
};

/** @brief Registers the callbacks used by the Gaming Profile.
*
* @param cb The callback structure.
*
* @return 0 in case of success or negative value in case of error.
*/
int bt_gmap_cb_register(const struct bt_gmap_cb *cb);

/**
* @brief Discover Gaming Service on a remote device.
*
* Procedure to find a Gaming Service on a server identified by @p conn.
* The @ref bt_gmap_cb.discover callback is called when the discovery procedure completes of fails.
* On discovery success the callback contains information about the remote device.
*
* @param conn Bluetooth connection object.
*
* @return 0 if success, errno on failure.
*/
int bt_gmap_discover(struct bt_conn *conn);

/** @} */ /* end of bt_gmap */

#endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_ */
162 changes: 162 additions & 0 deletions include/zephyr/bluetooth/audio/gmap_lc3_preset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/** @file
* @brief Header for Bluetooth GMAP LC3 presets.
*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_LC3_PRESET_
#define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_LC3_PRESET_

#include <zephyr/bluetooth/audio/bap_lc3_preset.h>

/* GMAP LC3 unicast presets defined by table 3.16 in the GMAP v1.0 specification */

/**
* @brief Helper to declare LC3 32_1_gr codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_32_1_GR(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_32_1(_loc, _stream_context), \
BT_CODEC_LC3_QOS_7_5_UNFRAMED(60U, 1U, 15U, 10000U))

/**
* @brief Helper to declare LC3 32_2_gr codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_32_2_GR(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_32_2(_loc, _stream_context), \
BT_CODEC_LC3_QOS_10_UNFRAMED(80U, 1U, 20U, 10000U))

/**
* @brief Helper to declare LC3 48_1_gr codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_1_GR(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_1(_loc, _stream_context), \
BT_CODEC_LC3_QOS_7_5_UNFRAMED(75U, 1U, 15U, 10000U))

/**
* @brief Helper to declare LC3 48_2_gr codec configuration
*
* Mandatory to support as both unicast client and server
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_2_GR(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_2(_loc, _stream_context), \
BT_CODEC_LC3_QOS_10_UNFRAMED(100U, 1U, 20U, 10000U))

/**
* @brief Helper to declare LC3 48_3_gr codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_3_GR(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_3(_loc, _stream_context), \
BT_CODEC_LC3_QOS_7_5_UNFRAMED(90U, 1U, 15U, 10000U))

/**
* @brief Helper to declare LC3 48_4_gr codec configuration
*
* Mandatory to support as unicast server
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_4_GR(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_4(_loc, _stream_context), \
BT_CODEC_LC3_QOS_10_UNFRAMED(120U, 1U, 20U, 10000U))

/**
* @brief Helper to declare LC3 32_1_gs codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_32_1_GS(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_32_1(_loc, _stream_context), \
BT_CODEC_LC3_QOS_7_5_UNFRAMED(60U, 1U, 15U, 21500U))

/**
* @brief Helper to declare LC3 32_2_gs codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_32_2_GS(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_32_2(_loc, _stream_context), \
BT_CODEC_LC3_QOS_10_UNFRAMED(80U, 1U, 20U, 22500U))

/**
* @brief Helper to declare LC3 48_1_gs codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_1_GS(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_1(_loc, _stream_context), \
BT_CODEC_LC3_QOS_7_5_UNFRAMED(75U, 1U, 15U, 21500U))

/**
* @brief Helper to declare LC3 48_2_gs codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_2_GS(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_2(_loc, _stream_context), \
BT_CODEC_LC3_QOS_10_UNFRAMED(100U, 1U, 20U, 22500U))

/* GMAP LC3 broadcast presets defined by table 3.22 in the GMAP v1.0 specification */

/**
* @brief Helper to declare LC3 48_1_g codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_1_G(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_1(_loc, _stream_context), \
BT_CODEC_LC3_QOS_7_5_UNFRAMED(75U, 1U, 8U, 10000U))

/**
* @brief Helper to declare LC3 48_2_g codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_2_G(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_2(_loc, _stream_context), \
BT_CODEC_LC3_QOS_10_UNFRAMED(100U, 1U, 10U, 10000U))

/**
* @brief Helper to declare LC3 48_3_g codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_3_G(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_3(_loc, _stream_context), \
BT_CODEC_LC3_QOS_7_5_UNFRAMED(90U, 1U, 8U, 10000U))

/**
* @brief Helper to declare LC3 48_4_g codec configuration
*
* @param _loc Audio channel location bitfield (@ref bt_audio_location)
* @param _stream_context Stream context (BT_AUDIO_CONTEXT_*)
*/
#define BT_GMAP_LC3_PRESET_48_4_G(_loc, _stream_context) \
BT_BAP_LC3_PRESET(BT_CODEC_LC3_CONFIG_48_4(_loc, _stream_context), \
BT_CODEC_LC3_QOS_10_UNFRAMED(120U, 1U, 10U, 10000U))

#endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_LC3_PRESET_ */
55 changes: 55 additions & 0 deletions include/zephyr/bluetooth/uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -5090,6 +5090,61 @@ struct bt_uuid_128 {
*/
#define BT_UUID_GATT_SL \
BT_UUID_DECLARE_16(BT_UUID_GATT_SL_VAL)

/**
* @brief Gaming Service UUID value
*/
#define BT_UUID_GMAS_VAL 0x1858
/**
* @brief Common Audio Service
*/
#define BT_UUID_GMAS BT_UUID_DECLARE_16(BT_UUID_GMAS_VAL)

/**
* @brief Gaming Profile Role UUID value
*/
#define BT_UUID_GMAP_ROLE_VAL 0x2C00
/**
* @brief Gaming Profile Role
*/
#define BT_UUID_GMAP_ROLE BT_UUID_DECLARE_16(BT_UUID_GMAP_ROLE_VAL)

/**
* @brief Gaming Profile Unicast Game Gateway Features UUID value
*/
#define BT_UUID_GMAP_UGG_FEAT_VAL 0x2C01
/**
* @brief Gaming Profile Unicast Game Gateway Features
*/
#define BT_UUID_GMAP_UGG_FEAT BT_UUID_DECLARE_16(BT_UUID_GMAP_UGG_FEAT_VAL)

/**
* @brief Gaming Profile Unicast Game Terminal Features UUID value
*/
#define BT_UUID_GMAP_UGT_FEAT_VAL 0x2C02
/**
* @brief Gaming Profile Unicast Game Terminal Features
*/
#define BT_UUID_GMAP_UGT_FEAT BT_UUID_DECLARE_16(BT_UUID_GMAP_UGT_FEAT_VAL)

/**
* @brief Gaming Profile Broadcast Game Sender Features UUID value
*/
#define BT_UUID_GMAP_BGS_FEAT_VAL 0x2C03
/**
* @brief Gaming Profile Broadcast Game Sender Features
*/
#define BT_UUID_GMAP_BGS_FEAT BT_UUID_DECLARE_16(BT_UUID_GMAP_BGS_FEAT_VAL)

/**
* @brief Gaming Profile Broadcast Game Receiver Features UUID value
*/
#define BT_UUID_GMAP_BGR_FEAT_VAL 0x2C04
/**
* @brief Gaming Profile Broadcast Game Receiver Features
*/
#define BT_UUID_GMAP_BGR_FEAT BT_UUID_DECLARE_16(BT_UUID_GMAP_BGR_FEAT_VAL)

/*
* Protocol UUIDs
*/
Expand Down
2 changes: 2 additions & 0 deletions subsys/bluetooth/audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ zephyr_library_sources_ifdef(CONFIG_BT_CAP cap_stream.c)
zephyr_library_sources_ifdef(CONFIG_BT_CAP_ACCEPTOR cap_acceptor.c)
zephyr_library_sources_ifdef(CONFIG_BT_CAP_INITIATOR cap_initiator.c)
zephyr_library_sources_ifdef(CONFIG_BT_TMAP tmap.c)
zephyr_library_sources_ifdef(CONFIG_BT_GMAS gmap_server.c)
zephyr_library_sources_ifdef(CONFIG_BT_GMAP gmap_client.c)
1 change: 1 addition & 0 deletions subsys/bluetooth/audio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ rsource "Kconfig.mpl"
rsource "Kconfig.mctl"
rsource "Kconfig.cap"
rsource "Kconfig.tmap"
rsource "Kconfig.gmap"

module = BT_AUDIO
module-str = "Bluetooth Audio"
Expand Down
Loading

0 comments on commit 79b774f

Please sign in to comment.