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