xref: /btstack/src/classic/avrcp_controller.c (revision be4cc80ad5308597786dd7d5f87160175907705a)
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_controller.c"
39 
40 #include <stdint.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <inttypes.h>
45 
46 #include "btstack.h"
47 #include "classic/avrcp.h"
48 #include "classic/avrcp_controller.h"
49 
50 // made public in avrcp_controller.h
51 
52 static int avrcp_controller_supports_browsing(uint16_t controller_supported_features){
53     return controller_supported_features & (1 << AVRCP_CONTROLLER_SUPPORTED_FEATURE_BROWSING);
54 }
55 
56 void avrcp_controller_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t supported_features, const char * service_name, const char * service_provider_name){
57     avrcp_create_sdp_record(1, service, service_record_handle, avrcp_controller_supports_browsing(supported_features), supported_features, service_name, service_provider_name);
58 }
59 
60 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){
61     btstack_assert(callback != NULL);
62 
63     uint8_t event[8];
64     int pos = 0;
65     event[pos++] = HCI_EVENT_AVRCP_META;
66     event[pos++] = sizeof(event) - 2;
67     event[pos++] = AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE;
68     little_endian_store_16(event, pos, avrcp_cid);
69     pos += 2;
70     event[pos++] = ctype;
71     event[pos++] = repeat_mode;
72     event[pos++] = shuffle_mode;
73     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
74 }
75 
76 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){
77     btstack_assert(callback != NULL);
78 
79     uint8_t event[7];
80     int pos = 0;
81     event[pos++] = HCI_EVENT_AVRCP_META;
82     event[pos++] = sizeof(event) - 2;
83     event[pos++] = subevent;
84     little_endian_store_16(event, pos, avrcp_cid);
85     pos += 2;
86     event[pos++] = ctype;
87     event[pos++] = operation_id;
88     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
89 }
90 
91 static void avrcp_press_and_hold_timeout_handler(btstack_timer_source_t * timer){
92     UNUSED(timer);
93     avrcp_connection_t * connection = (avrcp_connection_t*) btstack_run_loop_get_timer_context(timer);
94     btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
95     btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
96     connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
97     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
98 }
99 
100 static void avrcp_press_and_hold_timer_start(avrcp_connection_t * connection){
101     btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
102     btstack_run_loop_set_timer_handler(&connection->press_and_hold_cmd_timer, avrcp_press_and_hold_timeout_handler);
103     btstack_run_loop_set_timer_context(&connection->press_and_hold_cmd_timer, connection);
104     btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
105     btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
106 }
107 
108 static void avrcp_press_and_hold_timer_stop(avrcp_connection_t * connection){
109     connection->continuous_fast_forward_cmd = 0;
110     btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
111 }
112 
113 static uint8_t request_pass_through_release_control_cmd(avrcp_connection_t * connection){
114     connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
115     if (connection->continuous_fast_forward_cmd){
116         avrcp_press_and_hold_timer_stop(connection);
117     }
118     connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0];
119     connection->transaction_label++;
120     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
121     return ERROR_CODE_SUCCESS;
122 }
123 
124 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){
125     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
126     if (!connection){
127         log_error("avrcp: could not find a connection. avrcp cid 0x%02x", avrcp_cid);
128         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
129     }
130 
131     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
132     connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
133     connection->command_opcode =  AVRCP_CMD_OPCODE_PASS_THROUGH;
134     connection->command_type = AVRCP_CTYPE_CONTROL;
135     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
136     connection->subunit_id =   AVRCP_SUBUNIT_ID;
137     connection->cmd_operands_length = 0;
138 
139     connection->continuous_fast_forward_cmd = continuous_fast_forward_cmd;
140     connection->cmd_operands_length = 2;
141     connection->cmd_operands[0] = opid;
142     if (playback_speed > 0){
143         connection->cmd_operands[2] = playback_speed;
144         connection->cmd_operands_length++;
145     }
146     connection->cmd_operands[1] = connection->cmd_operands_length - 2;
147 
148     if (connection->continuous_fast_forward_cmd){
149         avrcp_press_and_hold_timer_start(connection);
150     }
151 
152     connection->transaction_label++;
153     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
154     return ERROR_CODE_SUCCESS;
155 }
156 
157 static uint8_t request_single_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){
158     return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 0);
159 }
160 
161 static uint8_t request_continuous_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){
162     return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 1);
163 }
164 
165 #define AVRCP_CMD_BUFFER_SIZE 30
166 static uint16_t avrcp_get_max_payload_size_for_packet_type(avrcp_packet_type_t packet_type){
167     switch (packet_type){
168         case AVRCP_SINGLE_PACKET:
169             return AVRCP_CMD_BUFFER_SIZE - 3;
170         case AVRCP_START_PACKET:
171             return AVRCP_CMD_BUFFER_SIZE - 4;
172         case AVRCP_CONTINUE_PACKET:
173         case AVRCP_END_PACKET:
174             return AVRCP_CMD_BUFFER_SIZE - 1;
175     }
176     return 0;
177 }
178 
179 static int avrcp_send_cmd(avrcp_connection_t * connection, avrcp_packet_type_t packet_type){
180     uint8_t command[AVRCP_CMD_BUFFER_SIZE];
181     int pos = 0;
182     uint16_t max_bytes = sizeof(command) - 1;
183 
184     // transport header
185     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
186     command[pos++] = (connection->transaction_label << 4) | (packet_type << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
187 
188     if (packet_type == AVRCP_START_PACKET){
189         // num packets: (3 bytes overhead (PID, num packets) + command) / (MTU - transport header)
190         command[pos++] = ((connection->cmd_operands_fragmented_len + 3 - 1) / (AVRCP_CMD_BUFFER_SIZE - 1)) + 1;
191         max_bytes -= 3;
192     }
193 
194     if ((packet_type == AVRCP_SINGLE_PACKET) || (packet_type == AVRCP_START_PACKET)){
195         // Profile IDentifier (PID)
196         command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
197         command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
198 
199         // command_type
200         command[pos++] = connection->command_type;
201         // subunit_type | subunit ID
202         command[pos++] = (connection->subunit_type << 3) | connection->subunit_id;
203         // opcode
204         command[pos++] = (uint8_t)connection->command_opcode;
205     }
206 
207     if (packet_type == AVRCP_SINGLE_PACKET){
208         // operands
209         (void)memcpy(command + pos, connection->cmd_operands,
210                      connection->cmd_operands_length);
211         pos += connection->cmd_operands_length;
212     } else {
213         uint16_t bytes_to_copy = btstack_min(connection->cmd_operands_fragmented_len-connection->cmd_operands_fragmented_pos, max_bytes);
214         (void)memcpy(command + pos,
215                      &connection->cmd_operands_fragmented_buffer[connection->cmd_operands_fragmented_pos],
216                      bytes_to_copy);
217         pos += bytes_to_copy;
218         connection->cmd_operands_fragmented_pos += bytes_to_copy;
219     }
220 
221     return l2cap_send(connection->l2cap_signaling_cid, command, pos);
222 }
223 
224 static int avrcp_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){
225     if (connection->notifications_to_deregister & (1 << event_id)) return 0;
226     if (connection->notifications_enabled & (1 << event_id)) return 0;
227     if (connection->notifications_to_register & (1 << event_id)) return 0;
228     connection->notifications_to_register |= (1 << event_id);
229     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
230     return 1;
231 }
232 
233 static void avrcp_prepare_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){
234     connection->transaction_label++;
235     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
236     connection->command_type = AVRCP_CTYPE_NOTIFY;
237     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
238     connection->subunit_id = AVRCP_SUBUNIT_ID;
239     int pos = 0;
240     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
241     pos += 3;
242     connection->cmd_operands[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION;
243     connection->cmd_operands[pos++] = 0;                     // reserved(upper 6) | packet_type -> 0
244     big_endian_store_16(connection->cmd_operands, pos, 5);     // parameter length
245     pos += 2;
246     connection->cmd_operands[pos++] = event_id;
247     big_endian_store_32(connection->cmd_operands, pos, 1); // send notification on playback position every second, for other notifications it is ignored
248     pos += 4;
249     connection->cmd_operands_length = pos;
250     // AVRCP_SPEC_V14.pdf 166
251     // answer page 61
252 }
253 
254 
255 static void avrcp_parser_reset(avrcp_connection_t * connection){
256     connection->list_offset = 0;
257     connection->num_attributes = 0;
258     connection->num_parsed_attributes = 0;
259     connection->parser_attribute_header_pos = 0;
260     connection->num_received_fragments = 0;
261     connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER;
262 }
263 
264 static void avrcp_controller_emit_now_playing_info_event_done(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t ctype, uint8_t status){
265     uint8_t event[7];
266     int pos = 0;
267     event[pos++] = HCI_EVENT_AVRCP_META;
268     event[pos++] = sizeof(event) - 2;
269     event[pos++] = AVRCP_SUBEVENT_NOW_PLAYING_INFO_DONE;
270     little_endian_store_16(event, pos, avrcp_cid);
271     pos += 2;
272     event[pos++] = ctype;
273     event[pos++] = status;
274     // printf_hexdump(event, pos);
275     (*callback)(HCI_EVENT_PACKET, 0, event, pos);
276 }
277 
278 static void avrcp_controller_emit_now_playing_info_event(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t ctype, avrcp_media_attribute_id_t attr_id, uint8_t * value, uint16_t value_len){
279     uint8_t event[HCI_EVENT_BUFFER_SIZE];
280     int pos = 0;
281     event[pos++] = HCI_EVENT_AVRCP_META;
282     // reserve one byte for subevent type and data len
283     int data_len_pos = pos;
284     pos++;
285     int subevent_type_pos = pos;
286     pos++;
287     little_endian_store_16(event, pos, avrcp_cid);
288     pos += 2;
289     event[pos++] = ctype;
290 
291     switch (attr_id){
292         case AVRCP_MEDIA_ATTR_TITLE:
293             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO;
294             event[pos++] = value_len;
295             (void)memcpy(event + pos, value, value_len);
296             break;
297         case AVRCP_MEDIA_ATTR_ARTIST:
298             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ARTIST_INFO;
299             event[pos++] = value_len;
300             (void)memcpy(event + pos, value, value_len);
301             break;
302         case AVRCP_MEDIA_ATTR_ALBUM:
303             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ALBUM_INFO;
304             event[pos++] = value_len;
305             (void)memcpy(event + pos, value, value_len);
306             break;
307         case AVRCP_MEDIA_ATTR_GENRE:
308             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_GENRE_INFO;
309             event[pos++] = value_len;
310             (void)memcpy(event + pos, value, value_len);
311             break;
312         case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS:
313             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_SONG_LENGTH_MS_INFO;
314             if (value){
315                 little_endian_store_32(event, pos, btstack_atoi((char *)value));
316             } else {
317                 little_endian_store_32(event, pos, 0);
318             }
319             pos += 4;
320             break;
321         case AVRCP_MEDIA_ATTR_TRACK:
322             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TRACK_INFO;
323             if (value){
324                 event[pos++] = btstack_atoi((char *)value);
325             } else {
326                 event[pos++] = 0;
327             }
328             break;
329         case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS:
330             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO;
331             if (value){
332                 event[pos++] = btstack_atoi((char *)value);
333             } else {
334                 event[pos++] = 0;
335             }
336             break;
337         default:
338             break;
339     }
340     event[data_len_pos] = pos - 2;
341     (*callback)(HCI_EVENT_PACKET, 0, event, pos);
342 }
343 
344 static void avrcp_parser_process_byte(uint8_t byte, avrcp_connection_t * connection, avrcp_command_type_t ctype){
345     uint16_t attribute_total_value_len;
346     uint32_t attribute_id;
347     // printf("avrcp_parser_process_byte: %02x, state %02x\n", byte, connection->parser_state);
348     switch(connection->parser_state){
349         case AVRCP_PARSER_GET_ATTRIBUTE_HEADER:
350             connection->parser_attribute_header[connection->parser_attribute_header_pos++] = byte;
351             connection->list_offset++;
352 
353             if (connection->parser_attribute_header_pos < AVRCP_ATTRIBUTE_HEADER_LEN) return;
354 
355             attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6);
356             connection->attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTTE_SIZE);
357             if (connection->attribute_value_len > 0){
358                 // get ready for attribute value
359                 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_VALUE;
360                 return;
361             }
362 
363             // emit empty attribute
364             attribute_id = big_endian_read_32(connection->parser_attribute_header, 0);
365             avrcp_controller_emit_now_playing_info_event(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, (avrcp_media_attribute_id_t) attribute_id, connection->attribute_value, connection->attribute_value_len);
366 
367             // done, see below
368             break;
369 
370         case AVRCP_PARSER_GET_ATTRIBUTE_VALUE:
371             connection->attribute_value[connection->attribute_value_offset++] = byte;
372             connection->list_offset++;
373 
374             if (connection->attribute_value_offset < connection->attribute_value_len) return;
375 
376             // emit (potentially partial) attribute
377             attribute_id = big_endian_read_32(connection->parser_attribute_header, 0);
378             avrcp_controller_emit_now_playing_info_event(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, (avrcp_media_attribute_id_t) attribute_id, connection->attribute_value, connection->attribute_value_len);
379 
380             attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6);
381             if (connection->attribute_value_offset < attribute_total_value_len){
382                 // ignore rest of attribute
383                 connection->parser_state = AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE;
384                 return;
385             }
386 
387             // done, see below
388             break;
389 
390         case AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE:
391             connection->attribute_value_offset++;
392             connection->list_offset++;
393 
394             attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6);
395             if (connection->attribute_value_offset < attribute_total_value_len) return;
396 
397             // done, see below
398             break;
399 
400         default:
401             return;
402     }
403 
404     // attribute fully read, check if more to come
405     if (connection->list_offset < connection->list_size){
406         // more to come, reset parser
407         connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER;
408         connection->parser_attribute_header_pos = 0;
409         connection->attribute_value_offset = 0;
410     } else {
411         // fully done
412         avrcp_parser_reset(connection);
413         avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 0);
414     }
415 }
416 
417 static void avrcp_source_parse_and_emit_element_attrs(uint8_t * packet, uint16_t num_bytes_to_read, avrcp_connection_t * connection, avrcp_command_type_t ctype){
418     int i;
419     for (i=0;i<num_bytes_to_read;i++){
420         avrcp_parser_process_byte(packet[i], connection, ctype);
421     }
422 }
423 
424 static uint8_t avrcp_controller_request_abort_continuation(avrcp_connection_t * connection){
425     connection->state = AVCTP_W2_SEND_COMMAND;
426     connection->transaction_label++;
427     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
428     connection->command_type = AVRCP_CTYPE_CONTROL;
429     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
430     connection->subunit_id = AVRCP_SUBUNIT_ID;
431     int pos = 0;
432     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
433     pos += 3;
434     connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE; // PDU ID
435     connection->cmd_operands[pos++] = 0;
436     // Parameter Length
437     connection->cmd_operands_length = 8;
438     big_endian_store_16(connection->cmd_operands, pos, 1);
439     pos += 2;
440     connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
441     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
442     return ERROR_CODE_SUCCESS;
443 }
444 
445 
446 static uint8_t avrcp_controller_request_continue_response(avrcp_connection_t * connection){
447     connection->state = AVCTP_W2_SEND_COMMAND;
448     connection->transaction_label++;
449     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
450     connection->command_type = AVRCP_CTYPE_CONTROL;
451     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
452     connection->subunit_id = AVRCP_SUBUNIT_ID;
453     int pos = 0;
454     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
455     pos += 3;
456     connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE; // PDU ID
457     connection->cmd_operands[pos++] = 0;
458     // Parameter Length
459     connection->cmd_operands_length = 8;
460     big_endian_store_16(connection->cmd_operands, pos, 1);
461     pos += 2;
462     connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
463     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
464     return ERROR_CODE_SUCCESS;
465 }
466 
467 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
468     uint8_t operands[20];
469     uint8_t opcode;
470     int     pos = 3;
471 
472     avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++];
473     uint8_t byte_value = packet[pos++];
474     avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3);
475     avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t)   (byte_value & 0x07);
476     opcode = packet[pos++];
477 
478     uint8_t pdu_id;
479     uint16_t param_length;
480     switch (avrcp_cmd_opcode(packet,size)){
481         case AVRCP_CMD_OPCODE_SUBUNIT_INFO:{
482             if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return;
483             connection->state = AVCTP_CONNECTION_OPENED;
484             // operands:
485             (void)memcpy(operands, packet + pos, 5);
486             uint8_t unit_type = operands[1] >> 3;
487             uint8_t max_subunit_ID = operands[1] & 0x07;
488             log_info("    SUBUNIT INFO response: ctype 0x%02x (0C), subunit_type 0x%02x (1F), subunit_id 0x%02x (07), opcode 0x%02x (30), unit_type 0x%02x, max_subunit_ID %d", ctype, subunit_type, subunit_id, opcode, unit_type, max_subunit_ID);
489             break;
490         }
491         case AVRCP_CMD_OPCODE_UNIT_INFO:{
492             if (connection->state != AVCTP_W2_RECEIVE_RESPONSE) return;
493             connection->state = AVCTP_CONNECTION_OPENED;
494             // operands:
495             (void)memcpy(operands, packet + pos, 5);
496             uint8_t unit_type = operands[1] >> 3;
497             uint8_t unit = operands[1] & 0x07;
498             uint32_t company_id = (operands[2] << 16) | (operands[3] << 8) | operands[4];
499             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%06" PRIx32,
500                 ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id);
501             break;
502         }
503         case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT:
504             if ((size - pos) < 7) {
505                 log_error("avrcp: wrong packet size");
506                 return;
507             };
508             // operands:
509             (void)memcpy(operands, packet + pos, 7);
510             pos += 7;
511             pdu_id = operands[3];
512 
513             if ((connection->state != AVCTP_W2_RECEIVE_RESPONSE) && (pdu_id != AVRCP_PDU_ID_REGISTER_NOTIFICATION)){
514                 log_info("AVRCP_CMD_OPCODE_VENDOR_DEPENDENT state %d", connection->state);
515                 return;
516             }
517             connection->state = AVCTP_CONNECTION_OPENED;
518 
519             param_length = big_endian_read_16(operands, 5);
520 
521             log_info("        VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d, status %s", pdu_id, param_length, avrcp_ctype2str(ctype));
522             switch (pdu_id){
523                 case AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue:{
524                     uint8_t num_attributes = packet[pos++];
525                     int i;
526                     avrcp_repeat_mode_t  repeat_mode =  AVRCP_REPEAT_MODE_INVALID;
527                     avrcp_shuffle_mode_t shuffle_mode = AVRCP_SHUFFLE_MODE_INVALID;
528                     for (i = 0; i < num_attributes; i++){
529                         uint8_t attribute_id    = packet[pos++];
530                         uint8_t value = packet[pos++];
531                         switch (attribute_id){
532                             case 0x02:
533                                 repeat_mode = (avrcp_repeat_mode_t) value;
534                                 break;
535                             case 0x03:
536                                 shuffle_mode = (avrcp_shuffle_mode_t) value;
537                                 break;
538                             default:
539                                 break;
540                         }
541                     }
542                     avrcp_emit_repeat_and_shuffle_mode(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, repeat_mode, shuffle_mode);
543                     break;
544                 }
545                 case AVRCP_PDU_ID_SetPlayerApplicationSettingValue:{
546                     uint8_t event[6];
547                     int offset = 0;
548                     event[offset++] = HCI_EVENT_AVRCP_META;
549                     event[offset++] = sizeof(event) - 2;
550                     event[offset++] = AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE;
551                     little_endian_store_16(event, offset, connection->avrcp_cid);
552                     offset += 2;
553                     event[offset++] = ctype;
554                     (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
555                     break;
556                 }
557                 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME:{
558                     uint8_t event[7];
559                     int offset = 0;
560                     event[offset++] = HCI_EVENT_AVRCP_META;
561                     event[offset++] = sizeof(event) - 2;
562                     event[offset++] = AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE;
563                     little_endian_store_16(event, offset, connection->avrcp_cid);
564                     offset += 2;
565                     event[offset++] = ctype;
566                     event[offset++] = packet[pos++];
567                     (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
568                     break;
569                 }
570                 case AVRCP_PDU_ID_GET_CAPABILITIES:{
571                     avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos++];
572                     uint8_t capability_count = packet[pos++];
573                     int i;
574                     switch (capability_id){
575                         case AVRCP_CAPABILITY_ID_COMPANY:
576                             for (i = 0; i < capability_count; i++){
577                                 uint32_t company_id = big_endian_read_24(packet, pos);
578                                 pos += 3;
579                                 log_info("  0x%06" PRIx32 ", ", company_id);
580                             }
581                             break;
582                         case AVRCP_CAPABILITY_ID_EVENT:
583                             for (i = 0; i < capability_count; i++){
584                                 uint8_t event_id = packet[pos++];
585                                 log_info("  0x%02x %s", event_id, avrcp_event2str(event_id));
586                             }
587                             break;
588                     }
589                     break;
590                 }
591                 case AVRCP_PDU_ID_GET_PLAY_STATUS:{
592                     uint32_t song_length = big_endian_read_32(packet, pos);
593                     pos += 4;
594                     uint32_t song_position = big_endian_read_32(packet, pos);
595                     pos += 4;
596                     uint8_t play_status = packet[pos];
597 
598                     uint8_t event[15];
599                     int offset = 0;
600                     event[offset++] = HCI_EVENT_AVRCP_META;
601                     event[offset++] = sizeof(event) - 2;
602                     event[offset++] = AVRCP_SUBEVENT_PLAY_STATUS;
603                     little_endian_store_16(event, offset, connection->avrcp_cid);
604                     offset += 2;
605                     event[offset++] = ctype;
606                     little_endian_store_32(event, offset, song_length);
607                     offset += 4;
608                     little_endian_store_32(event, offset, song_position);
609                     offset += 4;
610                     event[offset++] = play_status;
611                     (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
612                     break;
613                 }
614                 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{
615                     avrcp_notification_event_id_t  event_id = (avrcp_notification_event_id_t) packet[pos++];
616                     uint16_t event_mask = (1 << event_id);
617                     uint16_t reset_event_mask = ~event_mask;
618                     switch (ctype){
619                         case AVRCP_CTYPE_RESPONSE_INTERIM:
620                             // register as enabled
621                             connection->notifications_enabled |= event_mask;
622                             break;
623                         case AVRCP_CTYPE_RESPONSE_CHANGED_STABLE:
624                             // received change, event is considered deregistered
625                             // we are re-enabling it automatically, if it is not
626                             // explicitly disabled
627                             connection->notifications_enabled &= reset_event_mask;
628                             if (! (connection->notifications_to_deregister & event_mask)){
629                                 avrcp_register_notification(connection, event_id);
630                             } else {
631                                 connection->notifications_to_deregister &= reset_event_mask;
632                             }
633                             break;
634                         default:
635                             connection->notifications_to_register &= reset_event_mask;
636                             connection->notifications_enabled &= reset_event_mask;
637                             connection->notifications_to_deregister &= reset_event_mask;
638                             break;
639                     }
640 
641                     switch (event_id){
642                         case AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED:{
643                             uint32_t song_position = big_endian_read_32(packet, pos);
644                             uint8_t event[10];
645                             int offset = 0;
646                             event[offset++] = HCI_EVENT_AVRCP_META;
647                             event[offset++] = sizeof(event) - 2;
648                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_POS_CHANGED;
649                             little_endian_store_16(event, offset, connection->avrcp_cid);
650                             offset += 2;
651                             event[offset++] = ctype;
652                             little_endian_store_32(event, offset, song_position);
653                             offset += 4;
654                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
655                             break;
656                         }
657                         case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:{
658                             uint8_t event[7];
659                             int offset = 0;
660                             event[offset++] = HCI_EVENT_AVRCP_META;
661                             event[offset++] = sizeof(event) - 2;
662                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED;
663                             little_endian_store_16(event, offset, connection->avrcp_cid);
664                             offset += 2;
665                             event[offset++] = ctype;
666                             event[offset++] = packet[pos];
667                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
668                             break;
669                         }
670                         case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:{
671                             uint8_t event[6];
672                             int offset = 0;
673                             event[offset++] = HCI_EVENT_AVRCP_META;
674                             event[offset++] = sizeof(event) - 2;
675                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED;
676                             little_endian_store_16(event, offset, connection->avrcp_cid);
677                             offset += 2;
678                             event[offset++] = ctype;
679                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
680                             break;
681                         }
682                         case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:{
683                             uint8_t event[6];
684                             int offset = 0;
685                             event[offset++] = HCI_EVENT_AVRCP_META;
686                             event[offset++] = sizeof(event) - 2;
687                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED;
688                             little_endian_store_16(event, offset, connection->avrcp_cid);
689                             offset += 2;
690                             event[offset++] = ctype;
691                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
692                             break;
693                         }
694                         case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:{
695                             uint8_t event[6];
696                             int offset = 0;
697                             event[offset++] = HCI_EVENT_AVRCP_META;
698                             event[offset++] = sizeof(event) - 2;
699                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED;
700                             little_endian_store_16(event, offset, connection->avrcp_cid);
701                             offset += 2;
702                             event[offset++] = ctype;
703                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
704                             break;
705                         }
706                         case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:{
707                             uint8_t event[7];
708                             int offset = 0;
709                             event[offset++] = HCI_EVENT_AVRCP_META;
710                             event[offset++] = sizeof(event) - 2;
711                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED;
712                             little_endian_store_16(event, offset, connection->avrcp_cid);
713                             offset += 2;
714                             event[offset++] = ctype;
715                             event[offset++] = packet[pos++] & 0x7F;
716                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
717                             break;
718                         }
719                         case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:{
720                             uint8_t event[7];
721                             int offset = 0;
722                             event[offset++] = HCI_EVENT_AVRCP_META;
723                             event[offset++] = sizeof(event) - 2;
724                             event[offset++] = AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED;
725                             little_endian_store_16(event, offset, connection->avrcp_cid);
726                             offset += 2;
727                             event[offset++] = ctype;
728                             event[offset++] = packet[pos++] & 0x7F;
729                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
730                             break;
731                         }
732 
733                         default:
734                             log_info("avrcp: not implemented");
735                             break;
736                     }
737                     if (connection->notifications_to_register != 0){
738                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
739                     }
740                     break;
741                 }
742 
743                 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{
744                     avrcp_packet_type_t packet_type = (avrcp_packet_type_t) (operands[4] & 0x03);
745                     switch (packet_type){
746                         case AVRCP_START_PACKET:
747                         case AVRCP_SINGLE_PACKET:
748                             avrcp_parser_reset(connection);
749                             connection->list_size = param_length;
750                             connection->num_attributes = packet[pos++];
751 
752                             avrcp_source_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype);
753 
754                             if (packet_type == AVRCP_START_PACKET){
755                                 avrcp_controller_request_continue_response(connection);
756                             }
757                             break;
758                         case AVRCP_CONTINUE_PACKET:
759                         case AVRCP_END_PACKET:
760                             connection->num_received_fragments++;
761                             if (connection->num_received_fragments < connection->max_num_fragments){
762                                 avrcp_source_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype);
763                                 if (packet_type == AVRCP_CONTINUE_PACKET){
764                                     avrcp_controller_request_continue_response(connection);
765                                 }
766                             } else {
767                                 avrcp_controller_request_abort_continuation(connection);
768                                 avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 1);
769                                 avrcp_parser_reset(connection);
770                             }
771                             break;
772                     }
773                 }
774                 default:
775                     break;
776             }
777             break;
778         case AVRCP_CMD_OPCODE_PASS_THROUGH:{
779             // 0x80 | connection->cmd_operands[0]
780             uint8_t operation_id = packet[pos++];
781             switch (connection->state){
782                 case AVCTP_W2_RECEIVE_PRESS_RESPONSE:
783                     if (connection->continuous_fast_forward_cmd){
784                         connection->state = AVCTP_W4_STOP;
785                     } else {
786                         connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
787                     }
788                     break;
789                 case AVCTP_W2_RECEIVE_RESPONSE:
790                     connection->state = AVCTP_CONNECTION_OPENED;
791                     break;
792                 default:
793                     break;
794             }
795             if (connection->state == AVCTP_W4_STOP){
796                 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->avrcp_cid, ctype, operation_id);
797             }
798             if (connection->state == AVCTP_CONNECTION_OPENED) {
799                 // RELEASE response
800                 operation_id = operation_id & 0x7F;
801                 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->avrcp_cid, ctype, operation_id);
802             }
803             if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){
804                 // PRESS response
805                 request_pass_through_release_control_cmd(connection);
806             }
807             break;
808         }
809         default:
810             break;
811     }
812 
813     // trigger pending notification reqistrations
814     if ((connection->state == AVCTP_CONNECTION_OPENED) && connection->notifications_to_register){
815         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
816     }
817 }
818 
819 static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){
820     int i;
821     switch (connection->state){
822         case AVCTP_W2_SEND_PRESS_COMMAND:
823             connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE;
824             avrcp_send_cmd(connection, AVRCP_SINGLE_PACKET);
825             break;
826         case AVCTP_W2_SEND_COMMAND:
827         case AVCTP_W2_SEND_RELEASE_COMMAND:
828             connection->state = AVCTP_W2_RECEIVE_RESPONSE;
829             avrcp_send_cmd(connection, AVRCP_SINGLE_PACKET);
830             break;
831         case AVCTP_CONNECTION_OPENED:
832             if (connection->notifications_to_register != 0){
833                 for (i = 1; i <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; i++){
834                     if (connection->notifications_to_register & (1<<i)){
835                         connection->notifications_to_register &= ~ (1 << i);
836                         avrcp_prepare_notification(connection, (avrcp_notification_event_id_t) i);
837                         connection->state = AVCTP_W2_RECEIVE_RESPONSE;
838                         avrcp_send_cmd(connection, AVRCP_SINGLE_PACKET);
839                         return;
840                     }
841                 }
842             }
843             return;
844         case AVCTP_W2_SEND_FRAGMENTED_COMMAND:
845             if (connection->cmd_operands_fragmented_pos == 0){
846                  avrcp_send_cmd(connection, AVRCP_START_PACKET);
847                  avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
848             } else {
849                 if ((connection->cmd_operands_fragmented_len - connection->cmd_operands_fragmented_pos) > avrcp_get_max_payload_size_for_packet_type(AVRCP_CONTINUE_PACKET)){
850                      avrcp_send_cmd(connection, AVRCP_CONTINUE_PACKET);
851                      avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
852                  } else {
853                     connection->state = AVCTP_W2_RECEIVE_RESPONSE;
854                     avrcp_send_cmd(connection, AVRCP_END_PACKET);
855                  }
856             }
857         default:
858             return;
859     }
860 }
861 
862 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
863     avrcp_connection_t * connection;
864 
865     switch (packet_type) {
866         case L2CAP_DATA_PACKET:
867             connection = get_avrcp_connection_for_l2cap_signaling_cid_for_role(AVRCP_CONTROLLER, channel);
868             if (!connection) break;
869             avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size);
870             break;
871 
872         case HCI_EVENT_PACKET:
873             switch (hci_event_packet_get_type(packet)){
874                 case HCI_EVENT_AVRCP_META:
875                     // forward to app
876                     (*avrcp_controller_context.avrcp_callback)(packet_type, channel, packet, size);
877                     break;
878 
879                 case L2CAP_EVENT_CAN_SEND_NOW:
880                     connection = get_avrcp_connection_for_l2cap_signaling_cid_for_role(AVRCP_CONTROLLER, channel);
881                     if (!connection) break;
882                     avrcp_controller_handle_can_send_now(connection);
883                     break;
884             default:
885                 break;
886         }
887         default:
888             break;
889     }
890 }
891 
892 void avrcp_controller_init(void){
893     avrcp_controller_context.role = AVRCP_CONTROLLER;
894     avrcp_controller_context.packet_handler = avrcp_controller_packet_handler;
895     avrcp_register_controller_packet_handler(&avrcp_controller_packet_handler);
896 }
897 
898 void avrcp_controller_register_packet_handler(btstack_packet_handler_t callback){
899     btstack_assert(callback != NULL);
900     avrcp_controller_context.avrcp_callback = callback;
901 }
902 
903 uint8_t avrcp_controller_unit_info(uint16_t avrcp_cid){
904     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
905     if (!connection){
906         log_error("avrcp_unit_info: could not find a connection.");
907         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
908     }
909     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
910     connection->state = AVCTP_W2_SEND_COMMAND;
911 
912     connection->transaction_label++;
913     connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO;
914     connection->command_type = AVRCP_CTYPE_STATUS;
915     connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
916     connection->subunit_id =   AVRCP_SUBUNIT_ID_IGNORE;
917     memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length);
918     connection->cmd_operands_length = 5;
919     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
920     return ERROR_CODE_SUCCESS;
921 }
922 
923 uint8_t avrcp_controller_subunit_info(uint16_t avrcp_cid){
924     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
925     if (!connection){
926         log_error("avrcp_unit_info: could not find a connection.");
927         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
928     }
929     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
930     connection->state = AVCTP_W2_SEND_COMMAND;
931 
932     connection->transaction_label++;
933     connection->command_opcode = AVRCP_CMD_OPCODE_SUBUNIT_INFO;
934     connection->command_type = AVRCP_CTYPE_STATUS;
935     connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
936     connection->subunit_id =   AVRCP_SUBUNIT_ID_IGNORE;
937     memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length);
938     connection->cmd_operands[0] = 7; // page: 0, extention_code: 7
939     connection->cmd_operands_length = 5;
940     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
941     return ERROR_CODE_SUCCESS;
942 }
943 
944 static uint8_t avrcp_controller_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){
945     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
946     if (!connection){
947         log_error("avrcp_get_capabilities: could not find a connection.");
948         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
949     }
950     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
951     connection->state = AVCTP_W2_SEND_COMMAND;
952 
953     connection->transaction_label++;
954     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
955     connection->command_type = AVRCP_CTYPE_STATUS;
956     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
957     connection->subunit_id = AVRCP_SUBUNIT_ID;
958     big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
959     connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID
960     connection->cmd_operands[4] = 0;
961     big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length
962     connection->cmd_operands[7] = capability_id;                  // capability ID
963     connection->cmd_operands_length = 8;
964     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
965     return ERROR_CODE_SUCCESS;
966 }
967 
968 uint8_t avrcp_controller_get_supported_company_ids(uint16_t avrcp_cid){
969     return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY);
970 }
971 
972 uint8_t avrcp_controller_get_supported_events(uint16_t avrcp_cid){
973     return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT);
974 }
975 
976 
977 uint8_t avrcp_controller_play(uint16_t avrcp_cid){
978     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0);
979 }
980 
981 uint8_t avrcp_controller_stop(uint16_t avrcp_cid){
982     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0);
983 }
984 
985 uint8_t avrcp_controller_pause(uint16_t avrcp_cid){
986     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0);
987 }
988 
989 uint8_t avrcp_controller_forward(uint16_t avrcp_cid){
990     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0);
991 }
992 
993 uint8_t avrcp_controller_backward(uint16_t avrcp_cid){
994     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0);
995 }
996 
997 uint8_t avrcp_controller_volume_up(uint16_t avrcp_cid){
998     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0);
999 }
1000 
1001 uint8_t avrcp_controller_volume_down(uint16_t avrcp_cid){
1002     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0);
1003 }
1004 
1005 uint8_t avrcp_controller_mute(uint16_t avrcp_cid){
1006     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0);
1007 }
1008 
1009 uint8_t avrcp_controller_skip(uint16_t avrcp_cid){
1010     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0);
1011 }
1012 
1013 uint8_t avrcp_controller_fast_forward(uint16_t avrcp_cid){
1014     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
1015 }
1016 
1017 uint8_t avrcp_controller_rewind(uint16_t avrcp_cid){
1018     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0);
1019 }
1020 
1021 
1022 /* start cmds */
1023 
1024 uint8_t avrcp_controller_release_press_and_hold_cmd(uint16_t avrcp_cid){
1025     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1026     if (!connection){
1027         log_error("avrcp_stop_play: could not find a connection.");
1028         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1029     }
1030     if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED;
1031     return request_pass_through_release_control_cmd(connection);
1032 }
1033 
1034 uint8_t avrcp_controller_press_and_hold_play(uint16_t avrcp_cid){
1035     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0);
1036 }
1037 uint8_t avrcp_controller_press_and_hold_stop(uint16_t avrcp_cid){
1038     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0);
1039 }
1040 uint8_t avrcp_controller_press_and_hold_pause(uint16_t avrcp_cid){
1041     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0);
1042 }
1043 uint8_t avrcp_controller_press_and_hold_forward(uint16_t avrcp_cid){
1044     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0);
1045 }
1046 uint8_t avrcp_controller_press_and_hold_backward(uint16_t avrcp_cid){
1047     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0);
1048 }
1049 uint8_t avrcp_controller_press_and_hold_fast_forward(uint16_t avrcp_cid){
1050     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
1051 }
1052 uint8_t avrcp_controller_press_and_hold_rewind(uint16_t avrcp_cid){
1053     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0);
1054 }
1055 uint8_t avrcp_controller_press_and_hold_volume_up(uint16_t avrcp_cid){
1056     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0);
1057 }
1058 uint8_t avrcp_controller_press_and_hold_volume_down(uint16_t avrcp_cid){
1059     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0);
1060 }
1061 uint8_t avrcp_controller_press_and_hold_mute(uint16_t avrcp_cid){
1062     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0);
1063 }
1064 
1065 
1066 /* stop continuous cmds */
1067 
1068 uint8_t avrcp_controller_get_play_status(uint16_t avrcp_cid){
1069     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1070     if (!connection){
1071         log_error("avrcp_get_play_status: could not find a connection.");
1072         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1073     }
1074     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1075     connection->state = AVCTP_W2_SEND_COMMAND;
1076     connection->transaction_label++;
1077     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1078     connection->command_type = AVRCP_CTYPE_STATUS;
1079     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1080     connection->subunit_id = AVRCP_SUBUNIT_ID;
1081     big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
1082     connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS;
1083     connection->cmd_operands[4] = 0;                     // reserved(upper 6) | packet_type -> 0
1084     big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length
1085     connection->cmd_operands_length = 7;
1086     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1087     return ERROR_CODE_SUCCESS;
1088 }
1089 
1090 uint8_t avrcp_controller_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){
1091     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1092     if (!connection){
1093         log_error("avrcp_get_play_status: could not find a connection.");
1094         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1095     }
1096     avrcp_register_notification(connection, event_id);
1097     return ERROR_CODE_SUCCESS;
1098 }
1099 
1100 uint8_t avrcp_controller_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){
1101     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1102     if (!connection){
1103         log_error("avrcp_get_play_status: could not find a connection.");
1104         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1105     }
1106     connection->notifications_to_deregister |= (1 << event_id);
1107     return ERROR_CODE_SUCCESS;
1108 }
1109 
1110 uint8_t avrcp_controller_set_addressed_player(uint16_t avrcp_cid, uint16_t addressed_player_id){
1111     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1112     if (!connection){
1113         log_error("avrcp_get_capabilities: could not find a connection.");
1114         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1115     }
1116     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1117     connection->state = AVCTP_W2_SEND_COMMAND;
1118 
1119     connection->transaction_label++;
1120     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1121     connection->command_type = AVRCP_CTYPE_CONTROL;
1122     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1123     connection->subunit_id = AVRCP_SUBUNIT_ID;
1124     int pos = 0;
1125     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1126     pos += 3;
1127     connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ADDRESSED_PLAYER; // PDU ID
1128     connection->cmd_operands[pos++] = 0;
1129 
1130     // Parameter Length
1131     big_endian_store_16(connection->cmd_operands, pos, 2);
1132     pos += 2;
1133 
1134     big_endian_store_16(connection->cmd_operands, pos, addressed_player_id);
1135     pos += 2;
1136 
1137     connection->cmd_operands_length = pos;
1138     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1139     return ERROR_CODE_SUCCESS;
1140 }
1141 
1142 uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){
1143     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1144     if (!connection){
1145         log_error("avrcp_get_capabilities: could not find a connection.");
1146         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1147     }
1148     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1149     connection->state = AVCTP_W2_SEND_COMMAND;
1150 
1151     connection->transaction_label++;
1152     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1153     connection->command_type = AVRCP_CTYPE_STATUS;
1154     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1155     connection->subunit_id = AVRCP_SUBUNIT_ID;
1156     int pos = 0;
1157     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1158     pos += 3;
1159     connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID
1160     connection->cmd_operands[pos++] = 0;
1161 
1162     // Parameter Length
1163     big_endian_store_16(connection->cmd_operands, pos, 9);
1164     pos += 2;
1165 
1166     // write 8 bytes value
1167     memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING
1168     pos += 8;
1169 
1170     connection->cmd_operands[pos++] = 0; // attribute count, if 0 get all attributes
1171     // every attribute is 4 bytes long
1172 
1173     connection->cmd_operands_length = pos;
1174     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1175     return ERROR_CODE_SUCCESS;
1176 }
1177 
1178 uint8_t avrcp_controller_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){
1179      avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1180     if (!connection){
1181         log_error("avrcp_get_capabilities: could not find a connection.");
1182         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1183     }
1184     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1185     connection->state = AVCTP_W2_SEND_COMMAND;
1186 
1187     connection->transaction_label++;
1188     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1189     connection->command_type = AVRCP_CTYPE_CONTROL;
1190     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1191     connection->subunit_id = AVRCP_SUBUNIT_ID;
1192     int pos = 0;
1193     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1194     pos += 3;
1195     connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME; // PDU ID
1196     connection->cmd_operands[pos++] = 0;
1197 
1198     // Parameter Length
1199     big_endian_store_16(connection->cmd_operands, pos, 1);
1200     pos += 2;
1201     connection->cmd_operands[pos++] = volume;
1202 
1203     connection->cmd_operands_length = pos;
1204     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1205     return ERROR_CODE_SUCCESS;
1206 }
1207 
1208 uint8_t avrcp_controller_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){
1209     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1210     if (!connection){
1211         log_error("avrcp_get_capabilities: could not find a connection.");
1212         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1213     }
1214     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1215     connection->state = AVCTP_W2_SEND_COMMAND;
1216 
1217     connection->transaction_label++;
1218     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1219     connection->command_type = AVRCP_CTYPE_STATUS;
1220     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1221     connection->subunit_id = AVRCP_SUBUNIT_ID;
1222     big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
1223     connection->cmd_operands[3] = AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue; // PDU ID
1224     connection->cmd_operands[4] = 0;
1225     big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length
1226     connection->cmd_operands[7] = 4;                     // NumPlayerApplicationSettingAttributeID
1227     // PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133
1228     connection->cmd_operands[8]  = 0x01;    // equalizer  (1-OFF, 2-ON)
1229     connection->cmd_operands[9]  = 0x02;    // repeat     (1-off, 2-single track, 3-all tracks, 4-group repeat)
1230     connection->cmd_operands[10] = 0x03;    // shuffle    (1-off, 2-all tracks, 3-group shuffle)
1231     connection->cmd_operands[11] = 0x04;    // scan       (1-off, 2-all tracks, 3-group scan)
1232     connection->cmd_operands_length = 12;
1233     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1234     return ERROR_CODE_SUCCESS;
1235 }
1236 
1237 static uint8_t avrcp_controller_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attr_id, uint8_t attr_value){
1238     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1239     if (!connection){
1240         log_error("avrcp_get_capabilities: could not find a connection.");
1241         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1242     }
1243     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1244     connection->state = AVCTP_W2_SEND_COMMAND;
1245 
1246     connection->transaction_label++;
1247     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1248     connection->command_type = AVRCP_CTYPE_CONTROL;
1249     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1250     connection->subunit_id = AVRCP_SUBUNIT_ID;
1251     int pos = 0;
1252     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1253     pos += 3;
1254     connection->cmd_operands[pos++] = AVRCP_PDU_ID_SetPlayerApplicationSettingValue; // PDU ID
1255     connection->cmd_operands[pos++] = 0;
1256     // Parameter Length
1257     big_endian_store_16(connection->cmd_operands, pos, 3);
1258     pos += 2;
1259     connection->cmd_operands[pos++] = 2;
1260     connection->cmd_operands_length = pos;
1261     connection->cmd_operands[pos++]  = attr_id;
1262     connection->cmd_operands[pos++]  = attr_value;
1263     connection->cmd_operands_length = pos;
1264     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1265     return ERROR_CODE_SUCCESS;
1266 }
1267 
1268 uint8_t avrcp_controller_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){
1269     if ((mode < AVRCP_SHUFFLE_MODE_OFF) || (mode > AVRCP_SHUFFLE_MODE_GROUP)) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1270     return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x03, mode);
1271 }
1272 
1273 uint8_t avrcp_controller_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){
1274     if ((mode < AVRCP_REPEAT_MODE_OFF) || (mode > AVRCP_REPEAT_MODE_GROUP)) return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1275     return avrcp_controller_set_current_player_application_setting_value(avrcp_cid, 0x02, mode);
1276 }
1277 
1278 uint8_t avrcp_controller_play_item_for_scope(uint16_t avrcp_cid, uint8_t * uid, uint16_t uid_counter, avrcp_browsing_scope_t scope){
1279     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1280     if (!connection){
1281         log_error("Could not find a connection with cid 0%02x.", avrcp_cid);
1282         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1283     }
1284     if (connection->state != AVCTP_CONNECTION_OPENED){
1285         log_error("Connection in wrong state, expected %d, received %d", AVCTP_CONNECTION_OPENED, connection->state);
1286         return ERROR_CODE_COMMAND_DISALLOWED;
1287     }
1288     connection->state = AVCTP_W2_SEND_COMMAND;
1289 
1290     connection->transaction_label++;
1291     connection->command_type = AVRCP_CTYPE_CONTROL;
1292     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1293     connection->subunit_id = AVRCP_SUBUNIT_ID;
1294     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1295     int pos = 0;
1296     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1297     pos += 3;
1298     connection->cmd_operands[pos++] = AVRCP_PDU_ID_PLAY_ITEM; // PDU ID
1299     // reserved
1300     connection->cmd_operands[pos++] = 0;
1301     // Parameter Length
1302     big_endian_store_16(connection->cmd_operands, pos, 11);
1303     pos += 2;
1304     connection->cmd_operands[pos++]  = scope;
1305     memset(&connection->cmd_operands[pos], 0, 8);
1306     if (uid){
1307         (void)memcpy(&connection->cmd_operands[pos], uid, 8);
1308     }
1309     pos += 8;
1310     big_endian_store_16(connection->cmd_operands, pos, uid_counter);
1311     pos += 2;
1312     connection->cmd_operands_length = pos;
1313 
1314     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1315     return ERROR_CODE_SUCCESS;
1316 }
1317 
1318 uint8_t avrcp_controller_add_item_from_scope_to_now_playing_list(uint16_t avrcp_cid, uint8_t * uid, uint16_t uid_counter, avrcp_browsing_scope_t scope){
1319     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1320     if (!connection){
1321         log_error("Could not find a connection with cid 0%02x.", avrcp_cid);
1322         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1323     }
1324     if (connection->state != AVCTP_CONNECTION_OPENED){
1325         log_error("Connection in wrong state, expected %d, received %d", AVCTP_CONNECTION_OPENED, connection->state);
1326         return ERROR_CODE_COMMAND_DISALLOWED;
1327     }
1328     connection->state = AVCTP_W2_SEND_COMMAND;
1329 
1330     connection->transaction_label++;
1331     connection->command_type = AVRCP_CTYPE_CONTROL;
1332     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1333     connection->subunit_id = AVRCP_SUBUNIT_ID;
1334     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1335     int pos = 0;
1336     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1337     pos += 3;
1338     connection->cmd_operands[pos++] = AVRCP_PDU_ID_ADD_TO_NOW_PLAYING; // PDU ID
1339     // reserved
1340     connection->cmd_operands[pos++] = 0;
1341     // Parameter Length
1342     big_endian_store_16(connection->cmd_operands, pos, 11);
1343     pos += 2;
1344     connection->cmd_operands[pos++]  = scope;
1345     memset(&connection->cmd_operands[pos], 0, 8);
1346     if (uid){
1347         (void)memcpy(&connection->cmd_operands[pos], uid, 8);
1348     }
1349     pos += 8;
1350     big_endian_store_16(connection->cmd_operands, pos, uid_counter);
1351     pos += 2;
1352     connection->cmd_operands_length = pos;
1353 
1354     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1355     return ERROR_CODE_SUCCESS;
1356 }
1357 
1358 uint8_t avrcp_controller_set_max_num_fragments(uint16_t avrcp_cid, uint8_t max_num_fragments){
1359     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1360     if (!connection){
1361         log_error("avrcp_controller_play_item: could not find a connection.");
1362         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1363     }
1364     connection->max_num_fragments = max_num_fragments;
1365     return ERROR_CODE_SUCCESS;
1366 }
1367 
1368 uint8_t avrcp_controller_send_custom_command(uint16_t avrcp_cid, avrcp_command_type_t command_type, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t command_opcode, const uint8_t * command_buffer, uint16_t command_len){
1369     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
1370     if (!connection){
1371         log_error("avrcp_controller_play_item: could not find a connection.");
1372         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1373     }
1374 
1375     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1376     connection->state = AVCTP_W2_SEND_FRAGMENTED_COMMAND;
1377 
1378     connection->transaction_label++;
1379     connection->command_opcode = command_opcode;
1380     connection->command_type = command_type;
1381     connection->subunit_type = subunit_type;
1382     connection->subunit_id = subunit_id;
1383     connection->cmd_operands_fragmented_buffer = command_buffer;
1384     connection->cmd_operands_fragmented_pos = 0;
1385     connection->cmd_operands_fragmented_len = command_len;
1386 
1387     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1388     return ERROR_CODE_SUCCESS;
1389 }
1390