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