Skip to content

Commit 240ad5c

Browse files
makeshicfriedt
authored andcommitted
bluetooth: avrcp: Add support for AVRCP browsing
- AVRCP SDP record updates for browsing channel - L2CAP setup for AVCTP browsing channel, and add connect/disconnect - Add SetBrowsedPlayer browsing command handling Signed-off-by: Make Shi <[email protected]>
1 parent b923bde commit 240ad5c

File tree

4 files changed

+788
-15
lines changed

4 files changed

+788
-15
lines changed

include/zephyr/bluetooth/classic/avrcp.h

Lines changed: 248 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,124 @@ typedef enum __packed {
141141
BT_AVRCP_BUTTON_RELEASED = 1,
142142
} bt_avrcp_button_state_t;
143143

144+
/**
145+
* @brief AVRCP status and error codes.
146+
*
147+
* These status codes are used in AVRCP responses to indicate the result of a command.
148+
*/
149+
typedef enum __packed {
150+
/** Invalid command.
151+
* Valid for Commands: All
152+
*/
153+
BT_AVRCP_STATUS_INVALID_COMMAND = 0x00,
154+
155+
/** Invalid parameter.
156+
* Valid for Commands: All
157+
*/
158+
BT_AVRCP_STATUS_INVALID_PARAMETER = 0x01,
159+
160+
/** Parameter content error.
161+
* Valid for Commands: All
162+
*/
163+
BT_AVRCP_STATUS_PARAMETER_CONTENT_ERROR = 0x02,
164+
165+
/** Internal error.
166+
* Valid for Commands: All
167+
*/
168+
BT_AVRCP_STATUS_INTERNAL_ERROR = 0x03,
169+
170+
/** Operation completed without error.
171+
* Valid for Commands: All except where the response CType is AV/C REJECTED
172+
*/
173+
BT_AVRCP_STATUS_OPERATION_COMPLETED = 0x04,
174+
175+
/** The UIDs on the device have changed.
176+
* Valid for Commands: All
177+
*/
178+
BT_AVRCP_STATUS_UID_CHANGED = 0x05,
179+
180+
/** The Direction parameter is invalid.
181+
* Valid for Commands: ChangePath
182+
*/
183+
BT_AVRCP_STATUS_INVALID_DIRECTION = 0x07,
184+
185+
/** The UID provided does not refer to a folder item.
186+
* Valid for Commands: ChangePath
187+
*/
188+
BT_AVRCP_STATUS_NOT_A_DIRECTORY = 0x08,
189+
190+
/** The UID provided does not refer to any currently valid item.
191+
* Valid for Commands: ChangePath, PlayItem, AddToNowPlaying, GetItemAttributes
192+
*/
193+
BT_AVRCP_STATUS_DOES_NOT_EXIST = 0x09,
194+
195+
/** Invalid scope.
196+
* Valid for Commands: GetFolderItems, PlayItem, AddToNowPlayer, GetItemAttributes,
197+
* GetTotalNumberOfItems
198+
*/
199+
BT_AVRCP_STATUS_INVALID_SCOPE = 0x0a,
200+
201+
/** Range out of bounds.
202+
* Valid for Commands: GetFolderItems
203+
*/
204+
BT_AVRCP_STATUS_RANGE_OUT_OF_BOUNDS = 0x0b,
205+
206+
/** Folder item is not playable.
207+
* Valid for Commands: Play Item, AddToNowPlaying
208+
*/
209+
BT_AVRCP_STATUS_FOLDER_ITEM_IS_NOT_PLAYABLE = 0x0c,
210+
211+
/** Media in use.
212+
* Valid for Commands: PlayItem, AddToNowPlaying
213+
*/
214+
BT_AVRCP_STATUS_MEDIA_IN_USE = 0x0d,
215+
216+
/** Now Playing List full.
217+
* Valid for Commands: AddToNowPlaying
218+
*/
219+
BT_AVRCP_STATUS_NOW_PLAYING_LIST_FULL = 0x0e,
220+
221+
/** Search not supported.
222+
* Valid for Commands: Search
223+
*/
224+
BT_AVRCP_STATUS_SEARCH_NOT_SUPPORTED = 0x0f,
225+
226+
/** Search in progress.
227+
* Valid for Commands: Search
228+
*/
229+
BT_AVRCP_STATUS_SEARCH_IN_PROGRESS = 0x10,
230+
231+
/** The specified Player Id does not refer to a valid player.
232+
* Valid for Commands: SetAddressedPlayer, SetBrowsedPlayer
233+
*/
234+
BT_AVRCP_STATUS_INVALID_PLAYER_ID = 0x11,
235+
236+
/** Player not browsable.
237+
* Valid for Commands: SetBrowsedPlayer
238+
*/
239+
BT_AVRCP_STATUS_PLAYER_NOT_BROWSABLE = 0x12,
240+
241+
/** Player not addressed.
242+
* Valid for Commands: Search, SetBrowsedPlayer
243+
*/
244+
BT_AVRCP_STATUS_PLAYER_NOT_ADDRESSED = 0x13,
245+
246+
/** No valid search results.
247+
* Valid for Commands: GetFolderItems
248+
*/
249+
BT_AVRCP_STATUS_NO_VALID_SEARCH_RESULTS = 0x14,
250+
251+
/** No available players.
252+
* Valid for Commands: ALL
253+
*/
254+
BT_AVRCP_STATUS_NO_AVAILABLE_PLAYERS = 0x15,
255+
256+
/** Addressed player changed.
257+
* Valid for Commands: All Register Notification commands
258+
*/
259+
BT_AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED = 0x16,
260+
} bt_avrcp_status_t;
261+
144262
/** @brief AVRCP CT structure */
145263
struct bt_avrcp_ct;
146264
/** @brief AVRCP TG structure */
@@ -167,13 +285,34 @@ struct bt_avrcp_passthrough_rsp {
167285
uint8_t byte0; /**< [7]: state_flag, [6:0]: opid */
168286
uint8_t data_len;
169287
uint8_t data[];
170-
};
288+
} __packed;
171289

