xref: /btstack/src/classic/avrcp_controller.c (revision c4b5c3d5ad0dfb97ce202b96bc9ce3f296ebc992)
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 avrcp_context_t avrcp_controller_context;
52 
53 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){
54     avrcp_create_sdp_record(1, service, service_record_handle, browsing, supported_features, service_name, service_provider_name);
55 }
56 
57 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){
58     if (!callback) return;
59     uint8_t event[8];
60     int pos = 0;
61     event[pos++] = HCI_EVENT_AVRCP_META;
62     event[pos++] = sizeof(event) - 2;
63     event[pos++] = AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE;
64     little_endian_store_16(event, pos, avrcp_cid);
65     pos += 2;
66     event[pos++] = ctype;
67     event[pos++] = repeat_mode;
68     event[pos++] = shuffle_mode;
69     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
70 }
71 
72 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){
73     if (!callback) return;
74     uint8_t event[7];
75     int pos = 0;
76     event[pos++] = HCI_EVENT_AVRCP_META;
77     event[pos++] = sizeof(event) - 2;
78     event[pos++] = subevent;
79     little_endian_store_16(event, pos, avrcp_cid);
80     pos += 2;
81     event[pos++] = ctype;
82     event[pos++] = operation_id;
83     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
84 }
85 
86 static void avrcp_press_and_hold_timeout_handler(btstack_timer_source_t * timer){
87     UNUSED(timer);
88     avrcp_connection_t * connection = btstack_run_loop_get_timer_context(timer);
89     btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
90     btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
91     connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
92     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
93 }
94 
95 static void avrcp_press_and_hold_timer_start(avrcp_connection_t * connection){
96     btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
97     btstack_run_loop_set_timer_handler(&connection->press_and_hold_cmd_timer, avrcp_press_and_hold_timeout_handler);
98     btstack_run_loop_set_timer_context(&connection->press_and_hold_cmd_timer, connection);
99     btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
100     btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
101 }
102 
103 static void avrcp_press_and_hold_timer_stop(avrcp_connection_t * connection){
104     connection->continuous_fast_forward_cmd = 0;
105     btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
106 }
107 
108 static uint8_t request_pass_through_release_control_cmd(avrcp_connection_t * connection){
109     connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
110     if (connection->continuous_fast_forward_cmd){
111         avrcp_press_and_hold_timer_stop(connection);
112     }
113     connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0];
114     connection->transaction_label++;
115     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
116     return ERROR_CODE_SUCCESS;
117 }
118 
119 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, avrcp_context_t * context){
120     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, context);
121     if (!connection){
122         log_error("avrcp: could not find a connection.");
123         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
124     }
125     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
126     connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
127     connection->command_opcode =  AVRCP_CMD_OPCODE_PASS_THROUGH;
128     connection->command_type = AVRCP_CTYPE_CONTROL;
129     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
130     connection->subunit_id =   AVRCP_SUBUNIT_ID;
131     connection->cmd_operands_length = 0;
132 
133     connection->continuous_fast_forward_cmd = continuous_fast_forward_cmd;
134     connection->cmd_operands_length = 2;
135     connection->cmd_operands[0] = opid;
136     if (playback_speed > 0){
137         connection->cmd_operands[2] = playback_speed;
138         connection->cmd_operands_length++;
139     }
140     connection->cmd_operands[1] = connection->cmd_operands_length - 2;
141 
142     if (connection->continuous_fast_forward_cmd){
143         avrcp_press_and_hold_timer_start(connection);
144     }
145 
146     connection->transaction_label++;
147     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
148     return ERROR_CODE_SUCCESS;
149 }
150 
151 static uint8_t request_single_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){
152     return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 0, &avrcp_controller_context);
153 }
154 
155 static uint8_t request_continuous_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){
156     return request_pass_through_press_control_cmd(avrcp_cid, opid, playback_speed, 1, &avrcp_controller_context);
157 }
158 
159 #define AVRCP_CMD_BUFFER_SIZE 30
160 static uint16_t avrcp_get_max_payload_size_for_packet_type(avrcp_packet_type_t packet_type){
161     switch (packet_type){
162         case AVRCP_SINGLE_PACKET:
163             return AVRCP_CMD_BUFFER_SIZE - 3;
164         case AVRCP_START_PACKET:
165             return AVRCP_CMD_BUFFER_SIZE - 4;
166         case AVRCP_CONTINUE_PACKET:
167         case AVRCP_END_PACKET:
168             return AVRCP_CMD_BUFFER_SIZE - 1;
169     }
170 }
171 
172 static int avrcp_send_cmd(avrcp_connection_t * connection, avrcp_packet_type_t packet_type){
173     uint8_t command[AVRCP_CMD_BUFFER_SIZE];
174     int pos = 0;
175     uint16_t max_bytes = sizeof(command) - 1;
176 
177     // transport header
178     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
179     command[pos++] = (connection->transaction_label << 4) | (packet_type << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
180 
181     if (packet_type == AVRCP_START_PACKET){
182         // num packets: (3 bytes overhead (PID, num packets) + command) / (MTU - transport header)
183         command[pos++] = ((connection->cmd_operands_fragmented_len + 3 - 1) / (AVRCP_CMD_BUFFER_SIZE - 1)) + 1;
184         max_bytes -= 3;
185     }
186 
187     if (packet_type == AVRCP_SINGLE_PACKET || packet_type == AVRCP_START_PACKET){
188         // Profile IDentifier (PID)
189         command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
190         command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
191 
192         // command_type
193         command[pos++] = connection->command_type;
194         // subunit_type | subunit ID
195         command[pos++] = (connection->subunit_type << 3) | connection->subunit_id;
196         // opcode
197         command[pos++] = (uint8_t)connection->command_opcode;
198     }
199 
200     if (packet_type == AVRCP_SINGLE_PACKET){
201         // operands
202         memcpy(command+pos, connection->cmd_operands, connection->cmd_operands_length);
203         pos += connection->cmd_operands_length;
204     } else {
205         uint16_t bytes_to_copy = btstack_min(connection->cmd_operands_fragmented_len-connection->cmd_operands_fragmented_pos, max_bytes);
206         memcpy(command+pos, &connection->cmd_operands_fragmented_buffer[connection->cmd_operands_fragmented_pos], bytes_to_copy);
207         pos += bytes_to_copy;
208         connection->cmd_operands_fragmented_pos += bytes_to_copy;
209     }
210 
211     return l2cap_send(connection->l2cap_signaling_cid, command, pos);
212 }
213 
214 static int avrcp_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){
215     if (connection->notifications_to_deregister & (1 << event_id)) return 0;
216     if (connection->notifications_enabled & (1 << event_id)) return 0;
217     if (connection->notifications_to_register & (1 << event_id)) return 0;
218     connection->notifications_to_register |= (1 << event_id);
219     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
220     return 1;
221 }
222 
223 static void avrcp_prepare_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){
224     connection->transaction_label++;
225     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
226     connection->command_type = AVRCP_CTYPE_NOTIFY;
227     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
228     connection->subunit_id = AVRCP_SUBUNIT_ID;
229     int pos = 0;
230     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
231     pos += 3;
232     connection->cmd_operands[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION;
233     connection->cmd_operands[pos++] = 0;                     // reserved(upper 6) | packet_type -> 0
234     big_endian_store_16(connection->cmd_operands, pos, 5);     // parameter length
235     pos += 2;
236     connection->cmd_operands[pos++] = event_id;
237     big_endian_store_32(connection->cmd_operands, pos, 0);
238     pos += 4;
239     connection->cmd_operands_length = pos;
240     // AVRCP_SPEC_V14.pdf 166
241     // answer page 61
242 }
243 
244 
245 static void avrcp_parser_reset(avrcp_connection_t * connection){
246     connection->list_offset = 0;
247     connection->num_attributes = 0;
248     connection->num_parsed_attributes = 0;
249     connection->parser_attribute_header_pos = 0;
250     connection->num_received_fragments = 0;
251     connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER;
252 }
253 
254 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){
255     uint8_t event[7];
256     int pos = 0;
257     event[pos++] = HCI_EVENT_AVRCP_META;
258     event[pos++] = sizeof(event) - 2;
259     event[pos++] = AVRCP_SUBEVENT_NOW_PLAYING_INFO_DONE;
260     little_endian_store_16(event, pos, avrcp_cid);
261     pos += 2;
262     event[pos++] = ctype;
263     event[pos++] = status;
264     // printf_hexdump(event, pos);
265     (*callback)(HCI_EVENT_PACKET, 0, event, pos);
266 }
267 
268 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){
269     uint8_t event[HCI_EVENT_BUFFER_SIZE];
270     int pos = 0;
271     event[pos++] = HCI_EVENT_AVRCP_META;
272     // reserve one byte for subevent type and data len
273     int data_len_pos = pos;
274     pos++;
275     int subevent_type_pos = pos;
276     pos++;
277     little_endian_store_16(event, pos, avrcp_cid);
278     pos += 2;
279     event[pos++] = ctype;
280 
281     switch (attr_id){
282         case AVRCP_MEDIA_ATTR_TITLE:
283             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TITLE_INFO;
284             event[pos++] = value_len;
285             memcpy(event+pos, value, value_len);
286             break;
287         case AVRCP_MEDIA_ATTR_ARTIST:
288             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ARTIST_INFO;
289             event[pos++] = value_len;
290             memcpy(event+pos, value, value_len);
291             break;
292         case AVRCP_MEDIA_ATTR_ALBUM:
293             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_ALBUM_INFO;
294             event[pos++] = value_len;
295             memcpy(event+pos, value, value_len);
296             break;
297         case AVRCP_MEDIA_ATTR_GENRE:
298             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_GENRE_INFO;
299             event[pos++] = value_len;
300             memcpy(event+pos, value, value_len);
301             break;
302         case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS:
303             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_SONG_LENGTH_MS_INFO;
304             if (value){
305                 little_endian_store_32(event, pos, btstack_atoi((char *)value));
306             } else {
307                 little_endian_store_32(event, pos, 0);
308             }
309             pos += 4;
310             break;
311         case AVRCP_MEDIA_ATTR_TRACK:
312             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TRACK_INFO;
313             if (value){
314                 event[pos++] = btstack_atoi((char *)value);
315             } else {
316                 event[pos++] = 0;
317             }
318             break;
319         case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS:
320             event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO;
321             if (value){
322                 event[pos++] = btstack_atoi((char *)value);
323             } else {
324                 event[pos++] = 0;
325             }
326             break;
327         default:
328             break;
329     }
330     event[data_len_pos] = pos - 2;
331     // printf("send attr len %d,  value %s\n", value_len, value);
332     (*callback)(HCI_EVENT_PACKET, 0, event, pos);
333 }
334 
335 static void avrcp_parser_process_byte(uint8_t byte, avrcp_connection_t * connection, avrcp_command_type_t ctype){
336     uint16_t attribute_total_value_len;
337     uint32_t attribute_id;
338     switch(connection->parser_state){
339         case AVRCP_PARSER_GET_ATTRIBUTE_HEADER:
340             connection->parser_attribute_header[connection->parser_attribute_header_pos++] = byte;
341             connection->list_offset++;
342 
343             if (connection->parser_attribute_header_pos < AVRCP_ATTRIBUTE_HEADER_LEN) return;
344 
345             attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6);
346             connection->attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTTE_SIZE);
347             if (connection->attribute_value_len > 0){
348                 // get ready for attribute value
349                 connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_VALUE;
350                 return;
351             }
352 
353             // emit empty attribute
354             attribute_id = big_endian_read_32(connection->parser_attribute_header, 0);
355             avrcp_controller_emit_now_playing_info_event(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, attribute_id, connection->attribute_value, connection->attribute_value_len);
356 
357             // done, see below
358             break;
359 
360         case AVRCP_PARSER_GET_ATTRIBUTE_VALUE:
361             connection->attribute_value[connection->attribute_value_offset++] = byte;
362             connection->list_offset++;
363 
364             if (connection->attribute_value_offset < connection->attribute_value_len) return;
365 
366             // emit (potentially partial) attribute
367             attribute_id = big_endian_read_32(connection->parser_attribute_header, 0);
368             avrcp_controller_emit_now_playing_info_event(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, attribute_id, connection->attribute_value, connection->attribute_value_len);
369 
370             attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6);
371             if (connection->attribute_value_offset < attribute_total_value_len){
372                 // ignore rest of attribute
373                 connection->parser_state = AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE;
374                 return;
375             }
376 
377             // done, see below
378             break;
379 
380         case AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE:
381             connection->attribute_value_offset++;
382             connection->list_offset++;
383 
384             attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6);
385             if (connection->attribute_value_offset < attribute_total_value_len) return;
386 
387             // done, see below
388             break;
389 
390         default:
391             return;
392     }
393 
394     // attribute fully read, check if more to come
395     if (connection->list_offset < connection->list_size){
396         // more to come, reset parser
397         connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER;
398         connection->parser_attribute_header_pos = 0;
399     } else {
400         // fully done
401         avrcp_parser_reset(connection);
402         avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 0);
403     }
404 }
405 
406 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){
407     int i;
408     for (i=0;i<num_bytes_to_read;i++){
409         avrcp_parser_process_byte(packet[i], connection, ctype);
410     }
411 }
412 
413 static uint8_t avrcp_controller_request_abort_continuation(avrcp_connection_t * connection){
414     connection->state = AVCTP_W2_SEND_COMMAND;
415     connection->transaction_label++;
416     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
417     connection->command_type = AVRCP_CTYPE_CONTROL;
418     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
419     connection->subunit_id = AVRCP_SUBUNIT_ID;
420     int pos = 0;
421     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
422     pos += 3;
423     connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE; // PDU ID
424     connection->cmd_operands[pos++] = 0;
425     // Parameter Length
426     connection->cmd_operands_length = 8;
427     big_endian_store_16(connection->cmd_operands, pos, 1);
428     pos += 2;
429     connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
430     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
431     return ERROR_CODE_SUCCESS;
432 }
433 
434 
435 static uint8_t avrcp_controller_request_continue_response(avrcp_connection_t * connection){
436     connection->state = AVCTP_W2_SEND_COMMAND;
437     connection->transaction_label++;
438     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
439     connection->command_type = AVRCP_CTYPE_CONTROL;
440     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
441     connection->subunit_id = AVRCP_SUBUNIT_ID;
442     int pos = 0;
443     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
444     pos += 3;
445     connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE; // PDU ID
446     connection->cmd_operands[pos++] = 0;
447     // Parameter Length
448     connection->cmd_operands_length = 8;
449     big_endian_store_16(connection->cmd_operands, pos, 1);
450     pos += 2;
451     connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
452     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
453     return ERROR_CODE_SUCCESS;
454 }
455 
456 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
457     uint8_t operands[20];
458     uint8_t opcode;
459     int     pos = 3;
460     // uint8_t transport_header = packet[0];
461     // uint8_t transaction_label = transport_header >> 4;
462     // uint8_t packet_type = (transport_header & 0x0F) >> 2;
463     // uint8_t frame_type = (transport_header & 0x03) >> 1;
464     // uint8_t ipid = transport_header & 0x01;
465     // uint8_t byte_value = packet[2];
466     // uint16_t pid = (byte_value << 8) | packet[2];
467 
468     avrcp_command_type_t ctype = (avrcp_command_type_t) packet[pos++];
469     uint8_t byte_value = packet[pos++];
470     avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (byte_value >> 3);
471     avrcp_subunit_type_t subunit_id = (avrcp_subunit_type_t)   (byte_value & 0x07);
472     opcode = packet[pos++];
473 
474     // printf("    Transport header 0x%02x (transaction_label %d, packet_type %d, frame_type %d, ipid %d), pid 0x%4x\n",
475     //     transport_header, transaction_label, packet_type, frame_type, ipid, pid);
476     // // printf_hexdump(packet+pos, size-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             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             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             memcpy(operands, packet+pos, 7);
510             pos += 7;
511             // uint32_t company_id = operands[0] << 16 | operands[1] << 8 | operands[2];
512             pdu_id = operands[3];
513 
514             if (connection->state != AVCTP_W2_RECEIVE_RESPONSE && pdu_id != AVRCP_PDU_ID_REGISTER_NOTIFICATION){
515                 log_info("AVRCP_CMD_OPCODE_VENDOR_DEPENDENT state %d", connection->state);
516                 return;
517             }
518             connection->state = AVCTP_CONNECTION_OPENED;
519 
520 
521             // uint8_t unit_type = operands[4] >> 3;
522             // uint8_t unit = operands[4] & 0x07;
523             param_length = big_endian_read_16(operands, 5);
524 
525             // 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",
526             //     ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id );
527 
528             // if (ctype == AVRCP_CTYPE_RESPONSE_INTERIM) return;
529             log_info("        VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d, status %s", pdu_id, param_length, avrcp_ctype2str(ctype));
530             switch (pdu_id){
531                 case AVRCP_PDU_ID_GetCurrentPlayerApplicationSettingValue:{
532                     uint8_t num_attributes = packet[pos++];
533                     int i;
534                     avrcp_repeat_mode_t  repeat_mode =  AVRCP_REPEAT_MODE_INVALID;
535                     avrcp_shuffle_mode_t shuffle_mode = AVRCP_SHUFFLE_MODE_INVALID;
536                     for (i = 0; i < num_attributes; i++){
537                         uint8_t attribute_id    = packet[pos++];
538                         uint8_t value = packet[pos++];
539                         switch (attribute_id){
540                             case 0x02:
541                                 repeat_mode = (avrcp_repeat_mode_t) value;
542                                 break;
543                             case 0x03:
544                                 shuffle_mode = (avrcp_shuffle_mode_t) value;
545                                 break;
546                             default:
547                                 break;
548                         }
549                     }
550                     avrcp_emit_repeat_and_shuffle_mode(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, repeat_mode, shuffle_mode);
551                     break;
552                 }
553                 case AVRCP_PDU_ID_SetPlayerApplicationSettingValue:{
554                     uint8_t event[6];
555                     int offset = 0;
556                     event[offset++] = HCI_EVENT_AVRCP_META;
557                     event[offset++] = sizeof(event) - 2;
558                     event[offset++] = AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE;
559                     little_endian_store_16(event, offset, connection->avrcp_cid);
560                     offset += 2;
561                     event[offset++] = ctype;
562                     (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
563                     break;
564                 }
565                 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME:{
566                     uint8_t event[7];
567                     int offset = 0;
568                     event[offset++] = HCI_EVENT_AVRCP_META;
569                     event[offset++] = sizeof(event) - 2;
570                     event[offset++] = AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE;
571                     little_endian_store_16(event, offset, connection->avrcp_cid);
572                     offset += 2;
573                     event[offset++] = ctype;
574                     event[offset++] = packet[pos++];
575                     (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
576                     break;
577                 }
578                 case AVRCP_PDU_ID_GET_CAPABILITIES:{
579                     avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos++];
580                     uint8_t capability_count = packet[pos++];
581                     int i;
582                     switch (capability_id){
583                         case AVRCP_CAPABILITY_ID_COMPANY:
584                             // log_info("Supported companies %d: ", capability_count);
585                             for (i = 0; i < capability_count; i++){
586                                 uint32_t company_id = big_endian_read_24(packet, pos);
587                                 pos += 3;
588                                 log_info("  0x%06" PRIx32 ", ", company_id);
589                             }
590                             break;
591                         case AVRCP_CAPABILITY_ID_EVENT:
592                             // log_info("Supported events %d: ", capability_count);
593                             for (i = 0; i < capability_count; i++){
594                                 uint8_t event_id = packet[pos++];
595                                 log_info("  0x%02x %s", event_id, avrcp_event2str(event_id));
596                             }
597                             break;
598                     }
599                     break;
600                 }
601                 case AVRCP_PDU_ID_GET_PLAY_STATUS:{
602                     uint32_t song_length = big_endian_read_32(packet, pos);
603                     pos += 4;
604                     uint32_t song_position = big_endian_read_32(packet, pos);
605                     pos += 4;
606                     uint8_t play_status = packet[pos];
607                     // log_info("        GET_PLAY_STATUS length 0x%04X, position 0x%04X, status %s", song_length, song_position, avrcp_play_status2str(play_status));
608 
609                     uint8_t event[15];
610                     int offset = 0;
611                     event[offset++] = HCI_EVENT_AVRCP_META;
612                     event[offset++] = sizeof(event) - 2;
613                     event[offset++] = AVRCP_SUBEVENT_PLAY_STATUS;
614                     little_endian_store_16(event, offset, connection->avrcp_cid);
615                     offset += 2;
616                     event[offset++] = ctype;
617                     little_endian_store_32(event, offset, song_length);
618                     offset += 4;
619                     little_endian_store_32(event, offset, song_position);
620                     offset += 4;
621                     event[offset++] = play_status;
622                     (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
623                     break;
624                 }
625                 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{
626                     avrcp_notification_event_id_t  event_id = (avrcp_notification_event_id_t) packet[pos++];
627                     uint16_t event_mask = (1 << event_id);
628                     uint16_t reset_event_mask = ~event_mask;
629                     switch (ctype){
630                         case AVRCP_CTYPE_RESPONSE_INTERIM:
631                             // register as enabled
632                             connection->notifications_enabled |= event_mask;
633                             // printf("INTERIM notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled,  connection->notifications_to_register);
634                             break;
635                         case AVRCP_CTYPE_RESPONSE_CHANGED_STABLE:
636                             // received change, event is considered deregistered
637                             // we are re-enabling it automatically, if it is not
638                             // explicitly disabled
639                             connection->notifications_enabled &= reset_event_mask;
640                             if (! (connection->notifications_to_deregister & event_mask)){
641                                 avrcp_register_notification(connection, event_id);
642                                 // printf("CHANGED_STABLE notifications_enabled 0x%2x, notifications_to_register 0x%2x\n", connection->notifications_enabled,  connection->notifications_to_register);
643                             } else {
644                                 connection->notifications_to_deregister &= reset_event_mask;
645                             }
646                             break;
647                         default:
648                             connection->notifications_to_register &= reset_event_mask;
649                             connection->notifications_enabled &= reset_event_mask;
650                             connection->notifications_to_deregister &= reset_event_mask;
651                             break;
652                     }
653 
654                     switch (event_id){
655                         case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:{
656                             uint8_t event[7];
657                             int offset = 0;
658                             event[offset++] = HCI_EVENT_AVRCP_META;
659                             event[offset++] = sizeof(event) - 2;
660                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED;
661                             little_endian_store_16(event, offset, connection->avrcp_cid);
662                             offset += 2;
663                             event[offset++] = ctype;
664                             event[offset++] = packet[pos];
665                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
666                             break;
667                         }
668                         case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:{
669                             uint8_t event[6];
670                             int offset = 0;
671                             event[offset++] = HCI_EVENT_AVRCP_META;
672                             event[offset++] = sizeof(event) - 2;
673                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED;
674                             little_endian_store_16(event, offset, connection->avrcp_cid);
675                             offset += 2;
676                             event[offset++] = ctype;
677                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
678                             break;
679                         }
680                         case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:{
681                             uint8_t event[6];
682                             int offset = 0;
683                             event[offset++] = HCI_EVENT_AVRCP_META;
684                             event[offset++] = sizeof(event) - 2;
685                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED;
686                             little_endian_store_16(event, offset, connection->avrcp_cid);
687                             offset += 2;
688                             event[offset++] = ctype;
689                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
690                             break;
691                         }
692                         case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:{
693                             uint8_t event[6];
694                             int offset = 0;
695                             event[offset++] = HCI_EVENT_AVRCP_META;
696                             event[offset++] = sizeof(event) - 2;
697                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED;
698                             little_endian_store_16(event, offset, connection->avrcp_cid);
699                             offset += 2;
700                             event[offset++] = ctype;
701                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
702                             break;
703                         }
704                         case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:{
705                             uint8_t event[7];
706                             int offset = 0;
707                             event[offset++] = HCI_EVENT_AVRCP_META;
708                             event[offset++] = sizeof(event) - 2;
709                             event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED;
710                             little_endian_store_16(event, offset, connection->avrcp_cid);
711                             offset += 2;
712                             event[offset++] = ctype;
713                             event[offset++] = packet[pos++] & 0x7F;
714                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
715                             break;
716                         }
717                         case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:{
718                             uint8_t event[7];
719                             int offset = 0;
720                             event[offset++] = HCI_EVENT_AVRCP_META;
721                             event[offset++] = sizeof(event) - 2;
722                             event[offset++] = AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED;
723                             little_endian_store_16(event, offset, connection->avrcp_cid);
724                             offset += 2;
725                             event[offset++] = ctype;
726                             event[offset++] = packet[pos++] & 0x7F;
727                             (*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
728                             break;
729                         }
730 
731                         // case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:{
732                         //     uint8_t num_PlayerApplicationSettingAttributes = packet[pos++];
733                         //     int i;
734                         //     for (i = 0; i < num_PlayerApplicationSettingAttributes; i++){
735                         //         uint8_t PlayerApplicationSetting_AttributeID = packet[pos++];
736                         //         uint8_t PlayerApplicationSettingValueID = packet[pos++];
737                         //     }
738                         //     break;
739                         // }
740                         // case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED:
741                         //     uint16_t player_id = big_endian_read_16(packet, pos);
742                         //     pos += 2;
743                         //     uint16_t uid_counter = big_endian_read_16(packet, pos);
744                         //     pos += 2;
745                         //     break;
746                         // case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:
747                         //     uint16_t uid_counter = big_endian_read_16(packet, pos);
748                         //     pos += 2;
749                         //     break;
750                         default:
751                             log_info("avrcp: not implemented");
752                             break;
753                     }
754                     if (connection->notifications_to_register != 0){
755                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
756                     }
757                     break;
758                 }
759 
760                 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{
761                     avrcp_packet_type_t packet_type = operands[4] & 0x03;
762                     switch (packet_type){
763                         case AVRCP_START_PACKET:
764                         case AVRCP_SINGLE_PACKET:
765                             avrcp_parser_reset(connection);
766                             connection->list_size = param_length;
767                             connection->num_attributes = packet[pos++];
768 
769                             // printf("AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES num_attributes %d, total size %d, packet type 0x%02x \n", connection->num_attributes, connection->list_size, operands[4] & 0x03);
770                             avrcp_source_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype);
771 
772                             if (packet_type == AVRCP_START_PACKET){
773                                 avrcp_controller_request_continue_response(connection);
774                             }
775                             break;
776                         case AVRCP_CONTINUE_PACKET:
777                         case AVRCP_END_PACKET:
778                             connection->num_received_fragments++;
779                             if (connection->num_received_fragments < connection->max_num_fragments){
780                                 avrcp_source_parse_and_emit_element_attrs(packet+pos, size-pos, connection, ctype);
781                                 if (packet_type == AVRCP_CONTINUE_PACKET){
782                                     avrcp_controller_request_continue_response(connection);
783                                 }
784                             } else {
785                                 avrcp_controller_request_abort_continuation(connection);
786                                 avrcp_controller_emit_now_playing_info_event_done(avrcp_controller_context.avrcp_callback, connection->avrcp_cid, ctype, 1);
787                                 avrcp_parser_reset(connection);
788                             }
789                             break;
790                     }
791                 }
792                 default:
793                     break;
794             }
795             break;
796         case AVRCP_CMD_OPCODE_PASS_THROUGH:{
797             // 0x80 | connection->cmd_operands[0]
798             uint8_t operation_id = packet[pos++];
799             switch (connection->state){
800                 case AVCTP_W2_RECEIVE_PRESS_RESPONSE:
801                     if (connection->continuous_fast_forward_cmd){
802                         connection->state = AVCTP_W4_STOP;
803                     } else {
804                         connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
805                     }
806                     break;
807                 case AVCTP_W2_RECEIVE_RESPONSE:
808                     connection->state = AVCTP_CONNECTION_OPENED;
809                     break;
810                 default:
811                     // check for notifications? move state transition down
812                     // log_info("AVRCP_CMD_OPCODE_PASS_THROUGH state %d\n", connection->state);
813                     break;
814             }
815             if (connection->state == AVCTP_W4_STOP){
816                 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_START, connection->avrcp_cid, ctype, operation_id);
817             }
818             if (connection->state == AVCTP_CONNECTION_OPENED) {
819                 // RELEASE response
820                 operation_id = operation_id & 0x7F;
821                 avrcp_emit_operation_status(avrcp_controller_context.avrcp_callback, AVRCP_SUBEVENT_OPERATION_COMPLETE, connection->avrcp_cid, ctype, operation_id);
822             }
823             if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){
824                 // PRESS response
825                 request_pass_through_release_control_cmd(connection);
826             }
827             break;
828         }
829         default:
830             break;
831     }
832 }
833 
834 static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){
835     int i;
836     switch (connection->state){
837         case AVCTP_W2_SEND_PRESS_COMMAND:
838             connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE;
839             avrcp_send_cmd(connection, AVRCP_SINGLE_PACKET);
840             break;
841         case AVCTP_W2_SEND_COMMAND:
842         case AVCTP_W2_SEND_RELEASE_COMMAND:
843             connection->state = AVCTP_W2_RECEIVE_RESPONSE;
844             avrcp_send_cmd(connection, AVRCP_SINGLE_PACKET);
845             break;
846         case AVCTP_CONNECTION_OPENED:
847             if (connection->notifications_to_register != 0){
848                 for (i = 1; i <= AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED; i++){
849                     if (connection->notifications_to_register & (1<<i)){
850                         connection->notifications_to_register &= ~ (1 << i);
851                         avrcp_prepare_notification(connection, (avrcp_notification_event_id_t) i);
852                         connection->state = AVCTP_W2_RECEIVE_RESPONSE;
853                         avrcp_send_cmd(connection, AVRCP_SINGLE_PACKET);
854                         return;
855                     }
856                 }
857             }
858             return;
859         case AVCTP_W2_SEND_FRAGMENTED_COMMAND:
860             if (connection->cmd_operands_fragmented_pos == 0){
861                  avrcp_send_cmd(connection, AVRCP_START_PACKET);
862                  avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
863             } else {
864                 if (connection->cmd_operands_fragmented_len - connection->cmd_operands_fragmented_pos > avrcp_get_max_payload_size_for_packet_type(AVRCP_CONTINUE_PACKET)){
865                      avrcp_send_cmd(connection, AVRCP_CONTINUE_PACKET);
866                      avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
867                  } else {
868                     connection->state = AVCTP_W2_RECEIVE_RESPONSE;
869                     avrcp_send_cmd(connection, AVRCP_END_PACKET);
870                  }
871             }
872         default:
873             return;
874     }
875 }
876 
877 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
878     avrcp_connection_t * connection;
879 
880     switch (packet_type) {
881         case L2CAP_DATA_PACKET:
882             connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context);
883             if (!connection) break;
884             avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size);
885             break;
886         case HCI_EVENT_PACKET:
887             switch (hci_event_packet_get_type(packet)){
888                 case L2CAP_EVENT_CAN_SEND_NOW:
889                     connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_controller_context);
890                     if (!connection) break;
891                     avrcp_controller_handle_can_send_now(connection);
892                     break;
893             default:
894                 avrcp_packet_handler(packet_type, channel, packet, size, &avrcp_controller_context);
895                 break;
896         }
897         default:
898             break;
899     }
900 }
901 
902 void avrcp_controller_init(void){
903     avrcp_controller_context.role = AVRCP_CONTROLLER;
904     avrcp_controller_context.connections = NULL;
905     avrcp_controller_context.packet_handler = avrcp_controller_packet_handler;
906     l2cap_register_service(&avrcp_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0);
907 }
908 
909 void avrcp_controller_register_packet_handler(btstack_packet_handler_t callback){
910     if (callback == NULL){
911         log_error("avrcp_register_packet_handler called with NULL callback");
912         return;
913     }
914     avrcp_controller_context.avrcp_callback = callback;
915 }
916 
917 uint8_t avrcp_controller_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){
918     return avrcp_connect(bd_addr, &avrcp_controller_context, avrcp_cid);
919 }
920 
921 uint8_t avrcp_controller_unit_info(uint16_t avrcp_cid){
922     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
923     if (!connection){
924         log_error("avrcp_unit_info: could not find a connection.");
925         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
926     }
927     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
928     connection->state = AVCTP_W2_SEND_COMMAND;
929 
930     connection->transaction_label++;
931     connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO;
932     connection->command_type = AVRCP_CTYPE_STATUS;
933     connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
934     connection->subunit_id =   AVRCP_SUBUNIT_ID_IGNORE;
935     memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length);
936     connection->cmd_operands_length = 5;
937     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
938     return ERROR_CODE_SUCCESS;
939 }
940 
941 uint8_t avrcp_controller_subunit_info(uint16_t avrcp_cid){
942     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
943     if (!connection){
944         log_error("avrcp_unit_info: could not find a connection.");
945         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
946     }
947     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
948     connection->state = AVCTP_W2_SEND_COMMAND;
949 
950     connection->transaction_label++;
951     connection->command_opcode = AVRCP_CMD_OPCODE_SUBUNIT_INFO;
952     connection->command_type = AVRCP_CTYPE_STATUS;
953     connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
954     connection->subunit_id =   AVRCP_SUBUNIT_ID_IGNORE;
955     memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length);
956     connection->cmd_operands[0] = 7; // page: 0, extention_code: 7
957     connection->cmd_operands_length = 5;
958     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
959     return ERROR_CODE_SUCCESS;
960 }
961 
962 static uint8_t avrcp_controller_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){
963     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
964     if (!connection){
965         log_error("avrcp_get_capabilities: could not find a connection.");
966         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
967     }
968     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
969     connection->state = AVCTP_W2_SEND_COMMAND;
970 
971     connection->transaction_label++;
972     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
973     connection->command_type = AVRCP_CTYPE_STATUS;
974     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
975     connection->subunit_id = AVRCP_SUBUNIT_ID;
976     big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
977     connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID
978     connection->cmd_operands[4] = 0;
979     big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length
980     connection->cmd_operands[7] = capability_id;                  // capability ID
981     connection->cmd_operands_length = 8;
982     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
983     return ERROR_CODE_SUCCESS;
984 }
985 
986 uint8_t avrcp_controller_get_supported_company_ids(uint16_t avrcp_cid){
987     return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY);
988 }
989 
990 uint8_t avrcp_controller_get_supported_events(uint16_t avrcp_cid){
991     return avrcp_controller_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT);
992 }
993 
994 
995 uint8_t avrcp_controller_play(uint16_t avrcp_cid){
996     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0);
997 }
998 
999 uint8_t avrcp_controller_stop(uint16_t avrcp_cid){
1000     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0);
1001 }
1002 
1003 uint8_t avrcp_controller_pause(uint16_t avrcp_cid){
1004     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0);
1005 }
1006 
1007 uint8_t avrcp_controller_forward(uint16_t avrcp_cid){
1008     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0);
1009 }
1010 
1011 uint8_t avrcp_controller_backward(uint16_t avrcp_cid){
1012     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0);
1013 }
1014 
1015 uint8_t avrcp_controller_start_rewind(uint16_t avrcp_cid){
1016     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0);
1017 }
1018 
1019 uint8_t avrcp_controller_volume_up(uint16_t avrcp_cid){
1020     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0);
1021 }
1022 
1023 uint8_t avrcp_controller_volume_down(uint16_t avrcp_cid){
1024     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0);
1025 }
1026 
1027 uint8_t avrcp_controller_mute(uint16_t avrcp_cid){
1028     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0);
1029 }
1030 
1031 uint8_t avrcp_controller_skip(uint16_t avrcp_cid){
1032     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0);
1033 }
1034 
1035 uint8_t avrcp_controller_stop_rewind(uint16_t avrcp_cid){
1036     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
1037     if (!connection){
1038         log_error("avrcp_stop_rewind: could not find a connection.");
1039         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1040     }
1041     if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED;
1042     return request_pass_through_release_control_cmd(connection);
1043 }
1044 
1045 uint8_t avrcp_controller_start_fast_forward(uint16_t avrcp_cid){
1046     return request_continuous_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
1047 }
1048 
1049 uint8_t avrcp_controller_fast_forward(uint16_t avrcp_cid){
1050     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
1051 }
1052 
1053 uint8_t avrcp_controller_rewind(uint16_t avrcp_cid){
1054     return request_single_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0);
1055 }
1056 
1057 
1058 uint8_t avrcp_controller_stop_fast_forward(uint16_t avrcp_cid){
1059     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
1060     if (!connection){
1061         log_error("avrcp_stop_fast_forward: could not find a connection.");
1062         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1063     }
1064     if (connection->state != AVCTP_W4_STOP) return ERROR_CODE_COMMAND_DISALLOWED;
1065     return request_pass_through_release_control_cmd(connection);
1066 }
1067 
1068 uint8_t avrcp_controller_get_play_status(uint16_t avrcp_cid){
1069     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
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(avrcp_cid, &avrcp_controller_context);
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(avrcp_cid, &avrcp_controller_context);
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(avrcp_cid, &avrcp_controller_context);
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(avrcp_cid, &avrcp_controller_context);
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(avrcp_cid, &avrcp_controller_context);
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(avrcp_cid, &avrcp_controller_context);
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(avrcp_cid, &avrcp_controller_context);
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_disconnect(uint16_t avrcp_cid){
1279     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
1280     if (!connection){
1281         log_error("avrcp_get_capabilities: 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     if (connection->browsing_connection){
1286         if (connection->browsing_connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1287         l2cap_disconnect(connection->browsing_connection->l2cap_browsing_cid, 0);
1288     }
1289     l2cap_disconnect(connection->l2cap_signaling_cid, 0);
1290     return ERROR_CODE_SUCCESS;
1291 }
1292 
1293 uint8_t avrcp_controller_play_item_for_scope(uint16_t avrcp_cid, uint8_t * uid, uint16_t uid_counter, avrcp_browsing_scope_t scope){
1294     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
1295     if (!connection){
1296         log_error("Could not find a connection with cid 0%02x.", avrcp_cid);
1297         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1298     }
1299     if (connection->state != AVCTP_CONNECTION_OPENED){
1300         log_error("Connection in wrong state, expected %d, received %d", AVCTP_CONNECTION_OPENED, connection->state);
1301         return ERROR_CODE_COMMAND_DISALLOWED;
1302     }
1303     connection->state = AVCTP_W2_SEND_COMMAND;
1304 
1305     connection->transaction_label++;
1306     connection->command_type = AVRCP_CTYPE_CONTROL;
1307     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1308     connection->subunit_id = AVRCP_SUBUNIT_ID;
1309     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1310     int pos = 0;
1311     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1312     pos += 3;
1313     connection->cmd_operands[pos++] = AVRCP_PDU_ID_PLAY_ITEM; // PDU ID
1314     // reserved
1315     connection->cmd_operands[pos++] = 0;
1316     // Parameter Length
1317     big_endian_store_16(connection->cmd_operands, pos, 11);
1318     pos += 2;
1319     connection->cmd_operands[pos++]  = scope;
1320     memset(&connection->cmd_operands[pos], 0, 8);
1321     if (uid){
1322         memcpy(&connection->cmd_operands[pos], uid, 8);
1323     }
1324     pos += 8;
1325     big_endian_store_16(connection->cmd_operands, pos, uid_counter);
1326     pos += 2;
1327     connection->cmd_operands_length = pos;
1328 
1329     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1330     return ERROR_CODE_SUCCESS;
1331 }
1332 
1333 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){
1334     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
1335     if (!connection){
1336         log_error("Could not find a connection with cid 0%02x.", avrcp_cid);
1337         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1338     }
1339     if (connection->state != AVCTP_CONNECTION_OPENED){
1340         log_error("Connection in wrong state, expected %d, received %d", AVCTP_CONNECTION_OPENED, connection->state);
1341         return ERROR_CODE_COMMAND_DISALLOWED;
1342     }
1343     connection->state = AVCTP_W2_SEND_COMMAND;
1344 
1345     connection->transaction_label++;
1346     connection->command_type = AVRCP_CTYPE_CONTROL;
1347     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
1348     connection->subunit_id = AVRCP_SUBUNIT_ID;
1349     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
1350     int pos = 0;
1351     big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
1352     pos += 3;
1353     connection->cmd_operands[pos++] = AVRCP_PDU_ID_ADD_TO_NOW_PLAYING; // PDU ID
1354     // reserved
1355     connection->cmd_operands[pos++] = 0;
1356     // Parameter Length
1357     big_endian_store_16(connection->cmd_operands, pos, 11);
1358     pos += 2;
1359     connection->cmd_operands[pos++]  = scope;
1360     memset(&connection->cmd_operands[pos], 0, 8);
1361     if (uid){
1362         memcpy(&connection->cmd_operands[pos], uid, 8);
1363     }
1364     pos += 8;
1365     big_endian_store_16(connection->cmd_operands, pos, uid_counter);
1366     pos += 2;
1367     connection->cmd_operands_length = pos;
1368 
1369     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1370     return ERROR_CODE_SUCCESS;
1371 }
1372 
1373 uint8_t avrcp_controller_set_max_num_fragments(uint16_t avrcp_cid, uint8_t max_num_fragments){
1374     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
1375     if (!connection){
1376         log_error("avrcp_controller_play_item: could not find a connection.");
1377         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1378     }
1379     connection->max_num_fragments = max_num_fragments;
1380     return ERROR_CODE_SUCCESS;
1381 }
1382 
1383 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){
1384     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
1385     if (!connection){
1386         log_error("avrcp_controller_play_item: could not find a connection.");
1387         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1388     }
1389 
1390     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
1391     connection->state = AVCTP_W2_SEND_FRAGMENTED_COMMAND;
1392 
1393     connection->transaction_label++;
1394     connection->command_opcode = command_opcode;
1395     connection->command_type = command_type;
1396     connection->subunit_type = subunit_type;
1397     connection->subunit_id = subunit_id;
1398     connection->cmd_operands_fragmented_buffer = command_buffer;
1399     connection->cmd_operands_fragmented_pos = 0;
1400     connection->cmd_operands_fragmented_len = command_len;
1401 
1402     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1403     return ERROR_CODE_SUCCESS;
1404 }
1405