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