172290
struct bt_avrcp_get_cap_rsp {
173291
uint8_t cap_id; /**< bt_avrcp_cap_t */
174292
uint8_t cap_cnt; /**< number of items contained in *cap */
175293
uint8_t cap[]; /**< 1 or 3 octets each depends on cap_id */
176-
};
294+
} __packed;
295+
296+
/** @brief AVRCP Character Set IDs */
297+
typedef enum __packed {
298+
BT_AVRCP_CHARSET_UTF8 = 0x006a,
299+
} bt_avrcp_charset_t;
300+
301+
/** @brief get folder name (response) */
302+
struct bt_avrcp_folder_name {
303+
uint16_t folder_name_len;
304+
uint8_t folder_name[];
305+
} __packed;
306+
307+
/** @brief Set browsed player response structure */
308+
struct bt_avrcp_set_browsed_player_rsp {
309+
uint8_t status; /**< Status see bt_avrcp_status_t.*/
310+
uint16_t uid_counter; /**< UID counter */
311+
uint32_t num_items; /**< Number of items in the folder */
312+
uint16_t charset_id; /**< Character set ID */
313+
uint8_t folder_depth; /**< Folder depth */
314+
struct bt_avrcp_folder_name folder_names[0]; /**< Folder names data */
315+
} __packed;
177316

178317
struct bt_avrcp_ct_cb {
179318
/** @brief An AVRCP CT connection has been established.
@@ -195,6 +334,25 @@ struct bt_avrcp_ct_cb {
195334
*/
196335
void (*disconnected)(struct bt_avrcp_ct *ct);
197336

337+
/** @brief An AVRCP CT browsing connection has been established.
338+
*
339+
* This callback notifies the application of an avrcp browsing connection,
340+
* i.e., an AVCTP browsing L2CAP connection.
341+
*
342+
* @param conn Connection object.
343+
* @param ct AVRCP CT connection object.
344+
*/
345+
void (*browsing_connected)(struct bt_conn *conn, struct bt_avrcp_ct *ct);
346+
347+
/** @brief An AVRCP CT browsing connection has been disconnected.
348+
*
349+
* This callback notifies the application that an avrcp browsing connection
350+
* has been disconnected.
351+
*
352+
* @param ct AVRCP CT connection object.
353+
*/
354+
void (*browsing_disconnected)(struct bt_avrcp_ct *ct);
355+
198356
/** @brief Callback function for bt_avrcp_get_cap().
199357
*
200358
* Called when the get capabilities process is completed.
@@ -239,6 +397,19 @@ struct bt_avrcp_ct_cb {
239397
*/
240398
void (*passthrough_rsp)(struct bt_avrcp_ct *ct, uint8_t tid, bt_avrcp_rsp_t result,
241399
const struct bt_avrcp_passthrough_rsp *rsp);
400+
401+
/** @brief Callback function for bt_avrcp_ct_set_browsed_player().
402+
*
403+
* Called when the set browsed player process is completed.
404+
*
405+
* @param ct AVRCP CT connection object.
406+
* @param tid The transaction label of the response.
407+
* @param buf The response buffer containing the set browsed player response data.
408+
* The application can parse this payload according to the format defined in
409+
* @ref bt_avrcp_set_browsed_player_rsp. Note that the data is encoded in
410+
* big-endian format.
411+
*/
412+
void (*browsed_player_rsp)(struct bt_avrcp_ct *ct, uint8_t tid, struct net_buf *buf);
242413
};
243414

244415
/** @brief Connect AVRCP.
@@ -277,6 +448,27 @@ int bt_avrcp_disconnect(struct bt_conn *conn);
277448
*/
278449
struct net_buf *bt_avrcp_create_pdu(struct net_buf_pool *pool);
279450

