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