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