1 /**
2  * @file
3  * @brief Header for Bluetooth Gaming Audio Profile (GMAP).
4  *
5  * Copyright (c) 2023-2024 Nordic Semiconductor ASA
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_
11 #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_
12 
13 /**
14  * @brief Bluetooth Gaming Audio Profile (GMAP)
15  *
16  * @defgroup bt_gmap Bluetooth Gaming Audio Profile
17  *
18  * @since 3.5
19  * @version 0.8.0
20  *
21  * @ingroup bluetooth
22  * @{
23  */
24 
25 #include <zephyr/bluetooth/conn.h>
26 #include <zephyr/sys/util_macro.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /** Gaming Role bitfield */
33 enum bt_gmap_role {
34 	/**
35 	 * @brief Gaming Role Unicast Game Gateway
36 	 *
37 	 * Requires @kconfig{CONFIG_BT_CAP_INITIATOR}, @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT} and
38 	 * @kconfig{CONFIG_BT_VCP_VOL_CTLR} to be enabled.
39 	 */
40 	BT_GMAP_ROLE_UGG = BIT(0),
41 	/**
42 	 * @brief Gaming Role Unicast Game Terminal
43 	 *
44 	 * Requires @kconfig{CONFIG_BT_CAP_ACCEPTOR} and @kconfig{CONFIG_BT_BAP_UNICAST_SERVER} to
45 	 * be enabled.
46 	 */
47 	BT_GMAP_ROLE_UGT = BIT(1),
48 	/**
49 	 * @brief Gaming Role Broadcast Game Sender
50 	 *
51 	 * Requires @kconfig{CONFIG_BT_CAP_INITIATOR} and @kconfig{CONFIG_BT_BAP_BROADCAST_SOURCE}
52 	 * to be enabled.
53 	 */
54 	BT_GMAP_ROLE_BGS = BIT(2),
55 	/**
56 	 * @brief Gaming Role Broadcast Game Receiver
57 	 *
58 	 * Requires @kconfig{CONFIG_BT_CAP_ACCEPTOR}, @kconfig{CONFIG_BT_BAP_BROADCAST_SINK} and
59 	 * @kconfig{CONFIG_BT_VCP_VOL_REND} to be enabled.
60 	 */
61 	BT_GMAP_ROLE_BGR = BIT(3),
62 };
63 
64 /** Unicast Game Gateway Feature bitfield */
65 enum bt_gmap_ugg_feat {
66 	/**
67 	 * @brief Support transmitting multiple LC3 codec frames per block in an SDU
68 	 *
69 	 * Requires @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT} > 0
70 	 */
71 	BT_GMAP_UGG_FEAT_MULTIPLEX = BIT(0),
72 	/**
73 	 * @brief 96 kbps source support
74 	 *
75 	 * Requires @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT} > 0
76 	 */
77 	BT_GMAP_UGG_FEAT_96KBPS_SOURCE = BIT(1),
78 	/**
79 	 * @brief Support for receiving at least two channels of audio, each in a separate CIS
80 	 *
81 	 * Requires @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT} > 1 and
82 	 * @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT} > 1
83 	 */
84 	BT_GMAP_UGG_FEAT_MULTISINK = BIT(2),
85 };
86 
87 /** Unicast Game Terminal Feature bitfield */
88 enum bt_gmap_ugt_feat {
89 	/**
90 	 * @brief Source support
91 	 *
92 	 * Requires @kconfig{CONFIG_BT_ASCS_ASE_SRC_COUNT} > 0
93 	 */
94 	BT_GMAP_UGT_FEAT_SOURCE = BIT(0),
95 	/**
96 	 * @brief 80 kbps source support
97 	 *
98 	 * Requires BT_GMAP_UGT_FEAT_SOURCE to be set as well
99 	 */
100 	BT_GMAP_UGT_FEAT_80KBPS_SOURCE = BIT(1),
101 	/**
102 	 * @brief Sink support
103 	 *
104 	 * Requires @kconfig{CONFIG_BT_ASCS_ASE_SNK_COUNT} > 0
105 	 */
106 	BT_GMAP_UGT_FEAT_SINK = BIT(2),
107 	/**
108 	 * @brief 64 kbps sink support
109 	 *
110 	 * Requires BT_GMAP_UGT_FEAT_SINK to be set as well
111 	 */
112 	BT_GMAP_UGT_FEAT_64KBPS_SINK = BIT(3),
113 	/**
114 	 * @brief Support for receiving multiple LC3 codec frames per block in an SDU
115 	 *
116 	 * Requires BT_GMAP_UGT_FEAT_SINK to be set as well
117 	 */
118 	BT_GMAP_UGT_FEAT_MULTIPLEX = BIT(4),
119 	/**
120 	 * @brief Support for receiving at least two audio channels, each in a separate CIS
121 	 *
122 	 * Requires @kconfig{CONFIG_BT_ASCS_ASE_SNK_COUNT} > 1 and
123 	 * @kconfig{CONFIG_BT_ASCS_MAX_ACTIVE_ASES} > 1, and BT_GMAP_UGT_FEAT_SINK to be set as well
124 	 */
125 	BT_GMAP_UGT_FEAT_MULTISINK = BIT(5),
126 	/**
127 	 * @brief Support for sending at least two audio channels, each in a separate CIS
128 	 *
129 	 * Requires @kconfig{CONFIG_BT_ASCS_ASE_SRC_COUNT} > 1 and
130 	 * @kconfig{CONFIG_BT_ASCS_MAX_ACTIVE_ASES} > 1, and BT_GMAP_UGT_FEAT_SOURCE to be set
131 	 * as well
132 	 */
133 	BT_GMAP_UGT_FEAT_MULTISOURCE = BIT(6),
134 };
135 
136 /** Broadcast Game Sender Feature bitfield */
137 enum bt_gmap_bgs_feat {
138 	/** 96 kbps support */
139 	BT_GMAP_BGS_FEAT_96KBPS = BIT(0),
140 };
141 
142 /** Broadcast Game Receiver Feature bitfield */
143 enum bt_gmap_bgr_feat {
144 	/**
145 	 * @brief Support for receiving at least two audio channels, each in a separate BIS
146 	 *
147 	 * Requires @kconfig{CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT} > 1
148 	 */
149 	BT_GMAP_BGR_FEAT_MULTISINK = BIT(0),
150 	/** @brief Support for receiving multiple LC3 codec frames per block in an SDU */
151 	BT_GMAP_BGR_FEAT_MULTIPLEX = BIT(1),
152 };
153 
154 /** Broadcast Game Receiver Feature bitfield */
155 struct bt_gmap_feat {
156 	/** Unicast Game Gateway features */
157 	enum bt_gmap_ugg_feat ugg_feat;
158 	/** Unicast Game Terminal features */
159 	enum bt_gmap_ugt_feat ugt_feat;
160 	/** Remote Broadcast Game Sender features */
161 	enum bt_gmap_bgs_feat bgs_feat;
162 	/** Remote Broadcast Game Receiver features */
163 	enum bt_gmap_bgr_feat bgr_feat;
164 };
165 
166 /** @brief Hearing Access Service Client callback structure. */
167 struct bt_gmap_cb {
168 	/**
169 	 * @brief Callback function for bt_has_discover.
170 	 *
171 	 * This callback is called when discovery procedure is complete.
172 	 *
173 	 * @param conn Bluetooth connection object.
174 	 * @param err 0 on success, ATT error or negative errno otherwise.
175 	 * @param role Role of remote device. 0 on failure.
176 	 * @param features Remote features.
177 	 */
178 	void (*discover)(struct bt_conn *conn, int err, enum bt_gmap_role role,
179 			 struct bt_gmap_feat features);
180 };
181 
182 /**
183  * @brief Registers the callbacks used by the Gaming Audio Profile.
184  *
185  * @param cb The callback structure.
186  *
187  * @retval -EINVAL if @p cb is NULL
188  * @retval -EALREADY if callbacks have already be registered
189  * @retval 0 on success
190  */
191 int bt_gmap_cb_register(const struct bt_gmap_cb *cb);
192 
193 /**
194  * @brief Discover Gaming Service on a remote device.
195  *
196  * Procedure to find a Gaming Service on a server identified by @p conn.
197  * The @ref bt_gmap_cb.discover callback is called when the discovery procedure completes of fails.
198  * On discovery success the callback contains information about the remote device.
199  *
200  * @param conn Bluetooth connection object.
201  *
202  * @retval -EINVAL if @p conn is NULL
203  * @retval -EBUSY if discovery is already in progress for @p conn
204  * @retval -ENOEXEC if discovery failed to initiate
205  * @retval 0 on success
206  */
207 int bt_gmap_discover(struct bt_conn *conn);
208 
209 /**
210  * @brief Adds GMAS instance to database and sets the received Gaming Audio Profile role(s).
211  *
212  * @param role     Gaming Audio Profile role(s) of the device (one or multiple).
213  * @param features Features of the roles. If a role is not in the @p role parameter, then the
214  *                 feature value for that role is simply ignored.
215  *
216  * @retval -EINVAL on invalid arguments
217  * @retval -ENOEXEC on service register failure
218  * @retval 0 on success
219  */
220 int bt_gmap_register(enum bt_gmap_role role, struct bt_gmap_feat features);
221 
222 /**
223  * @brief Set one or multiple Gaming Audio Profile roles and features dynamically.
224  *
225  * Previously registered value will be overwritten. If there is a role change, this will trigger
226  * a Gaming Audio Service (GMAS) service change. If there is only a feature change, no service
227  * change will happen.
228  *
229  * @param role     Gaming Audio Profile role(s).
230  * @param features Features of the roles. If a role is not in the @p role parameter, then the
231  *                 feature value for that role is simply ignored.
232  *
233  * @retval -ENOEXEC if the service has not yet been registered
234  * @retval -EINVAL on invalid arguments
235  * @retval -EALREADY if the @p role and @p features are the same as existing ones
236  * @retval -ENOENT on service unregister failure
237  * @retval -ECANCELED on service re-register failure
238  * @retval 0 on success
239  */
240 int bt_gmap_set_role(enum bt_gmap_role role, struct bt_gmap_feat features);
241 
242 #ifdef __cplusplus
243 }
244 #endif
245 /** @} */ /* end of bt_gmap */
246 
247 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_GMAP_ */
248