xref: /btstack/src/classic/avrcp.h (revision 4783d25609a5032739e1b6e67d2236f2d80f2100)
1 /*
2  * Copyright (C) 2016 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 /*
39  * avrcp.h
40  *
41  * Audio/Video Remote Control Profile
42  *
43  */
44 
45 #ifndef AVRCP_H
46 #define AVRCP_H
47 
48 #include <stdint.h>
49 
50 #include "btstack_run_loop.h"
51 #include "btstack_linked_list.h"
52 #include "l2cap.h"
53 
54 #if defined __cplusplus
55 extern "C" {
56 #endif
57 
58 #define PSM_AVCTP_BROWSING              0x001b
59 
60 #define AVRCP_BROWSING_ITEM_HEADER_LEN 3
61 #define AVRCP_BROWSING_MAX_NUM_ATTR_IDS 8
62 
63 #define BT_SIG_COMPANY_ID 0x001958
64 #define AVRCP_MEDIA_ATTR_COUNT 7
65 #define AVRCP_MAX_ATTRIBUTTE_SIZE 100
66 #define AVRCP_ATTRIBUTE_HEADER_LEN  8
67 #define AVRCP_MAX_FOLDER_NAME_SIZE      20
68 
69 #define AVRCP_NO_TRACK_SELECTED_PLAYBACK_POSITION_CHANGED    0xFFFFFFFF
70 
71 typedef enum {
72     AVRCP_STATUS_INVALID_COMMAND = 0,           // sent if TG received a PDU that it did not understand.
73     AVRCP_STATUS_INVALID_PARAMETER,             // Sent if the TG received a PDU with a parameter ID that it did not understand, or, if there is only one parameter ID in the PDU.
74     AVRCP_STATUS_SPECIFIED_PARAMETER_NOT_FOUND, // sent if the parameter ID is understood, but content is wrong or corrupted.
75     AVRCP_STATUS_INTERNAL_ERROR,                // sent if there are error conditions not covered by a more specific error code.
76     AVRCP_STATUS_SUCCESS,                       // sent if the operation was successful.
77     AVRCP_STATUS_UID_CHANGED,                   // sent if the UIDs on the device have changed.
78     AVRCP_STATUS_RESERVED_6,
79     AVRCP_STATUS_INVALID_DIRECTION,             // The Direction parameter is invalid. Valid for command: Change Path
80     AVRCP_STATUS_NOT_A_DIRECTORY,               // The UID provided does not refer to a folder item. Valid for command: Change Path
81     AVRCP_STATUS_DOES_NOT_EXIST,                // The UID provided does not refer to any currently valid. Valid for command: Change Path, PlayItem, AddToNowPlaying, GetItemAttributes
82     AVRCP_STATUS_INVALID_SCOPE,                 // The scope parameter is invalid. Valid for command: GetFolderItems, PlayItem, AddToNowPlayer, GetItemAttributes,
83     AVRCP_STATUS_RANGE_OUT_OF_BOUNDS,           // The start of range provided is not valid. Valid for command: GetFolderItems
84     AVRCP_STATUS_UID_IS_A_DIRECTORY,            // The UID provided refers to a directory, which cannot be handled by this media player. Valid for command: PlayItem, AddToNowPlaying
85     AVRCP_STATUS_MEDIA_IN_USE,                  // The media is not able to be used for this operation at this time. Valid for command: PlayItem, AddToNowPlaying
86     AVRCP_STATUS_NOW_PLAYING_LIST_FULL,         // No more items can be added to the Now Playing List. Valid for command: AddToNowPlaying
87     AVRCP_STATUS_SEARCH_NOT_SUPPORTED,          // The Browsed Media Player does not support search. Valid for command: Search
88     AVRCP_STATUS_SEARCH_IN_PROGRESS,            // A search operation is already in progress. Valid for command: Search
89     AVRCP_STATUS_INVALID_PLAYER_ID,             // The specified Player Id does not refer to a valid player. Valid for command: SetAddressedPlayer, SetBrowsedPlayer
90     AVRCP_STATUS_PLAYER_NOT_BROWSABLE,          // The Player Id supplied refers to a Media Player which does not support browsing. Valid for command: SetBrowsedPlayer
91     AVRCP_STATUS_PLAYER_NOT_ADDRESSED,          // The Player Id supplied refers to a player which is not currently addressed, and the command is not able to be performed if the player is not set as addressed. Valid for command: Search SetBrowsedPlayer
92     AVRCP_STATUS_NO_VALID_SEARCH_RESULTS,       // The Search result list does not contain valid entries, e.g. after being invalidated due to change of browsed player. Valid for command: GetFolderItems
93     AVRCP_STATUS_NO_AVAILABLE_PLAYERS,
94     AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED,       // Valid for command: Register Notification
95     AVRCP_STATUS_RESERVED                       // 0x17 - 0xFF
96 } avrcp_status_code_t;
97 
98 typedef enum {
99     AVRCP_SINGLE_PACKET= 0,
100     AVRCP_START_PACKET    ,
101     AVRCP_CONTINUE_PACKET ,
102     AVRCP_END_PACKET
103 } avrcp_packet_type_t;
104 
105 typedef enum {
106     AVRCP_COMMAND_FRAME = 0,
107     AVRCP_RESPONSE_FRAME
108 } avrcp_frame_type_t;
109 
110 
111 typedef enum {
112     AVRCP_CAPABILITY_ID_COMPANY = 0x02,
113     AVRCP_CAPABILITY_ID_EVENT = 0x03
114 } avrcp_capability_id_t;
115 
116 typedef enum {
117     AVRCP_MEDIA_ATTR_ALL = 0x0000,
118     AVRCP_MEDIA_ATTR_TITLE,
119     AVRCP_MEDIA_ATTR_ARTIST,
120     AVRCP_MEDIA_ATTR_ALBUM,
121     AVRCP_MEDIA_ATTR_TRACK,
122     AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS,
123     AVRCP_MEDIA_ATTR_GENRE,
124     AVRCP_MEDIA_ATTR_SONG_LENGTH_MS,
125     AVRCP_MEDIA_ATTR_DEFAULT_COVER_ART,
126     AVRCP_MEDIA_ATTR_NONE = 0x7FFF
127 } avrcp_media_attribute_id_t;
128 
129 typedef enum {
130     AVRCP_PDU_ID_GET_CAPABILITIES = 0x10,
131     AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue = 0x13,
132     AVRCP_PDU_ID_SetPlayerApplicationSettingValue = 0x14,
133     AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES = 0x20,
134     AVRCP_PDU_ID_GET_PLAY_STATUS = 0x30,
135     AVRCP_PDU_ID_REGISTER_NOTIFICATION = 0x31,
136     AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE = 0x40,
137     AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE = 0x41,
138     AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME = 0x50,
139     AVRCP_PDU_ID_SET_ADDRESSED_PLAYER = 0x60,
140     AVRCP_PDU_ID_SET_BROWSED_PLAYER = 0x70,
141     AVRCP_PDU_ID_GET_FOLDER_ITEMS = 0x71,
142     AVRCP_PDU_ID_CHANGE_PATH = 0x72,
143     AVRCP_PDU_ID_GET_ITEM_ATTRIBUTES = 0x73,
144     AVRCP_PDU_ID_PLAY_ITEM = 0x74,
145     AVRCP_PDU_ID_GET_TOTAL_NUMBER_OF_ITEMS = 0x75,
146     AVRCP_PDU_ID_SEARCH = 0x80,
147     AVRCP_PDU_ID_ADD_TO_NOW_PLAYING = 0x90,
148     AVRCP_PDU_ID_GENERAL_REJECT = 0xA0,
149 
150     AVRCP_PDU_ID_UNDEFINED = 0xFF
151 } avrcp_pdu_id_t;
152 
153 typedef enum {
154     AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED = 0x01,            // Change in playback status of the current track.
155     AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED = 0x02,                      // Change of current track
156     AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END = 0x03,                  // Reached end of a track
157     AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START = 0x04,                // Reached start of a track
158     AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED = 0x05,               // Change in playback position. Returned after the specified playback notification change notification interval
159     AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED = 0x06,                // Change in battery status
160     AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED = 0x07,              // Change in system status
161     AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED = 0x08, // Change in player application setting
162     AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED = 0x09,        // The content of the Now Playing list has changed, see 6.9.5.
163     AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED = 0x0a,          // The available players have changed, see 6.9.4.
164     AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED = 0x0b,           // The Addressed Player has been changed, see 6.9.2.
165     AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED = 0x0c,                       // The UIDs have changed, see 6.10.3.3.
166     AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED = 0x0d,                     // The volume has been changed locally on the TG, see 6.13.3.
167     AVRCP_NOTIFICATION_EVENT_MAX_VALUE = 0x0e
168 } avrcp_notification_event_id_t;
169 
170 
171 // control command response: accepted, rejected, interim
172 // status  command response: not implemented, rejected, in transition, stable
173 // notify  command response: not implemented, rejected, changed
174 
175 typedef enum {
176     AVRCP_CTYPE_CONTROL = 0,
177     AVRCP_CTYPE_STATUS,
178     AVRCP_CTYPE_SPECIFIC_INQUIRY,
179     AVRCP_CTYPE_NOTIFY,
180     AVRCP_CTYPE_GENERAL_INQUIRY,
181     AVRCP_CTYPE_RESERVED5,
182     AVRCP_CTYPE_RESERVED6,
183     AVRCP_CTYPE_RESERVED7,
184     AVRCP_CTYPE_RESPONSE_NOT_IMPLEMENTED = 8,
185     AVRCP_CTYPE_RESPONSE_ACCEPTED,
186     AVRCP_CTYPE_RESPONSE_REJECTED,
187     AVRCP_CTYPE_RESPONSE_IN_TRANSITION, // target state is in transition. A subsequent STATUS command, may result in the return of a STABLE status
188     AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE,
189     AVRCP_CTYPE_RESPONSE_CHANGED_STABLE,
190     AVRCP_CTYPE_RESPONSE_RESERVED,
191     AVRCP_CTYPE_RESPONSE_INTERIM            // target is unable to respond with either ACCEPTED or REJECTED within 100 millisecond
192 } avrcp_command_type_t;
193 
194 typedef enum {
195     AVRCP_SUBUNIT_TYPE_MONITOR = 0,
196     AVRCP_SUBUNIT_TYPE_AUDIO = 1,
197     AVRCP_SUBUNIT_TYPE_PRINTER,
198     AVRCP_SUBUNIT_TYPE_DISC,
199     AVRCP_SUBUNIT_TYPE_TAPE_RECORDER_PLAYER,
200     AVRCP_SUBUNIT_TYPE_TUNER,
201     AVRCP_SUBUNIT_TYPE_CA,
202     AVRCP_SUBUNIT_TYPE_CAMERA,
203     AVRCP_SUBUNIT_TYPE_RESERVED,
204     AVRCP_SUBUNIT_TYPE_PANEL = 9,
205     AVRCP_SUBUNIT_TYPE_BULLETIN_BOARD,
206     AVRCP_SUBUNIT_TYPE_CAMERA_STORAGE,
207     AVRCP_SUBUNIT_TYPE_VENDOR_UNIQUE = 0x1C,
208     AVRCP_SUBUNIT_TYPE_RESERVED_FOR_ALL_SUBUNIT_TYPES,
209     AVRCP_SUBUNIT_TYPE_EXTENDED_TO_NEXT_BYTE, // The unit_type field may take value 1E16, which means that the field is extended to the following byte. In that case, an additional byte for extended_unit_type will be added immediately following operand[1].
210                                               // Further extension is possible when the value of extended_unit_type is FF16, in which case another byte will be added.
211     AVRCP_SUBUNIT_TYPE_UNIT = 0x1F
212 } avrcp_subunit_type_t;
213 
214 typedef enum {
215     AVRCP_SUBUNIT_ID = 0,
216     AVRCP_SUBUNIT_ID_IGNORE = 7
217 } avrcp_subunit_id_t;
218 
219 typedef enum {
220     AVRCP_CMD_OPCODE_VENDOR_DEPENDENT = 0x00,
221     // AVRCP_CMD_OPCODE_RESERVE = 0x01,
222     AVRCP_CMD_OPCODE_UNIT_INFO = 0x30,
223     AVRCP_CMD_OPCODE_SUBUNIT_INFO = 0x31,
224     AVRCP_CMD_OPCODE_PASS_THROUGH = 0x7C,
225     // AVRCP_CMD_OPCODE_VERSION = 0xB0,
226     // AVRCP_CMD_OPCODE_POWER = 0xB2,
227     AVRCP_CMD_OPCODE_UNDEFINED = 0xFF
228 } avrcp_command_opcode_t;
229 
230 typedef enum {
231     AVRCP_OPERATION_ID_CHANNEL_UP = 0x30,
232     AVRCP_OPERATION_ID_CHANNEL_DOWN = 0x31,
233     AVRCP_OPERATION_ID_SELECT = 0x00,
234     AVRCP_OPERATION_ID_UP = 0x01,
235     AVRCP_OPERATION_ID_DOWN = 0x02,
236     AVRCP_OPERATION_ID_LEFT = 0x03,
237     AVRCP_OPERATION_ID_RIGHT = 0x04,
238     AVRCP_OPERATION_ID_ROOT_MENU = 0x09,
239 
240     AVRCP_OPERATION_ID_SKIP = 0x3C,
241     AVRCP_OPERATION_ID_VOLUME_UP = 0x41,
242     AVRCP_OPERATION_ID_VOLUME_DOWN = 0x42,
243     AVRCP_OPERATION_ID_MUTE = 0x43,
244 
245     AVRCP_OPERATION_ID_PLAY = 0x44,
246     AVRCP_OPERATION_ID_STOP = 0x45,
247     AVRCP_OPERATION_ID_PAUSE = 0x46,
248     AVRCP_OPERATION_ID_REWIND = 0x48,
249     AVRCP_OPERATION_ID_FAST_FORWARD = 0x49,
250     AVRCP_OPERATION_ID_FORWARD = 0x4B,
251     AVRCP_OPERATION_ID_BACKWARD = 0x4C,
252     AVRCP_OPERATION_ID_UNDEFINED = 0xFF
253 } avrcp_operation_id_t;
254 
255 typedef enum{
256     AVRCP_PLAYBACK_STATUS_STOPPED = 0x00,
257     AVRCP_PLAYBACK_STATUS_PLAYING,
258     AVRCP_PLAYBACK_STATUS_PAUSED,
259     AVRCP_PLAYBACK_STATUS_FWD_SEEK,
260     AVRCP_PLAYBACK_STATUS_REV_SEEK,
261     AVRCP_PLAYBACK_STATUS_ERROR = 0xFF
262 } avrcp_playback_status_t;
263 
264 typedef enum {
265     AVRCP_BATTERY_STATUS_NORMAL = 0x00, // Battery operation is in normal state
266     AVRCP_BATTERY_STATUS_WARNING,       // unable to operate soon. Is provided when the battery level is going down.
267     AVRCP_BATTERY_STATUS_CRITICAL,      // can not operate any more. Is provided when the battery level is going down.
268     AVRCP_BATTERY_STATUS_EXTERNAL,      // Plugged to external power supply
269     AVRCP_BATTERY_STATUS_FULL_CHARGE    // when the device is completely charged from the external power supply
270 } avrcp_battery_status_t;
271 
272 typedef enum {
273     AVRCP_SYSTEM_STATUS_POWER_ON = 0x00,
274     AVRCP_SYSTEM_STATUS_POWER_OFF,
275     AVRCP_SYSTEM_STATUS_UNPLUGGED
276 } avrcp_system_status_t;
277 
278 typedef enum {
279     AVRCP_PLAYER_APPLICATION_SETTING_ATTRIBUTE_ID_ILLEGAL = 0x00,       // ValueIDs with descriptions:
280     AVRCP_PLAYER_APPLICATION_SETTING_ATTRIBUTE_ID_EQUALIZER_STATUS,     // 1 - off, 2 - on
281     AVRCP_PLAYER_APPLICATION_SETTING_ATTRIBUTE_ID_REPEAT_MODE_STATUS,   // 1 - off, 2 - single track repeat, 3 - all tracks repeat, 4 - group repeat
282     AVRCP_PLAYER_APPLICATION_SETTING_ATTRIBUTE_ID_SHUFFLE_STATUS,       // 1 - off, 2 - all tracks shuffle , 3 - group shuffle
283     AVRCP_PLAYER_APPLICATION_SETTING_ATTRIBUTE_ID_SCAN_STATUS           // 1 - off, 2 - all tracks scan    , 3 - group scan
284 } avrcp_player_application_setting_attribute_id_t;
285 
286 typedef enum {
287     AVCTP_CONNECTION_IDLE,
288     AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE,
289     AVCTP_CONNECTION_W4_ERTM_CONFIGURATION,
290     AVCTP_CONNECTION_W4_L2CAP_CONNECTED,
291     AVCTP_CONNECTION_W2_L2CAP_RECONNECT,
292     AVCTP_CONNECTION_OPENED,
293     AVCTP_W2_SEND_PRESS_COMMAND,
294     AVCTP_W2_SEND_RELEASE_COMMAND,
295     AVCTP_W4_STOP,
296     AVCTP_W2_SEND_COMMAND,
297     AVCTP_W2_SEND_RESPONSE,
298     AVCTP_W2_RECEIVE_PRESS_RESPONSE,
299     AVCTP_W2_RECEIVE_RESPONSE,
300     AVCTP_W2_SEND_FRAGMENTED_COMMAND,
301 } avctp_connection_state_t;
302 
303 typedef struct {
304     uint16_t len;
305     uint8_t  * value;
306 } avrcp_now_playing_info_item_t;
307 
308 typedef struct {
309     uint8_t track_id[8];
310     uint16_t track_nr;
311     char * title;
312     char * artist;
313     char * album;
314     char * genre;
315     uint32_t song_length_ms;
316     uint32_t song_position_ms;
317 } avrcp_track_t;
318 
319 typedef enum {
320     AVRCP_PARSER_GET_ATTRIBUTE_HEADER = 0,       // 8 bytes
321     AVRCP_PARSER_GET_ATTRIBUTE_VALUE,
322     AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE
323 } avrcp_parser_state_t;
324 
325 
326 typedef enum{
327     AVRCP_CONTROLLER = 0,
328     AVRCP_TARGET
329 } avrcp_role_t;
330 
331 typedef enum {
332     AVRCP_SHUFFLE_MODE_INVALID,
333     AVRCP_SHUFFLE_MODE_OFF,
334     AVRCP_SHUFFLE_MODE_ALL_TRACKS,
335     AVRCP_SHUFFLE_MODE_GROUP
336 } avrcp_shuffle_mode_t;
337 
338 typedef enum {
339     AVRCP_REPEAT_MODE_INVALID,
340     AVRCP_REPEAT_MODE_OFF,
341     AVRCP_REPEAT_MODE_SINGLE_TRACK,
342     AVRCP_REPEAT_MODE_ALL_TRACKS,
343     AVRCP_REPEAT_MODE_GROUP
344 } avrcp_repeat_mode_t;
345 
346 typedef enum {
347     RFC2978_CHARSET_MIB_UTF8 = 106
348 } rfc2978_charset_mib_enumid_t;
349 
350 typedef enum {
351     AVRCP_BROWSING_MEDIA_PLAYER_LIST = 0x00,
352     AVRCP_BROWSING_MEDIA_PLAYER_VIRTUAL_FILESYSTEM,
353     AVRCP_BROWSING_SEARCH,
354     AVRCP_BROWSING_NOW_PLAYING
355 } avrcp_browsing_scope_t;
356 
357 
358 
359 
360 // BROWSING
361 typedef struct {
362     uint16_t l2cap_browsing_cid;
363 
364     avctp_connection_state_t state;
365     bool     wait_to_send;
366     uint8_t  transaction_label;
367     // used for AVCTP fragmentation
368     uint8_t  num_packets;
369     uint16_t bytes_to_send;
370 
371     uint8_t *ertm_buffer;
372     uint32_t ertm_buffer_size;
373     l2cap_ertm_config_t ertm_config;
374 
375     // players
376     uint8_t  set_browsed_player_id;
377     uint16_t browsed_player_id;
378 
379     avrcp_browsing_scope_t  scope;
380     uint8_t  folder_uid[8]; // or media element
381     uint16_t uid_counter;
382 
383     // get folder item
384     uint8_t  get_folder_items;
385     uint32_t start_item;
386     uint32_t end_item;
387     uint32_t attr_bitmap;
388 
389     // item attrs
390     uint8_t get_item_attributes;
391 
392     // change_path
393     uint8_t  change_path;
394     uint8_t  direction;
395 
396     // search str
397     uint16_t search_str_len;
398     uint8_t  search_str[20];
399     uint8_t  search;
400 
401     // get_item_attributes
402     uint8_t  get_total_nr_items;
403     avrcp_browsing_scope_t get_total_nr_items_scope;
404 
405     avrcp_pdu_id_t pdu_id;
406     uint8_t browsing_status;
407     uint16_t num_items;
408 
409     avrcp_parser_state_t parser_state;
410     uint8_t  parser_attribute_header[AVRCP_BROWSING_ITEM_HEADER_LEN];
411     uint8_t  parser_attribute_header_pos;
412     uint8_t  parsed_attribute_value[AVRCP_MAX_ATTRIBUTTE_SIZE];
413     uint16_t parsed_attribute_value_len;
414     uint16_t parsed_attribute_value_offset;
415     uint8_t  parsed_num_attributes;
416 
417     // get folder items data
418     uint8_t * attr_list;
419     uint16_t attr_list_size;
420     // command
421     // uint8_t transaction_label;
422     avrcp_command_opcode_t command_opcode;
423     avrcp_command_type_t command_type;
424     avrcp_subunit_type_t subunit_type;
425     avrcp_subunit_id_t   subunit_id;
426     avrcp_packet_type_t  packet_type;
427     uint8_t cmd_operands[200];
428     uint8_t cmd_operands_length;
429 
430     bool incoming_declined;
431 } avrcp_browsing_connection_t;
432 
433 typedef struct {
434     btstack_linked_item_t    item;
435 
436     avrcp_role_t role;
437     bd_addr_t remote_addr;
438     uint16_t avrcp_l2cap_psm;
439     uint16_t l2cap_signaling_cid;
440     uint16_t l2cap_mtu;
441     uint16_t avrcp_cid;
442     bool incoming_declined;
443 
444     uint16_t avrcp_browsing_cid;
445     uint16_t browsing_l2cap_psm;
446     uint16_t browsing_version;
447 
448     avrcp_browsing_connection_t * browsing_connection;
449 
450     avctp_connection_state_t state;
451     bool wait_to_send;
452 
453     // PID check
454     uint8_t reject_transport_header;
455     uint8_t transport_header;
456     uint16_t invalid_pid;
457 
458     // command
459     uint8_t transaction_label;
460     avrcp_command_opcode_t command_opcode;
461     avrcp_command_type_t command_type;
462     avrcp_subunit_type_t subunit_type;
463     avrcp_subunit_id_t   subunit_id;
464     avrcp_packet_type_t  packet_type;
465 
466     // regular commands
467     uint8_t cmd_operands[20];
468     uint8_t cmd_operands_length;
469 
470     // long/fragmented commands
471     const uint8_t * cmd_operands_fragmented_buffer;
472     uint16_t  cmd_operands_fragmented_pos;
473     uint16_t  cmd_operands_fragmented_len;
474 
475     btstack_timer_source_t reconnect_timer;
476     btstack_timer_source_t press_and_hold_cmd_timer;
477     uint8_t  continuous_fast_forward_cmd;
478     uint16_t notifications_enabled;
479     uint16_t notifications_to_register;
480     uint16_t notifications_to_deregister;
481     uint8_t  notifications_transaction_label[AVRCP_NOTIFICATION_EVENT_MAX_VALUE+1];
482 
483     avrcp_subunit_type_t unit_type;
484     uint32_t company_id;
485     avrcp_subunit_type_t subunit_info_type;
486     const uint8_t * subunit_info_data;
487     uint16_t subunit_info_data_size;
488 
489     avrcp_now_playing_info_item_t now_playing_info[AVRCP_MEDIA_ATTR_COUNT];
490     uint8_t  track_id[8];
491     uint32_t song_length_ms;
492     uint32_t song_position_ms;
493     int total_tracks;
494     int track_nr;
495     uint8_t track_selected;
496     uint8_t track_changed;
497 
498     avrcp_playback_status_t playback_status;
499     uint8_t playback_status_changed;
500 
501     uint8_t playing_content_changed;
502 
503     avrcp_battery_status_t battery_status;
504     uint8_t battery_status_changed;
505     uint8_t volume_percentage;
506     uint8_t notify_volume_percentage_changed;
507 
508     uint8_t now_playing_info_response;
509     uint8_t now_playing_info_attr_bitmap;
510     uint8_t abort_continue_response;
511 
512     // used for fragmentation
513     avrcp_media_attribute_id_t next_attr_id;
514 
515     avrcp_parser_state_t parser_state;
516     uint8_t  parser_attribute_header[AVRCP_ATTRIBUTE_HEADER_LEN];
517     uint8_t  parser_attribute_header_pos;
518 
519     uint16_t list_size;
520     uint16_t list_offset;
521     uint8_t  attribute_value[AVRCP_MAX_ATTRIBUTTE_SIZE];
522     uint16_t attribute_value_len;
523     uint16_t attribute_value_offset;
524 
525     uint32_t attribute_id;
526 
527     uint8_t  num_attributes;
528     uint8_t  num_parsed_attributes;
529 
530     uint8_t addressed_player_changed;
531     uint16_t addressed_player_id;
532     uint16_t uid_counter;
533     // PTS requires definition of max num fragments
534     uint8_t max_num_fragments;
535     uint8_t num_received_fragments;
536 
537     uint8_t accept_response;
538 } avrcp_connection_t;
539 
540 typedef struct {
541     avrcp_role_t role;
542     btstack_packet_handler_t avrcp_callback;
543     btstack_packet_handler_t packet_handler;
544 
545     bool (*set_addressed_player_callback)(uint16_t player_id);
546 
547     btstack_packet_handler_t browsing_avrcp_callback;
548     btstack_packet_handler_t browsing_packet_handler;
549 
550     // SDP query
551     bd_addr_t remote_addr;
552     uint8_t  parse_sdp_record;
553     uint32_t record_id;
554     uint16_t avrcp_cid;
555     uint16_t avrcp_l2cap_psm;
556     uint16_t avrcp_version;
557 
558     uint16_t browsing_l2cap_psm;
559     uint16_t browsing_version;
560 } avrcp_context_t;
561 
562 
563 const char * avrcp_subunit2str(uint16_t index);
564 const char * avrcp_event2str(uint16_t index);
565 const char * avrcp_operation2str(uint8_t index);
566 const char * avrcp_attribute2str(uint8_t index);
567 const char * avrcp_play_status2str(uint8_t index);
568 const char * avrcp_ctype2str(uint8_t index);
569 const char * avrcp_repeat2str(uint8_t index);
570 const char * avrcp_shuffle2str(uint8_t index);
571 
572 
573 void avrcp_register_controller_packet_handler(btstack_packet_handler_t avrcp_controller_packet_handler);
574 void avrcp_register_target_packet_handler(btstack_packet_handler_t avrcp_target_packet_handler);
575 
576 uint8_t avrcp_cmd_opcode(uint8_t *packet, uint16_t size);
577 
578 avrcp_connection_t * get_avrcp_connection_for_l2cap_signaling_cid_for_role(avrcp_role_t role, uint16_t l2cap_cid);
579 avrcp_connection_t * get_avrcp_connection_for_avrcp_cid_for_role(avrcp_role_t role, uint16_t avrcp_cid);
580 avrcp_connection_t * get_avrcp_connection_for_bd_addr_for_role(avrcp_role_t role, bd_addr_t addr);
581 
582 avrcp_connection_t * get_avrcp_connection_for_browsing_cid_for_role(avrcp_role_t role, uint16_t browsing_cid);
583 avrcp_connection_t * get_avrcp_connection_for_browsing_l2cap_cid_for_role(avrcp_role_t role, uint16_t browsing_l2cap_cid);
584 avrcp_browsing_connection_t * get_avrcp_browsing_connection_for_l2cap_cid_for_role(avrcp_role_t role, uint16_t l2cap_cid);
585 
586 void avrcp_request_can_send_now(avrcp_connection_t * connection, uint16_t l2cap_cid);
587 uint16_t avrcp_get_next_cid(avrcp_role_t role);
588 
589 uint8_t avrcp_start_sdp_query(btstack_packet_handler_t packet_handler, const uint8_t *remote_addr, uint16_t cid);
590 uint16_t avrcp_sdp_sdp_query_browsing_l2cap_psm(void);
591 void avrcp_handle_sdp_client_query_attribute_value(uint8_t *packet);
592 avrcp_connection_t * get_avrcp_connection_for_browsing_cid_for_role(avrcp_role_t role, uint16_t browsing_cid);
593 avrcp_connection_t * get_avrcp_connection_for_browsing_l2cap_cid_for_role(avrcp_role_t role, uint16_t browsing_l2cap_cid);
594 avrcp_browsing_connection_t * get_avrcp_browsing_connection_for_l2cap_cid_for_role(avrcp_role_t role, uint16_t l2cap_cid);
595 // SDP query
596 void    avrcp_create_sdp_record(uint8_t controller, uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name);
597 
598 
599 /* API_START */
600 
601 /**
602  * @brief Set up AVRCP service
603  */
604 void avrcp_init(void);
605 
606 /**
607  * @brief Register callback for the AVRCP Controller client.
608  * @param callback
609  */
610 void avrcp_register_packet_handler(btstack_packet_handler_t callback);
611 
612 /**
613  * @brief   Connect to AVRCP service on a remote device, emits AVRCP_SUBEVENT_CONNECTION_ESTABLISHED with status
614  * @param   remote_addr
615  * @param   avrcp_cid  outgoing parameter, valid if status == ERROR_CODE_SUCCESS
616  * @returns status
617  */
618 uint8_t avrcp_connect(bd_addr_t remote_addr, uint16_t * avrcp_cid);
619 
620 /**
621  * @brief   Disconnect from AVRCP service
622  * @param   avrcp_cid
623  * @returns status
624  */
625 uint8_t avrcp_disconnect(uint16_t avrcp_cid);
626 
627 /**
628  * @brief Set up AVRCP Browsing service
629  */
630 void avrcp_browsing_init(void);
631 
632 /**
633  * @brief Register callback for the AVRCP Browsing Controller client.
634  * @param callback
635  */
636 void avrcp_browsing_register_packet_handler(btstack_packet_handler_t callback);
637 
638 /**
639  * @brief   Connect to AVRCP Browsing service on a remote device, emits AVRCP_SUBEVENT_BROWSING_CONNECTION_ESTABLISHED with status
640  * @param   remote_addr
641  * @param   ertm_buffer
642  * @param   ertm_buffer_size
643  * @param   ertm_config
644  * @param   avrcp_browsing_cid  outgoing parameter, valid if status == ERROR_CODE_SUCCESS
645  * @returns status
646  */
647 uint8_t avrcp_browsing_connect(bd_addr_t remote_addr, uint8_t * ertm_buffer, uint32_t ertm_buffer_size, l2cap_ertm_config_t * ertm_config, uint16_t * avrcp_browsing_cid);
648 
649 /**
650  * @brief Configure incoming connection for Browsing Service.
651  * @param avrcp_browsing_cid
652  * @param ertm_buffer
653  * @param ertm_buffer_size
654  * @param ertm_config
655  * @returns status
656  */
657 uint8_t avrcp_browsing_configure_incoming_connection(uint16_t avrcp_browsing_cid, uint8_t * ertm_buffer, uint32_t ertm_buffer_size, l2cap_ertm_config_t * ertm_config);
658 
659 /**
660  * @brief Decline incoming connection Browsing Service.
661  * @param avrcp_browsing_cid
662  * @returns status
663  */
664 uint8_t avrcp_browsing_decline_incoming_connection(uint16_t avrcp_browsing_cid);
665 
666 /**
667  * @brief   Disconnect from AVRCP Browsing service
668  * @param   avrcp_browsing_cid
669  * @returns status
670  */
671 uint8_t avrcp_browsing_disconnect(uint16_t avrcp_browsing_cid);
672 
673 /* API_END */
674 
675 void avrcp_browsing_register_controller_packet_handler(btstack_packet_handler_t callback);
676 void avrcp_browsing_register_target_packet_handler(btstack_packet_handler_t callback);
677 void avrcp_browsing_request_can_send_now(avrcp_browsing_connection_t * connection, uint16_t l2cap_cid);
678 
679 #if defined __cplusplus
680 }
681 #endif
682 
683 #endif // AVRCP_H
684