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