xref: /btstack/src/classic/avrcp.c (revision b397c740f56f5937fa7fa5a169ff9b66feef6779)
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 #define __BTSTACK_FILE__ "avrcp.c"
39 
40 #include <stdint.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 
45 #include "btstack.h"
46 #include "classic/avrcp.h"
47 
48 #define AV_REMOTE_CONTROL_TARGET        0x110C
49 #define AV_REMOTE_CONTROL               0x110E
50 #define AV_REMOTE_CONTROL_CONTROLLER    0x110F
51 
52 #define PSM_AVCTP                       BLUETOOTH_PROTOCOL_AVCTP
53 #define PSM_AVCTP_BROWSING              0xFF17
54 
55 /*
56 Category 1: Player/Recorder
57 Category 2: Monitor/Amplifier
58 Category 3: Tuner
59 Category 4: Menu
60 */
61 
62 /* controller supported features
63 Bit 0 = Category 1
64 Bit 1 = Category 2
65 Bit 2 = Category 3
66 Bit 3 = Category 4
67 Bit 4-5 = RFA
68 Bit 6 = Supports browsing
69 Bit 7-15 = RFA
70 The bits for supported categories are set to 1. Others are set to 0.
71 */
72 
73 /* target supported features
74 Bit 0 = Category 1
75 Bit 1 = Category 2
76 Bit 2 = Category 3
77 Bit 3 = Category 4
78 Bit 4 = Player Application Settings. Bit 0 should be set for this bit to be set.
79 Bit 5 = Group Navigation. Bit 0 should be set for this bit to be set.
80 Bit 6 = Supports browsing*4
81 Bit 7 = Supports multiple media player applications
82 Bit 8-15 = RFA
83 The bits for supported categories are set to 1. Others are set to 0.
84 */
85 
86 // TODO: merge with avdtp_packet_type_t
87 typedef enum {
88     AVRCP_SINGLE_PACKET= 0,
89     AVRCP_START_PACKET    ,
90     AVRCP_CONTINUE_PACKET ,
91     AVRCP_END_PACKET
92 } avrcp_packet_type_t;
93 
94 typedef enum {
95     AVRCP_COMMAND_FRAME = 0,
96     AVRCP_RESPONSE_FRAME
97 } avrcp_frame_type_t;
98 
99 static const char * default_avrcp_controller_service_name = "BTstack AVRCP Controller Service";
100 static const char * default_avrcp_controller_service_provider_name = "BTstack AVRCP Controller Service Provider";
101 static const char * default_avrcp_target_service_name = "BTstack AVRCP Target Service";
102 static const char * default_avrcp_target_service_provider_name = "BTstack AVRCP Target Service Provider";
103 
104 static btstack_linked_list_t avrcp_connections;
105 static btstack_packet_handler_t avrcp_callback;
106 
107 static const char * avrcp_subunit_type_name[] = {
108     "MONITOR", "AUDIO", "PRINTER", "DISC", "TAPE_RECORDER_PLAYER", "TUNER",
109     "CA", "CAMERA", "RESERVED", "PANEL", "BULLETIN_BOARD", "CAMERA_STORAGE",
110     "VENDOR_UNIQUE", "RESERVED_FOR_ALL_SUBUNIT_TYPES",
111     "EXTENDED_TO_NEXT_BYTE", "UNIT", "ERROR"
112 };
113 const char * avrcp_subunit2str(uint16_t index){
114     if (index <= 11) return avrcp_subunit_type_name[index];
115     if (index >= 0x1C && index <= 0x1F) return avrcp_subunit_type_name[index - 0x10];
116     return avrcp_subunit_type_name[16];
117 }
118 
119 static const char * avrcp_event_name[] = {
120     "ERROR", "PLAYBACK_STATUS_CHANGED",
121     "TRACK_CHANGED", "TRACK_REACHED_END", "TRACK_REACHED_START",
122     "PLAYBACK_POS_CHANGED", "BATT_STATUS_CHANGED", "SYSTEM_STATUS_CHANGED",
123     "PLAYER_APPLICATION_SETTING_CHANGED", "NOW_PLAYING_CONTENT_CHANGED",
124     "AVAILABLE_PLAYERS_CHANGED", "ADDRESSED_PLAYER_CHANGED", "UIDS_CHANGED", "VOLUME_CHANGED"
125 };
126 const char * avrcp_event2str(uint16_t index){
127     if (index <= 0x0d) return avrcp_event_name[index];
128     return avrcp_event_name[0];
129 }
130 
131 static const char * avrcp_operation_name[] = {
132     "NOT SUPPORTED", // 0x3B
133     "SKIP", "NOT SUPPORTED", "NOT SUPPORTED", "NOT SUPPORTED", "NOT SUPPORTED",
134     "VOLUME_UP", "VOLUME_DOWN", "MUTE", "PLAY", "STOP", "PAUSE", "NOT SUPPORTED",
135     "REWIND", "FAST_FORWARD", "NOT SUPPORTED", "FORWARD", "BACKWARD" // 0x4C
136 };
137 const char * avrcp_operation2str(uint8_t index){
138     if (index >= 0x3B && index <= 0x4C) return avrcp_operation_name[index - 0x3B];
139     return avrcp_operation_name[0];
140 }
141 
142 static const char * avrcp_media_attribute_id_name[] = {
143     "NONE", "TITLE", "ARTIST", "ALBUM", "TRACK", "TOTAL TRACKS", "GENRE", "SONG LENGTH"
144 };
145 const char * avrcp_attribute2str(uint8_t index){
146     if (index >= 1 && index <= 7) return avrcp_media_attribute_id_name[index];
147     return avrcp_media_attribute_id_name[0];
148 }
149 
150 static const char * avrcp_play_status_name[] = {
151     "STOPPED", "PLAYING", "PAUSED", "FORWARD SEEK", "REVERSE SEEK",
152     "ERROR" // 0xFF
153 };
154 const char * avrcp_play_status2str(uint8_t index){
155     if (index >= 1 && index <= 4) return avrcp_play_status_name[index];
156     return avrcp_play_status_name[5];
157 }
158 
159 static const char * avrcp_ctype_name[] = {
160     "CONTROL",
161     "STATUS",
162     "SPECIFIC_INQUIRY",
163     "NOTIFY",
164     "GENERAL_INQUIRY",
165     "RESERVED5",
166     "RESERVED6",
167     "RESERVED7",
168     "NOT IMPLEMENTED IN REMOTE",
169     "ACCEPTED BY REMOTE",
170     "REJECTED BY REMOTE",
171     "IN_TRANSITION",
172     "IMPLEMENTED_STABLE",
173     "CHANGED_STABLE",
174     "RESERVED",
175     "INTERIM"
176 };
177 const char * avrcp_ctype2str(uint8_t index){
178     if (index < sizeof(avrcp_ctype_name)){
179         return avrcp_ctype_name[index];
180     }
181     return "NONE";
182 }
183 
184 static const char * avrcp_shuffle_mode_name[] = {
185     "SHUFFLE OFF",
186     "SHUFFLE ALL TRACKS",
187     "SHUFFLE GROUP"
188 };
189 
190 const char * avrcp_shuffle2str(uint8_t index){
191     if (index >= 1 && index <= 3) return avrcp_shuffle_mode_name[index-1];
192     return "NONE";
193 }
194 
195 static const char * avrcp_repeat_mode_name[] = {
196     "REPEAT OFF",
197     "REPEAT SINGLE TRACK",
198     "REPEAT ALL TRACKS",
199     "REPEAT GROUP"
200 };
201 
202 const char * avrcp_repeat2str(uint8_t index){
203     if (index >= 1 && index <= 4) return avrcp_repeat_mode_name[index-1];
204     return "NONE";
205 }
206 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
207 
208 static 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){
209     uint8_t* attribute;
210     de_create_sequence(service);
211 
212     // 0x0000 "Service Record Handle"
213     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
214     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
215 
216     // 0x0001 "Service Class ID List"
217     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
218     attribute = de_push_sequence(service);
219     {
220         if (controller){
221             de_add_number(attribute, DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL);
222             de_add_number(attribute, DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL_CONTROLLER);
223         } else {
224             de_add_number(attribute, DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL_TARGET);
225         }
226     }
227     de_pop_sequence(service, attribute);
228 
229     // 0x0004 "Protocol Descriptor List"
230     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
231     attribute = de_push_sequence(service);
232     {
233         uint8_t* l2cpProtocol = de_push_sequence(attribute);
234         {
235             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
236             de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVCTP);
237         }
238         de_pop_sequence(attribute, l2cpProtocol);
239 
240         uint8_t* avctpProtocol = de_push_sequence(attribute);
241         {
242             de_add_number(avctpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVCTP);  // avctpProtocol_service
243             de_add_number(avctpProtocol,  DE_UINT, DE_SIZE_16,  0x0103);    // version
244         }
245         de_pop_sequence(attribute, avctpProtocol);
246 
247         if (browsing){
248             de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
249             attribute = de_push_sequence(service);
250             {
251                 uint8_t* browsing_l2cpProtocol = de_push_sequence(attribute);
252                 {
253                     de_add_number(browsing_l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
254                     de_add_number(browsing_l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_AVCTP_BROWSING);
255                 }
256                 de_pop_sequence(attribute, browsing_l2cpProtocol);
257 
258                 uint8_t* browsing_avctpProtocol = de_push_sequence(attribute);
259                 {
260                     de_add_number(browsing_avctpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVCTP);  // browsing_avctpProtocol_service
261                     de_add_number(browsing_avctpProtocol,  DE_UINT, DE_SIZE_16,  0x0103);    // version
262                 }
263                 de_pop_sequence(attribute, browsing_avctpProtocol);
264             }
265             de_pop_sequence(service, attribute);
266         }
267     }
268     de_pop_sequence(service, attribute);
269 
270     // 0x0005 "Public Browse Group"
271     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
272     attribute = de_push_sequence(service);
273     {
274         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT);
275     }
276     de_pop_sequence(service, attribute);
277 
278     // 0x0009 "Bluetooth Profile Descriptor List"
279     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
280     attribute = de_push_sequence(service);
281     {
282         uint8_t *avrcProfile = de_push_sequence(attribute);
283         {
284             de_add_number(avrcProfile,  DE_UUID, DE_SIZE_16, AV_REMOTE_CONTROL);
285             de_add_number(avrcProfile,  DE_UINT, DE_SIZE_16, 0x0105);
286         }
287         de_pop_sequence(attribute, avrcProfile);
288     }
289     de_pop_sequence(service, attribute);
290 
291 
292     // 0x0100 "Service Name"
293     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
294     if (service_name){
295         de_add_data(service,  DE_STRING, strlen(service_name), (uint8_t *) service_name);
296     } else {
297         if (controller){
298             de_add_data(service,  DE_STRING, strlen(default_avrcp_controller_service_name), (uint8_t *) default_avrcp_controller_service_name);
299         } else {
300             de_add_data(service,  DE_STRING, strlen(default_avrcp_target_service_name), (uint8_t *) default_avrcp_target_service_name);
301         }
302     }
303 
304     // 0x0100 "Provider Name"
305     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0102);
306     if (service_provider_name){
307         de_add_data(service,  DE_STRING, strlen(service_provider_name), (uint8_t *) service_provider_name);
308     } else {
309         if (controller){
310             de_add_data(service,  DE_STRING, strlen(default_avrcp_controller_service_provider_name), (uint8_t *) default_avrcp_controller_service_provider_name);
311         } else {
312             de_add_data(service,  DE_STRING, strlen(default_avrcp_target_service_provider_name), (uint8_t *) default_avrcp_target_service_provider_name);
313         }
314     }
315 
316     // 0x0311 "Supported Features"
317     de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311);
318     de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
319 }
320 
321 void avrcp_controller_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name){
322     avrcp_create_sdp_record(1, service, service_record_handle, browsing, supported_features, service_name, service_provider_name);
323 }
324 
325 void avrcp_target_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name){
326     avrcp_create_sdp_record(0, service, service_record_handle, browsing, supported_features, service_name, service_provider_name);
327 }
328 
329 static void avrcp_emit_connection_established(btstack_packet_handler_t callback, uint8_t status, bd_addr_t addr, uint16_t con_handle, uint16_t avrcp_cid){
330     if (!callback) return;
331     uint8_t event[14];
332     int pos = 0;
333     event[pos++] = HCI_EVENT_AVRCP_META;
334     event[pos++] = sizeof(event) - 2;
335     event[pos++] = AVRCP_SUBEVENT_CONNECTION_ESTABLISHED;
336     event[pos++] = status;
337     reverse_bd_addr(addr,&event[pos]);
338     pos += 6;
339     little_endian_store_16(event, pos, con_handle);
340     pos += 2;
341     little_endian_store_16(event, pos, avrcp_cid);
342     pos += 2;
343     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
344 }
345 
346 static void avrcp_emit_repeat_and_shuffle_mode(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t ctype, avrcp_repeat_mode_t repeat_mode, avrcp_shuffle_mode_t shuffle_mode){
347     if (!callback) return;
348     uint8_t event[8];
349     int pos = 0;
350     event[pos++] = HCI_EVENT_AVRCP_META;
351     event[pos++] = sizeof(event) - 2;
352     event[pos++] = AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE;
353     little_endian_store_16(event, pos, avrcp_cid);
354     pos += 2;
355     event[pos++] = ctype;
356     event[pos++] = repeat_mode;
357     event[pos++] = shuffle_mode;
358     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
359 }
360 
361 static void avrcp_emit_operation_status(btstack_packet_handler_t callback, uint8_t subevent, uint16_t avrcp_cid, uint8_t ctype, uint8_t operation_id){
362     if (!callback) return;
363     uint8_t event[7];
364     int pos = 0;
365     event[pos++] = HCI_EVENT_AVRCP_META;
366     event[pos++] = sizeof(event) - 2;
367     event[pos++] = subevent;
368     little_endian_store_16(event, pos, avrcp_cid);
369     pos += 2;
370     event[pos++] = ctype;
371     event[pos++] = operation_id;
372     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
373 }
374 
375 static void avrcp_emit_connection_closed(btstack_packet_handler_t callback, uint16_t avrcp_cid){
376     if (!callback) return;
377     uint8_t event[5];
378     int pos = 0;
379     event[pos++] = HCI_EVENT_AVRCP_META;
380     event[pos++] = sizeof(event) - 2;
381     event[pos++] = AVRCP_SUBEVENT_CONNECTION_RELEASED;
382     little_endian_store_16(event, pos, avrcp_cid);
383     pos += 2;
384     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
385 }
386 
387 static avrcp_connection_t * get_avrcp_connection_for_bd_addr(bd_addr_t addr){
388     btstack_linked_list_iterator_t it;
389     btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avrcp_connections);
390     while (btstack_linked_list_iterator_has_next(&it)){
391         avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it);
392         if (memcmp(addr, connection->remote_addr, 6) != 0) continue;
393         return connection;
394     }
395     return NULL;
396 }
397 
398 static avrcp_connection_t * get_avrcp_connection_for_l2cap_signaling_cid(uint16_t l2cap_cid){
399     btstack_linked_list_iterator_t it;
400     btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avrcp_connections);
401     while (btstack_linked_list_iterator_has_next(&it)){
402         avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it);
403         if (connection->l2cap_signaling_cid != l2cap_cid) continue;
404         return connection;
405     }
406     return NULL;
407 }
408 
409 static void avrcp_request_can_send_now(avrcp_connection_t * connection, uint16_t l2cap_cid){
410     connection->wait_to_send = 1;
411     l2cap_request_can_send_now_event(l2cap_cid);
412 }
413 
414 static void avrcp_press_and_hold_timeout_handler(btstack_timer_source_t * timer){
415     UNUSED(timer);
416     avrcp_connection_t * connection = btstack_run_loop_get_timer_context(timer);
417     btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
418     btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
419     connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
420     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
421 }
422 
423 static void avrcp_press_and_hold_timer_start(avrcp_connection_t * connection){
424     btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
425     btstack_run_loop_set_timer_handler(&connection->press_and_hold_cmd_timer, avrcp_press_and_hold_timeout_handler);
426     btstack_run_loop_set_timer_context(&connection->press_and_hold_cmd_timer, connection);
427     btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
428     btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
429 }
430 
431 static void avrcp_press_and_hold_timer_stop(avrcp_connection_t * connection){
432     connection->continuous_fast_forward_cmd = 0;
433     btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
434 }
435 
436 static uint8_t request_pass_through_release_control_cmd(avrcp_connection_t * connection){
437     connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
438     if (connection->continuous_fast_forward_cmd){
439         avrcp_press_and_hold_timer_stop(connection);
440     }
441     connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0];
442     connection->transaction_label++;
443     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
444     return ERROR_CODE_SUCCESS;
445 }
446 
447 static inline uint8_t request_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed, uint8_t continuous_fast_forward_cmd){
448     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
449     if (!connection){
450         log_error("avrcp: could not find a connection.");
451         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
452     }
453     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
454     connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
455     connection->command_opcode =  AVRCP_CMD_OPCODE_PASS_THROUGH;
456     connection->command_type = AVRCP_CTYPE_CONTROL;
457     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
458     connection->subunit_id =   AVRCP_SUBUNIT_ID;
459     connection->cmd_operands_length = 0;
460 
461     connection->continuous_fast_forward_cmd = continuous_fast_forward_cmd;
462     connection->cmd_operands_length = 2;
463     connection->cmd_operands[0] = opid;
464     if (playback_speed > 0){
465         connection->cmd_operands[2] = playback_speed;
466         connection->cmd_operands_length++;
467     }
468     connection->cmd_operands[1] = connection->cmd_operands_length - 2;
469 
470     if (connection->continuous_fast_forward_cmd){
471         avrcp_press_and_hold_timer_start(connection);
472     }
473 
474     connection->transaction_label++;
475     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
476     return ERROR_CODE_SUCCESS;
477 }
478 
479 static uint8_t request_single_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){
480     return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 0);
481 }
482 
483 static uint8_t request_continuous_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){
484     return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 1);
485 }
486 
487 static int avrcp_send_cmd(uint16_t cid, avrcp_connection_t * connection){
488     uint8_t command[30];
489     int pos = 0;
490     // transport header
491     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
492     command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
493     // Profile IDentifier (PID)
494     command[pos++] = AV_REMOTE_CONTROL >> 8;
495     command[pos++] = AV_REMOTE_CONTROL & 0x00FF;
496 
497     // command_type
498     command[pos++] = connection->command_type;
499     // subunit_type | subunit ID
500     command[pos++] = (connection->subunit_type << 3) | connection->subunit_id;
501     // opcode
502     command[pos++] = (uint8_t)connection->command_opcode;
503     // operands
504     memcpy(command+pos, connection->cmd_operands, connection->cmd_operands_length);
505     pos += connection->cmd_operands_length;
506 
507     return l2cap_send(cid, command, pos);
508 }
509 
510 static int avrcp_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){
511     if (connection->notifications_to_deregister & (1 << event_id)) return 0;
512     if (connection->notifications_enabled & (1 << event_id)) return 0;
513     if (connection->notifications_to_register & (1 << event_id)) return 0;
514     connection->notifications_to_register |= (1 << event_id);
515     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
516     return 1;
517 }
518 
519 static void avrcp_prepare_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){
520     connection->transaction_label++;
521     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
522     connection->command_type = AVRCP_CTYPE_NOTIFY;
523     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
524     connection->subunit_id = AVRCP_SUBUNIT_ID;
525     int pos = 0;
526     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
527     pos += 3;
528     connection->cmd_operands[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION;
529     connection->cmd_operands[pos++] = 0;                     // reserved(upper 6) | packet_type -> 0
530     big_endian_store_16(connection->cmd_operands, pos, 5);     // parameter length
531     pos += 2;
532     connection->cmd_operands[pos++] = event_id;
533     big_endian_store_32(connection->cmd_operands, pos, 0);
534     pos += 4;
535     connection->cmd_operands_length = pos;
536     // AVRCP_SPEC_V14.pdf 166
537     // answer page 61
538 }
539 
540 static uint8_t avrcp_cmd_opcode(uint8_t *packet, uint16_t size){
541     uint8_t cmd_opcode_index = 5;
542     if (cmd_opcode_index > size) return AVRCP_CMD_OPCODE_UNDEFINED;
543     return packet[cmd_opcode_index];
544 }
545 
546 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
547     uint8_t operands[20];
548     uint8_t opcode;
549     int     pos = 3;
550     // uint8_t transport_header = packet[0];
551     // uint8_t transaction_label = transport_header >> 4;
552     // uint8_t packet_type = (transport_header & 0x0F) >> 2;
553     // uint8_t frame_type = (transport_header & 0x03) >> 1;
554     // uint8_t ipid = transport_header & 0x01;
555     // uint8_t byte_value = packet[2];
556     // uint16_t pid = (byte_value << 8) | packet[2];
557 
558     avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++];
559     uint8_t byte_value = packet[pos++];
560     avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3);
561     avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t)   (byte_value & 0x07);
562     opcode = packet[pos++];
563 
564     // printf("    Transport header 0x%02x (transaction_label %d, packet_type %d, frame_type %d, ipid %d), pid 0x%4x\n",
565     //     transport_header, transaction_label, packet_type, frame_type, ipid, pid);
566     // // printf_hexdump(packet+pos, size-pos);
567 
568     uint8_t pdu_id;
569     uint16_t param_length;
570     switch (avrcp_cmd_opcode(packet,size)){
571         case AVRCP_CMD_OPCODE_UNIT_INFO:{
572             if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return;
573             connection->state = AVCTP_CONNECTION_OPENED;
574 
575             // operands:
576             memcpy(operands, packet+pos, 5);
577             uint8_t unit_type = operands[1] >> 3;
578             uint8_t unit = operands[1] & 0x07;
579             uint32_t company_id = operands[2] << 16 | operands[3] << 8 | operands[4];
580             log_info("    UNIT INFO response: ctype 0x%02x (0C), subunit_type 0x%02x (1F), subunit_id 0x%02x (07), opcode 0x%02x (30), unit_type 0x%02x, unit %d, company_id 0x%06x",
581                 ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id );
582             break;
583         }
584         case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT:
585             if (size - pos < 7) {
586                 log_error("avrcp: wrong packet size");
587                 return;
588             };
589             // operands:
590             memcpy(operands, packet+pos, 7);
591             pos += 7;
592             // uint32_t company_id = operands[0] << 16 | operands[1] << 8 | operands[2];
593             pdu_id = operands[3];
594 
595             if (connection->state != AVCTP_W2_RECEIVE_RESPONSE && pdu_id != AVRCP_PDU_ID_REGISTER_NOTIFICATION){
596                 log_info("AVRCP_CMD_OPCODE_VENDOR_DEPENDENT state %d", connection->state);
597                 return;
598             }
599             connection->state = AVCTP_CONNECTION_OPENED;
600 
601 
602             // uint8_t unit_type = operands[4] >> 3;
603             // uint8_t unit = operands[4] & 0x07;
604             param_length = big_endian_read_16(operands, 5);
605 
606             // printf("    VENDOR DEPENDENT response: ctype 0x%02x (0C), subunit_type 0x%02x (1F), subunit_id 0x%02x (07), opcode 0x%02x (30), unit_type 0x%02x, unit %d, company_id 0x%06x\n",
607             //     ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id );
608 
609             // if (ctype == AVRCP_CTYPE_RESPONSE_INTERIM) return;
610             log_info("        VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d, status %s", pdu_id, param_length, avrcp_ctype2str(ctype));
611             switch (pdu_id){
612                 case AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue:{
613                     uint8_t num_attributes = packet[pos++];
614                     int i;
615                     avrcp_repeat_mode_t  repeat_mode =  AVRCP_REPEAT_MODE_INVALID;
616                     avrcp_shuffle_mode_t shuffle_mode = AVRCP_SHUFFLE_MODE_INVALID;
617                     for (i = 0; i < num_attributes; i++){
618                         uint8_t attribute_id    = packet[pos++];
619                         uint8_t attribute_value = packet[pos++];
620                         switch (attribute_id){
621                             case 0x02:
622                                 repeat_mode = (avrcp_repeat_mode_t) attribute_value;
623                                 break;
624                             case 0x03:
625                                 shuffle_mode = (avrcp_shuffle_mode_t) attribute_value;
626                                 break;
627                             default:
628                                 break;
629                         }
630                     }
631                     avrcp_emit_repeat_and_shuffle_mode(avrcp_callback, connection->l2cap_signaling_cid, ctype, repeat_mode, shuffle_mode);
632                     break;
633                 }
634                 case AVRCP_PDU_ID_SetPlayerApplicationSettingValue:{
635                     uint8_t event[6];
636                     int offset = 0;
637                     event[offset++] = HCI_EVENT_AVRCP_META;
638                     event[offset++] = sizeof(event) - 2;
639                     event[offset++] = AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE;
640                     little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
641                     offset += 2;
642                     event[offset++] = ctype;
643                     (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
644                     break;
645                 }
646                 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME:{
647                     uint8_t event[7];
648                     int offset = 0;
649                     event[offset++] = HCI_EVENT_AVRCP_META;
650                     event[offset++] = sizeof(event) - 2;
651                     event[offset++] = AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE;
652                     little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
653                     offset += 2;
654                     event[offset++] = ctype;
655                     event[offset++] = packet[pos++];
656                     (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
657                     break;
658                 }
659                 case AVRCP_PDU_ID_GET_CAPABILITIES:{
660                     avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos++];
661                     uint8_t capability_count = packet[pos++];
662                     int i;
663                     switch (capability_id){
664                         case AVRCP_CAPABILITY_ID_COMPANY:
665                             // log_info("Supported companies %d: ", capability_count);
666                             for (i = 0; i < capability_count; i++){
667                                 uint32_t company_id = big_endian_read_24(packet, pos);
668                                 pos += 3;
669                                 log_info("  0x%06x, ", company_id);
670                             }
671                             break;
672                         case AVRCP_CAPABILITY_ID_EVENT:
673                             // log_info("Supported events %d: ", capability_count);
674                             for (i = 0; i < capability_count; i++){
675                                 uint8_t event_id = packet[pos++];
676                                 log_info("  0x%02x %s", event_id, avrcp_event2str(event_id));
677                             }
678                             break;
679                     }
680                     break;
681                 }
682                 case AVRCP_PDU_ID_GET_PLAY_STATUS:{
683                     uint32_t song_length = big_endian_read_32(packet, pos);
684                     pos += 4;
685                     uint32_t song_position = big_endian_read_32(packet, pos);
686                     pos += 4;
687                     uint8_t play_status = packet[pos];
688                     // log_info("        GET_PLAY_STATUS length 0x%04X, position 0x%04X, status %s", song_length, song_position, avrcp_play_status2str(play_status));
689 
690                     uint8_t event[15];
691                     int offset = 0;
692                     event[offset++] = HCI_EVENT_AVRCP_META;
693                     event[offset++] = sizeof(event) - 2;
694                     event[offset++] = AVRCP_SUBEVENT_PLAY_STATUS;
695                     little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
696                     offset += 2;
697                     event[offset++] = ctype;
698                     little_endian_store_32(event, offset, song_length);
699                     offset += 4;
700                     little_endian_store_32(event, offset, song_position);
701                     offset += 4;
702                     event[offset++] = play_status;
703                     (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
704                     break;
705                 }
706                 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{
707                     avrcp_notification_event_id_t  event_id = (avrcp_notification_event_id_t) packet[pos++];
708                     uint16_t event_mask = (1 << event_id);
709                     uint16_t reset_event_mask = ~event_mask;
710                     switch (ctype){
711                         case AVRCP_CTYPE_RESPONSE_INTERIM:
712                             // register as enabled
713                             connection->notifications_enabled |= event_mask;
714                             // printf("INTERIM notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled,  connection->notifications_to_register);
715                             break;
716                         case AVRCP_CTYPE_RESPONSE_CHANGED_STABLE:
717                             // received change, event is considered deregistered
718                             // we are re-enabling it automatically, if it is not
719                             // explicitly disabled
720                             connection->notifications_enabled &= reset_event_mask;
721                             if (! (connection->notifications_to_deregister & event_mask)){
722                                 avrcp_register_notification(connection, event_id);
723                                 // printf("CHANGED_STABLE notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled,  connection->notifications_to_register);
724                             } else {
725                                 connection->notifications_to_deregister &= reset_event_mask;
726                             }
727                             break;
728                         default:
729                             connection->notifications_to_register &= reset_event_mask;
730                             connection->notifications_enabled &= reset_event_mask;
731                             connection->notifications_to_deregister &= reset_event_mask;
732                             break;
733                     }
734 
735                     switch (event_id){
736                         case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:{
737                             uint8_t event[7];
738                             int offset = 0;
739                             event[offset++] = HCI_EVENT_AVRCP_META;
740                             event[offset++] = sizeof(event) - 2;
741                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED;
742                             little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
743                             offset += 2;
744                             event[offset++] = ctype;
745                             event[offset++] = packet[pos];
746                             (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
747                             break;
748                         }
749                         case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:{
750                             uint8_t event[6];
751                             int offset = 0;
752                             event[offset++] = HCI_EVENT_AVRCP_META;
753                             event[offset++] = sizeof(event) - 2;
754                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED;
755                             little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
756                             offset += 2;
757                             event[offset++] = ctype;
758                             (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
759                             break;
760                         }
761                         case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:{
762                             uint8_t event[6];
763                             int offset = 0;
764                             event[offset++] = HCI_EVENT_AVRCP_META;
765                             event[offset++] = sizeof(event) - 2;
766                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED;
767                             little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
768                             offset += 2;
769                             event[offset++] = ctype;
770                             (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
771                             break;
772                         }
773                         case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:{
774                             uint8_t event[6];
775                             int offset = 0;
776                             event[offset++] = HCI_EVENT_AVRCP_META;
777                             event[offset++] = sizeof(event) - 2;
778                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED;
779                             little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
780                             offset += 2;
781                             event[offset++] = ctype;
782                             (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
783                             break;
784                         }
785                         case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:{
786                             uint8_t event[7];
787                             int offset = 0;
788                             event[offset++] = HCI_EVENT_AVRCP_META;
789                             event[offset++] = sizeof(event) - 2;
790                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED;
791                             little_endian_store_16(event, offset, connection->l2cap_signaling_cid);
792                             offset += 2;
793                             event[offset++] = ctype;
794                             event[offset++] = packet[pos++] & 0x7F;
795                             (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
796                             break;
797                         }
798                         // case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:{
799                         //     uint8_t num_PlayerApplicationSettingAttributes = packet[pos++];
800                         //     int i;
801                         //     for (i = 0; i < num_PlayerApplicationSettingAttributes; i++){
802                         //         uint8_t PlayerApplicationSetting_AttributeID = packet[pos++];
803                         //         uint8_t PlayerApplicationSettingValueID = packet[pos++];
804                         //     }
805                         //     break;
806                         // }
807                         // case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED:
808                         //     uint16_t player_id = big_endian_read_16(packet, pos);
809                         //     pos += 2;
810                         //     uint16_t uid_counter = big_endian_read_16(packet, pos);
811                         //     pos += 2;
812                         //     break;
813                         // case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:
814                         //     uint16_t uid_counter = big_endian_read_16(packet, pos);
815                         //     pos += 2;
816                         //     break;
817                         default:
818                             log_info("avrcp: not implemented");
819                             break;
820                     }
821                     if (connection->notifications_to_register != 0){
822                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
823                     }
824                     break;
825                 }
826 
827                 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{
828                     uint8_t num_attributes = packet[pos++];
829                     int i;
830                     struct item {
831                         uint16_t len;
832                         uint8_t  * value;
833                     } items[AVRCP_MEDIA_ATTR_COUNT];
834                     memset(items, 0, sizeof(items));
835 
836                     uint16_t string_attributes_len = 0;
837                     uint8_t  num_string_attributes = 0;
838                     uint16_t total_event_payload_for_string_attributes = HCI_EVENT_PAYLOAD_SIZE-2;
839                     uint16_t max_string_attribute_value_len = 0;
840                     if (ctype == AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE || ctype == AVRCP_CTYPE_RESPONSE_CHANGED_STABLE){
841                         for (i = 0; i < num_attributes; i++){
842                             avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) big_endian_read_32(packet, pos);
843                             pos += 4;
844                             // uint16_t character_set = big_endian_read_16(packet, pos);
845                             pos += 2;
846                             uint16_t attr_value_length = big_endian_read_16(packet, pos);
847                             pos += 2;
848 
849                             // debug - to remove later
850                             uint8_t  value[100];
851                             uint16_t value_len = sizeof(value) <= attr_value_length? sizeof(value) - 1 : attr_value_length;
852                             memcpy(value, packet+pos, value_len);
853                             value[value_len] = 0;
854                             // printf("Now Playing Info %s: %s \n", attribute2str(attr_id), value);
855                             // end debug
856 
857                             if ((attr_id >= 1) || (attr_id <= AVRCP_MEDIA_ATTR_COUNT)) {
858                                 items[attr_id-1].len = attr_value_length;
859                                 items[attr_id-1].value = &packet[pos];
860                                 switch (attr_id){
861                                     case AVRCP_MEDIA_ATTR_TITLE:
862                                     case AVRCP_MEDIA_ATTR_ARTIST:
863                                     case AVRCP_MEDIA_ATTR_ALBUM:
864                                     case AVRCP_MEDIA_ATTR_GENRE:
865                                         num_string_attributes++;
866                                         string_attributes_len += attr_value_length;
867                                         if (max_string_attribute_value_len < attr_value_length){
868                                             max_string_attribute_value_len = attr_value_length;
869                                         }
870                                         break;
871                                     default:
872                                         break;
873                                 }
874                             }
875                             pos += attr_value_length;
876                         }
877                     }
878 
879                     // subtract space for fixed fields
880                     total_event_payload_for_string_attributes -= 14 + 4;    // 4 for '\0'
881 
882                     // @TODO optimize space by repeatedly decreasing max_string_attribute_value_len until it fits into buffer instead of crude divion
883                     uint16_t max_value_len = total_event_payload_for_string_attributes > string_attributes_len? max_string_attribute_value_len : total_event_payload_for_string_attributes/(string_attributes_len+1) - 1;
884                     // printf("num_string_attributes %d, string_attributes_len %d, total_event_payload_for_string_attributes %d, max_value_len %d \n", num_string_attributes, string_attributes_len, total_event_payload_for_string_attributes, max_value_len);
885 
886                     const uint8_t attribute_order[] = {
887                         AVRCP_MEDIA_ATTR_TRACK,
888                         AVRCP_MEDIA_ATTR_TOTAL_TRACKS,
889                         AVRCP_MEDIA_ATTR_SONG_LENGTH,
890                         AVRCP_MEDIA_ATTR_TITLE,
891                         AVRCP_MEDIA_ATTR_ARTIST,
892                         AVRCP_MEDIA_ATTR_ALBUM,
893                         AVRCP_MEDIA_ATTR_GENRE
894                     };
895 
896                     uint8_t event[HCI_EVENT_BUFFER_SIZE];
897                     event[0] = HCI_EVENT_AVRCP_META;
898                     pos = 2;
899                     event[pos++] = AVRCP_SUBEVENT_NOW_PLAYING_INFO;
900                     little_endian_store_16(event, pos, connection->l2cap_signaling_cid);
901                     pos += 2;
902                     event[pos++] = ctype;
903                     for (i = 0; i < sizeof(attribute_order); i++){
904                         avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) attribute_order[i];
905                         uint16_t value_len = 0;
906                         switch (attr_id){
907                             case AVRCP_MEDIA_ATTR_TITLE:
908                             case AVRCP_MEDIA_ATTR_ARTIST:
909                             case AVRCP_MEDIA_ATTR_ALBUM:
910                             case AVRCP_MEDIA_ATTR_GENRE:
911                                 if (items[attr_id-1].value){
912                                     value_len = items[attr_id-1].len <= max_value_len ? items[attr_id-1].len : max_value_len;
913                                 }
914                                 event[pos++] = value_len + 1;
915                                 if (value_len){
916                                     memcpy(event+pos, items[attr_id-1].value, value_len);
917                                     pos += value_len;
918                                 }
919                                 event[pos++] = 0;
920                                 break;
921                             case AVRCP_MEDIA_ATTR_SONG_LENGTH:
922                                 if (items[attr_id-1].value){
923                                     little_endian_store_32(event, pos, btstack_atoi((char *)items[attr_id-1].value));
924                                 } else {
925                                     little_endian_store_32(event, pos, 0);
926                                 }
927                                 pos += 4;
928                                 break;
929                             case AVRCP_MEDIA_ATTR_TRACK:
930                             case AVRCP_MEDIA_ATTR_TOTAL_TRACKS:
931                                 if (items[attr_id-1].value){
932                                     event[pos++] = btstack_atoi((char *)items[attr_id-1].value);
933                                 } else {
934                                     event[pos++] = 0;
935                                 }
936                                 break;
937                         }
938                     }
939                     event[1] = pos - 2;
940                     // printf_hexdump(event, pos);
941                     (*avrcp_callback)(HCI_EVENT_PACKET, 0, event, pos);
942                     break;
943                 }
944                 default:
945                     break;
946             }
947             break;
948         case AVRCP_CMD_OPCODE_PASS_THROUGH:{
949             // 0x80 | connection->cmd_operands[0]
950             uint8_t operation_id = packet[pos++];
951             switch (connection->state){
952                 case AVCTP_W2_RECEIVE_PRESS_RESPONSE:
953                     if (connection->continuous_fast_forward_cmd){
954                         connection->state = AVCTP_W4_STOP;
955                     } else {
956                         connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
957                     }
958                     break;
959                 case AVCTP_W2_RECEIVE_RESPONSE:
960                     connection->state = AVCTP_CONNECTION_OPENED;
961                     break;
962                 default:
963                     // check for notifications? move state transition down
964                     // log_info("AVRCP_CMD_OPCODE_PASS_THROUGH state %d\n", connection->state);
965                     break;
966             }
967             if (connection->state == AVCTP_W4_STOP){
968                 avrcp_emit_operation_status(avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->l2cap_signaling_cid, ctype, operation_id);
969             }
970             if (connection->state == AVCTP_CONNECTION_OPENED) {
971                 // RELEASE response
972                 operation_id = operation_id & 0x7F;
973                 avrcp_emit_operation_status(avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->l2cap_signaling_cid, ctype, operation_id);
974             }
975             if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){
976                 // PRESS response
977                 request_pass_through_release_control_cmd(connection);
978             }
979             break;
980         }
981         default:
982             break;
983     }
984 }
985 
986 static void avrcp_handle_can_send_now(avrcp_connection_t * connection){
987     int i;
988     switch (connection->state){
989         case AVCTP_W2_SEND_PRESS_COMMAND:
990             connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE;
991             avrcp_send_cmd(connection->l2cap_signaling_cid, connection);
992             break;
993         case AVCTP_W2_SEND_COMMAND:
994         case AVCTP_W2_SEND_RELEASE_COMMAND:
995             connection->state = AVCTP_W2_RECEIVE_RESPONSE;
996             avrcp_send_cmd(connection->l2cap_signaling_cid, connection);
997             break;
998         case AVCTP_CONNECTION_OPENED:
999             if (connection->notifications_to_register != 0){
1000                 for (i = 1; i <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; i++){
1001                     if (connection->notifications_to_register & (1<<i)){
1002                         connection->notifications_to_register &= ~ (1 << i);
1003                         avrcp_prepare_notification(connection, (avrcp_notification_event_id_t) i);
1004                         connection->state = AVCTP_W2_RECEIVE_RESPONSE;
1005                         avrcp_send_cmd(connection->l2cap_signaling_cid, connection);
1006                         return;
1007                     }
1008                 }
1009             }
1010             return;
1011         default:
1012             return;
1013     }
1014 }
1015 
1016 static avrcp_connection_t * avrcp_create_connection(bd_addr_t remote_addr){
1017     avrcp_connection_t * connection = btstack_memory_avrcp_connection_get();
1018     memset(connection, 0, sizeof(avrcp_connection_t));
1019     connection->state = AVCTP_CONNECTION_IDLE;
1020     connection->transaction_label = 0xFF;
1021     memcpy(connection->remote_addr, remote_addr, 6);
1022     btstack_linked_list_add(&avrcp_connections, (btstack_linked_item_t *) connection);
1023     return connection;
1024 }
1025 
1026 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1027     bd_addr_t event_addr;
1028     uint16_t local_cid;
1029     uint8_t status;
1030     hci_con_handle_t con_handle;
1031     avrcp_connection_t * connection = NULL;
1032 
1033     switch (packet_type) {
1034         case L2CAP_DATA_PACKET:
1035             connection = get_avrcp_connection_for_l2cap_signaling_cid(channel);
1036             if (!connection) break;
1037             avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size);
1038             break;
1039 
1040         case HCI_EVENT_PACKET:
1041             switch (hci_event_packet_get_type(packet)) {
1042                 case L2CAP_EVENT_INCOMING_CONNECTION:
1043                     l2cap_event_incoming_connection_get_address(packet, event_addr);
1044                     local_cid = l2cap_event_incoming_connection_get_local_cid(packet);
1045                     connection = avrcp_create_connection(event_addr);
1046                     if (!connection) {
1047                         log_error("Failed to alloc connection structure");
1048                         l2cap_decline_connection(local_cid);
1049                         break;
1050                     }
1051                     connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
1052                     connection->l2cap_signaling_cid = local_cid;
1053                     l2cap_accept_connection(local_cid);
1054                     break;
1055 
1056                 case L2CAP_EVENT_CHANNEL_OPENED:
1057                     l2cap_event_channel_opened_get_address(packet, event_addr);
1058 
1059                     connection = get_avrcp_connection_for_bd_addr(event_addr);
1060                     status = l2cap_event_channel_opened_get_status(packet);
1061                     local_cid  = l2cap_event_channel_opened_get_local_cid(packet);
1062 
1063                     if (connection){
1064                         // outgoing connection
1065                         if (l2cap_event_channel_opened_get_status(packet)){
1066                             log_error("L2CAP connection to connection %s failed. status code 0x%02x",
1067                                 bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_status(packet));
1068                             if (connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED){
1069                                 avrcp_emit_connection_established(avrcp_callback, status, event_addr, HCI_CON_HANDLE_INVALID, local_cid);
1070                             }
1071                             // free connection
1072                             btstack_linked_list_remove(&avrcp_connections, (btstack_linked_item_t*) connection);
1073                             btstack_memory_avrcp_connection_free(connection);
1074                             break;
1075                         }
1076                     } else {
1077                         // incoming connection
1078                         connection = avrcp_create_connection(event_addr);
1079                         if (!connection) {
1080                             log_error("Failed to alloc connection structure");
1081                             l2cap_disconnect(local_cid, 0); // reason isn't used
1082                             break;
1083                         }
1084                     }
1085 
1086                     connection->l2cap_signaling_cid = local_cid;
1087                     con_handle = l2cap_event_channel_opened_get_handle(packet);
1088                     connection->state = AVCTP_CONNECTION_OPENED;
1089                     avrcp_emit_connection_established(avrcp_callback, ERROR_CODE_SUCCESS, event_addr, con_handle, local_cid);
1090                     break;
1091 
1092                 case L2CAP_EVENT_CAN_SEND_NOW:
1093                     connection = get_avrcp_connection_for_l2cap_signaling_cid(channel);
1094                     if (!connection) break;
1095                     avrcp_handle_can_send_now(connection);
1096                     break;
1097 
1098                 case L2CAP_EVENT_CHANNEL_CLOSED:
1099                     // data: event (8), len(8), channel (16)
1100                     local_cid = l2cap_event_channel_closed_get_local_cid(packet);
1101                     connection = get_avrcp_connection_for_l2cap_signaling_cid(local_cid);
1102                     if (connection){
1103                         avrcp_emit_connection_closed(avrcp_callback, connection->l2cap_signaling_cid);
1104                         // free connection
1105                         btstack_linked_list_remove(&avrcp_connections, (btstack_linked_item_t*) connection);
1106                         btstack_memory_avrcp_connection_free(connection);
1107                         break;
1108                     }
1109                     break;
1110                 default:
1111                     break;
1112             }
1113             break;
1114         default:
1115             break;
1116     }
1117 }
1118 
1119 void avrcp_init(void){
1120     avrcp_connections = NULL;
1121     l2cap_register_service(&packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0);
1122 }
1123 
1124 void avrcp_register_packet_handler(btstack_packet_handler_t callback){
1125     if (callback == NULL){
1126         log_error("avrcp_register_packet_handler called with NULL callback");
1127         return;
1128     }
1129     avrcp_callback = callback;
1130 }
1131 
1132 uint8_t avrcp_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){
1133     avrcp_connection_t * connection = get_avrcp_connection_for_bd_addr(bd_addr);
1134     if (connection){
1135         return ERROR_CODE_COMMAND_DISALLOWED;
1136     }
1137 
1138     connection = avrcp_create_connection(bd_addr);
1139     if (!connection){
1140         log_error("avrcp: could not allocate connection struct.");
1141         return BTSTACK_MEMORY_ALLOC_FAILED;
1142     }
1143 
1144     connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
1145     l2cap_create_channel(packet_handler, connection->remote_addr, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, &connection->l2cap_signaling_cid);
1146     if (avrcp_cid) {
1147         *avrcp_cid = connection->l2cap_signaling_cid;
1148     }
1149     return ERROR_CODE_SUCCESS;
1150 }
1151 
1152 uint8_t avrcp_unit_info(uint16_t avrcp_cid){
1153     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1154     if (!connection){
1155         log_error("avrcp_unit_info: could not find a connection.");
1156         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1157     }
1158     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1159     connection->state = AVCTP_W2_SEND_COMMAND;
1160 
1161     connection->transaction_label++;
1162     connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO;
1163     connection->command_type = AVRCP_CTYPE_STATUS;
1164     connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
1165     connection->subunit_id =   AVRCP_SUBUNIT_ID_IGNORE;
1166     memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length);
1167     connection->cmd_operands_length = 5;
1168     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1169     return ERROR_CODE_SUCCESS;
1170 }
1171 
1172 static uint8_t avrcp_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){
1173     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1174     if (!connection){
1175         log_error("avrcp_get_capabilities: could not find a connection.");
1176         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1177     }
1178     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1179     connection->state = AVCTP_W2_SEND_COMMAND;
1180 
1181     connection->transaction_label++;
1182     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1183     connection->command_type = AVRCP_CTYPE_STATUS;
1184     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1185     connection->subunit_id = AVRCP_SUBUNIT_ID;
1186     big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
1187     connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID
1188     connection->cmd_operands[4] = 0;
1189     big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length
1190     connection->cmd_operands[7] = capability_id;                  // capability ID
1191     connection->cmd_operands_length = 8;
1192     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1193     return ERROR_CODE_SUCCESS;
1194 }
1195 
1196 uint8_t avrcp_get_supported_company_ids(uint16_t avrcp_cid){
1197     return avrcp_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY);
1198 }
1199 
1200 uint8_t avrcp_get_supported_events(uint16_t avrcp_cid){
1201     return avrcp_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT);
1202 }
1203 
1204 
1205 uint8_t avrcp_play(uint16_t avrcp_cid){
1206     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0);
1207 }
1208 
1209 uint8_t avrcp_stop(uint16_t avrcp_cid){
1210     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0);
1211 }
1212 
1213 uint8_t avrcp_pause(uint16_t avrcp_cid){
1214     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0);
1215 }
1216 
1217 uint8_t avrcp_forward(uint16_t avrcp_cid){
1218     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0);
1219 }
1220 
1221 uint8_t avrcp_backward(uint16_t avrcp_cid){
1222     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0);
1223 }
1224 
1225 uint8_t avrcp_start_rewind(uint16_t avrcp_cid){
1226     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0);
1227 }
1228 
1229 uint8_t avrcp_volume_up(uint16_t avrcp_cid){
1230     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0);
1231 }
1232 
1233 uint8_t avrcp_volume_down(uint16_t avrcp_cid){
1234     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0);
1235 }
1236 
1237 uint8_t avrcp_mute(uint16_t avrcp_cid){
1238     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0);
1239 }
1240 
1241 uint8_t avrcp_skip(uint16_t avrcp_cid){
1242     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0);
1243 }
1244 
1245 uint8_t avrcp_stop_rewind(uint16_t avrcp_cid){
1246     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1247     if (!connection){
1248         log_error("avrcp_stop_rewind: could not find a connection.");
1249         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1250     }
1251     if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED;
1252     return request_pass_through_release_control_cmd(connection);
1253 }
1254 
1255 uint8_t avrcp_start_fast_forward(uint16_t avrcp_cid){
1256     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
1257 }
1258 
1259 uint8_t avrcp_fast_forward(uint16_t avrcp_cid){
1260     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
1261 }
1262 
1263 uint8_t avrcp_rewind(uint16_t avrcp_cid){
1264     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0);
1265 }
1266 
1267 
1268 uint8_t avrcp_stop_fast_forward(uint16_t avrcp_cid){
1269     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1270     if (!connection){
1271         log_error("avrcp_stop_fast_forward: could not find a connection.");
1272         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1273     }
1274     if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED;
1275     return request_pass_through_release_control_cmd(connection);
1276 }
1277 
1278 uint8_t avrcp_get_play_status(uint16_t avrcp_cid){
1279     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1280     if (!connection){
1281         log_error("avrcp_get_play_status: could not find a connection.");
1282         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1283     }
1284     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1285     connection->state = AVCTP_W2_SEND_COMMAND;
1286 
1287     connection->transaction_label++;
1288     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1289     connection->command_type = AVRCP_CTYPE_STATUS;
1290     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1291     connection->subunit_id = AVRCP_SUBUNIT_ID;
1292     big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
1293     connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS;
1294     connection->cmd_operands[4] = 0;                     // reserved(upper 6) | packet_type -> 0
1295     big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length
1296     connection->cmd_operands_length = 7;
1297     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1298 
1299     return ERROR_CODE_SUCCESS;
1300 }
1301 
1302 uint8_t avrcp_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){
1303     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1304     if (!connection){
1305         log_error("avrcp_get_play_status: could not find a connection.");
1306         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1307     }
1308     avrcp_register_notification(connection, event_id);
1309     return ERROR_CODE_SUCCESS;
1310 }
1311 
1312 uint8_t avrcp_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){
1313     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1314     if (!connection){
1315         log_error("avrcp_get_play_status: could not find a connection.");
1316         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1317     }
1318     connection->notifications_to_deregister |= (1 << event_id);
1319     return ERROR_CODE_SUCCESS;
1320 }
1321 
1322 uint8_t avrcp_get_now_playing_info(uint16_t avrcp_cid){
1323     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1324     if (!connection){
1325         log_error("avrcp_get_capabilities: could not find a connection.");
1326         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1327     }
1328     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1329     connection->state = AVCTP_W2_SEND_COMMAND;
1330 
1331     connection->transaction_label++;
1332     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1333     connection->command_type = AVRCP_CTYPE_STATUS;
1334     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1335     connection->subunit_id = AVRCP_SUBUNIT_ID;
1336     int pos = 0;
1337     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1338     pos += 3;
1339     connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID
1340     connection->cmd_operands[pos++] = 0;
1341 
1342     // Parameter Length
1343     big_endian_store_16(connection->cmd_operands, pos, 9);
1344     pos += 2;
1345 
1346     // write 8 bytes value
1347     memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING
1348     pos += 8;
1349 
1350     connection->cmd_operands[pos++] = 0; // attribute count, if 0 get all attributes
1351     // every attribute is 4 bytes long
1352 
1353     connection->cmd_operands_length = pos;
1354     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1355     return ERROR_CODE_SUCCESS;
1356 }
1357 
1358 uint8_t avrcp_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){
1359      avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1360     if (!connection){
1361         log_error("avrcp_get_capabilities: could not find a connection.");
1362         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1363     }
1364     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1365     connection->state = AVCTP_W2_SEND_COMMAND;
1366 
1367     connection->transaction_label++;
1368     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1369     connection->command_type = AVRCP_CTYPE_CONTROL;
1370     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1371     connection->subunit_id = AVRCP_SUBUNIT_ID;
1372     int pos = 0;
1373     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1374     pos += 3;
1375     connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME; // PDU ID
1376     connection->cmd_operands[pos++] = 0;
1377 
1378     // Parameter Length
1379     big_endian_store_16(connection->cmd_operands, pos, 1);
1380     pos += 2;
1381     connection->cmd_operands[pos++] = volume;
1382 
1383     connection->cmd_operands_length = pos;
1384     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1385     return ERROR_CODE_SUCCESS;
1386 }
1387 
1388 uint8_t avrcp_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){
1389     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1390     if (!connection){
1391         log_error("avrcp_get_capabilities: could not find a connection.");
1392         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1393     }
1394     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1395     connection->state = AVCTP_W2_SEND_COMMAND;
1396 
1397     connection->transaction_label++;
1398     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1399     connection->command_type = AVRCP_CTYPE_STATUS;
1400     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1401     connection->subunit_id = AVRCP_SUBUNIT_ID;
1402     big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
1403     connection->cmd_operands[3] = AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue; // PDU ID
1404     connection->cmd_operands[4] = 0;
1405     big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length
1406     connection->cmd_operands[7] = 4;                     // NumPlayerApplicationSettingAttributeID
1407     // PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133
1408     connection->cmd_operands[8]  = 0x01;    // equalizer  (1-OFF, 2-ON)
1409     connection->cmd_operands[9]  = 0x02;    // repeat     (1-off, 2-single track, 3-all tracks, 4-group repeat)
1410     connection->cmd_operands[10] = 0x03;    // shuffle    (1-off, 2-all tracks, 3-group shuffle)
1411     connection->cmd_operands[11] = 0x04;    // scan       (1-off, 2-all tracks, 3-group scan)
1412     connection->cmd_operands_length = 12;
1413     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1414     return ERROR_CODE_SUCCESS;
1415 }
1416 
1417 static uint8_t avrcp_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attribute_id, uint8_t attribute_value){
1418     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1419     if (!connection){
1420         log_error("avrcp_get_capabilities: could not find a connection.");
1421         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1422     }
1423     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1424     connection->state = AVCTP_W2_SEND_COMMAND;
1425 
1426     connection->transaction_label++;
1427     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1428     connection->command_type = AVRCP_CTYPE_CONTROL;
1429     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1430     connection->subunit_id = AVRCP_SUBUNIT_ID;
1431     int pos = 0;
1432     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1433     pos += 3;
1434     connection->cmd_operands[pos++] = AVRCP_PDU_ID_SetPlayerApplicationSettingValue; // PDU ID
1435     connection->cmd_operands[pos++] = 0;
1436     // Parameter Length
1437     big_endian_store_16(connection->cmd_operands, pos, 3);
1438     pos += 2;
1439     connection->cmd_operands[pos++] = 2;
1440     connection->cmd_operands_length = pos;
1441     connection->cmd_operands[pos++]  = attribute_id;
1442     connection->cmd_operands[pos++]  = attribute_value;
1443     connection->cmd_operands_length = pos;
1444     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1445     return ERROR_CODE_SUCCESS;
1446 }
1447 
1448 uint8_t avrcp_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){
1449     if (mode < AVRCP_SHUFFLE_MODE_OFF || mode > AVRCP_SHUFFLE_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1450     return avrcp_set_current_player_application_setting_value(avrcp_cid, 0x03, mode);
1451 }
1452 
1453 uint8_t avrcp_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){
1454     if (mode < AVRCP_REPEAT_MODE_OFF || mode > AVRCP_REPEAT_MODE_GROUP) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1455     return avrcp_set_current_player_application_setting_value(avrcp_cid, 0x02, mode);
1456 }
1457 
1458 uint8_t avrcp_disconnect(uint16_t avrcp_cid){
1459     avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
1460     if (!connection){
1461         log_error("avrcp_get_capabilities: could not find a connection.");
1462         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1463     }
1464     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1465     l2cap_disconnect(connection->l2cap_signaling_cid, 0);
1466     return ERROR_CODE_SUCCESS;
1467 }