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