451+
/** @brief Connect AVRCP browsing channel.
452+
*
453+
* This function is to be called after the AVRCP control channel is established.
454+
* The API is to be used to establish AVRCP browsing connection between devices.
455+
*
456+
* @param conn Pointer to bt_conn structure.
457+
*
458+
* @return 0 in case of success or error code in case of error.
459+
*/
460+
int bt_avrcp_browsing_connect(struct bt_conn *conn);
461+
462+
/** @brief Disconnect AVRCP browsing channel.
463+
*
464+
* This function close AVCTP browsing channel L2CAP connection.
465+
*
466+
* @param conn Pointer to bt_conn structure.
467+
*
468+
* @return 0 in case of success or error code in case of error.
469+
*/
470+
int bt_avrcp_browsing_disconnect(struct bt_conn *conn);
471+
280472
/** @brief Register callback.
281473
*
282474
* Register AVRCP callbacks to monitor the state and interact with the remote device.
@@ -339,6 +531,18 @@ int bt_avrcp_ct_get_subunit_info(struct bt_avrcp_ct *ct, uint8_t tid);
339531
int bt_avrcp_ct_passthrough(struct bt_avrcp_ct *ct, uint8_t tid, uint8_t opid, uint8_t state,
340532
const uint8_t *payload, uint8_t len);
341533

534+
/** @brief Set browsed player.
535+
*
536+
* This function sets the browsed player on the remote device.
537+
*
538+
* @param ct The AVRCP CT instance.
539+
* @param tid The transaction label of the response, valid from 0 to 15.
540+
* @param player_id The player ID to be set as browsed player.
541+
*
542+
* @return 0 in case of success or error code in case of error.
543+
*/
544+
int bt_avrcp_ct_set_browsed_player(struct bt_avrcp_ct *ct, uint8_t tid, uint16_t player_id);
545+
342546
struct bt_avrcp_tg_cb {
343547
/** @brief An AVRCP TG connection has been established.
344548
*
@@ -367,6 +571,35 @@ struct bt_avrcp_tg_cb {
367571
* @param tg AVRCP TG connection object.
368572
*/
369573
void (*unit_info_req)(struct bt_avrcp_tg *tg, uint8_t tid);
574+
575+
/** @brief An AVRCP TG browsing connection has been established.
576+
*
577+
* This callback notifies the application of an avrcp browsing connection,
578+
* i.e., an AVCTP browsing L2CAP connection.
579+
*
580+
* @param conn Connection object.
581+
* @param tg AVRCP TG connection object.
582+
*/
583+
void (*browsing_connected)(struct bt_conn *conn, struct bt_avrcp_tg *tg);
584+
585+
/** @brief An AVRCP TG browsing connection has been disconnected.
586+
*
587+
* This callback notifies the application that an avrcp browsing connection
588+
* has been disconnected.
589+
*
590+
* @param tg AVRCP TG connection object.
591+
*/
592+
void (*browsing_disconnected)(struct bt_avrcp_tg *tg);
593+
594+
/** @brief Set browsed player request callback.
595+
*
596+
* This callback is called whenever an AVRCP set browsed player request is received.
597+
*
598+
* @param tg AVRCP TG connection object.
599+
* @param tid The transaction label of the request.
600+
* @param player_id The player ID to be set as browsed player.
601+
*/
602+
void (*set_browsed_player_req)(struct bt_avrcp_tg *tg, uint8_t tid, uint16_t player_id);
370603
};
371604

372605
/** @brief Register callback.
@@ -391,6 +624,19 @@ int bt_avrcp_tg_register_cb(const struct bt_avrcp_tg_cb *cb);
391624
*/
392625
int bt_avrcp_tg_send_unit_info_rsp(struct bt_avrcp_tg *tg, uint8_t tid,
393626
struct bt_avrcp_unit_info_rsp *rsp);
627+
628+
/** @brief Send the set browsed player response.
629+
*
630+
* This function is called by the application to send the set browsed player response.
631+
*
632+
* @param tg The AVRCP TG instance.
633+
* @param tid The transaction label of the response, valid from 0 to 15.
634+
* @param buf The response buffer containing the set browsed player response data.
635+
*
636+
* @return 0 in case of success or error code in case of error.
637+
*/
638+
int bt_avrcp_tg_send_set_browsed_player_rsp(struct bt_avrcp_tg *tg, uint8_t tid,
639+
struct net_buf *buf);
394640
#ifdef __cplusplus
395641
}
396642
#endif

subsys/bluetooth/host/classic/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,14 @@ config BT_AVRCP_CONTROLLER
485485
help
486486
This option enables the AVRCP profile controller function
487487

488+
config BT_AVRCP_BROWSING
489+
bool "Bluetooth AVRCP Browsing channel support [EXPERIMENTAL]"
490+
select EXPERIMENTAL
491+
select BT_L2CAP_ENH_RET
492+
help
493+
This option enables support for the AVRCP Browsing channel
494+
over Bluetooth BR/EDR.
495+
488496
endif # BT_AVRCP
489497

490498
config BT_PAGE_TIMEOUT

0 commit comments

Comments
 (0)