xref: /btstack/src/classic/avrcp_target.c (revision c1b6583a190ace9247a1f81941d6be4382eb4f1e)
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 BLUEKITCHEN
24  * GMBH 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_target.c"
39 
40 #include <stdint.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <inttypes.h>
44 
45 #include "classic/avrcp.h"
46 #include "classic/avrcp_target.h"
47 
48 #include "bluetooth_sdp.h"
49 #include "btstack_debug.h"
50 #include "btstack_event.h"
51 #include "btstack_util.h"
52 #include "l2cap.h"
53 
54 #include <stdio.h>
55 #define AVRCP_ATTR_HEADER_LEN  8
56 
57 static const uint8_t AVRCP_NOTIFICATION_TRACK_SELECTED[] = {0,0,0,0,0,0,0,0};
58 static const uint8_t AVRCP_NOTIFICATION_TRACK_NOT_SELECTED[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
59 
60 static const char * avrcp_default_target_service_name = "AVRCP Target";
61 static const char * avrcp_default_target_service_provider_name = "BlueKitchen";
62 
63 avrcp_context_t avrcp_target_context;
64 
65 static uint32_t default_companies[] = {
66     0x581900 //BT SIG registered CompanyID
67 };
68 
69 static int avrcp_target_supports_browsing(uint16_t target_supported_features){
70     return target_supported_features & AVRCP_FEATURE_MASK_BROWSING;
71 }
72 
73 void avrcp_target_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t supported_features, const char * service_name, const char * service_provider_name){
74     if (service_name == NULL){
75         service_name = avrcp_default_target_service_name;
76     }
77     if (service_provider_name == NULL){
78         service_provider_name = avrcp_default_target_service_provider_name;
79     }
80     avrcp_create_sdp_record(false, service, service_record_handle, avrcp_target_supports_browsing(supported_features), supported_features, service_name, service_provider_name);
81 }
82 
83 static void
84 avrcp_target_emit_operation(btstack_packet_handler_t callback, uint16_t avrcp_cid, avrcp_operation_id_t operation_id,
85                             bool button_pressed, uint8_t operands_length, uint8_t operand) {
86     btstack_assert(callback != NULL);
87 
88     uint8_t event[9];
89     int pos = 0;
90     event[pos++] = HCI_EVENT_AVRCP_META;
91     event[pos++] = sizeof(event) - 2;
92     event[pos++] = AVRCP_SUBEVENT_OPERATION;
93     little_endian_store_16(event, pos, avrcp_cid);
94     pos += 2;
95     event[pos++] = operation_id;
96     event[pos++] = button_pressed ? 1 : 0;
97     event[pos++] = operands_length;
98     event[pos++] = operand;
99     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
100 }
101 
102 static void avrcp_target_emit_volume_changed(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t absolute_volume){
103     btstack_assert(callback != NULL);
104 
105     uint8_t event[7];
106     int offset = 0;
107     event[offset++] = HCI_EVENT_AVRCP_META;
108     event[offset++] = sizeof(event) - 2;
109     event[offset++] = AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED;
110     little_endian_store_16(event, offset, avrcp_cid);
111     offset += 2;
112     event[offset++] = AVRCP_CTYPE_NOTIFY;
113     event[offset++] = absolute_volume;
114     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
115 }
116 
117 static void avrcp_target_emit_respond_vendor_dependent_query(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t subevent_id){
118     btstack_assert(callback != NULL);
119 
120     uint8_t event[5];
121     int pos = 0;
122     event[pos++] = HCI_EVENT_AVRCP_META;
123     event[pos++] = sizeof(event) - 2;
124     event[pos++] = subevent_id;
125     little_endian_store_16(event, pos, avrcp_cid);
126     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
127 }
128 
129 static void avrcp_target_emit_respond_play_item(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint16_t uid_counter, avrcp_browsing_scope_t scope, uint8_t * uid){
130     btstack_assert(callback != NULL);
131 
132     uint8_t event[16];
133     int pos = 0;
134     event[pos++] = HCI_EVENT_AVRCP_META;
135     event[pos++] = sizeof(event) - 2;
136     event[pos++] = AVRCP_SUBEVENT_PLAY_ITEM;
137     little_endian_store_16(event, pos, avrcp_cid);
138     pos += 2;
139     little_endian_store_16(event, pos, uid_counter);
140     pos += 2;
141     event[pos++] = (uint8_t) scope;
142     memcpy(&event[pos], uid, 8);
143     pos += 8;
144 
145     (*callback)(HCI_EVENT_PACKET, 0, event, pos);
146 }
147 
148 
149 static void avrcp_target_emit_add_to_now_playing_item(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint16_t uid_counter, avrcp_browsing_scope_t scope, uint8_t * uid){
150     btstack_assert(callback != NULL);
151 
152     uint8_t event[16];
153     int pos = 0;
154     event[pos++] = HCI_EVENT_AVRCP_META;
155     event[pos++] = sizeof(event) - 2;
156     event[pos++] = AVRCP_SUBEVENT_ADD_TO_NOW_PLAYING;
157     little_endian_store_16(event, pos, avrcp_cid);
158     pos += 2;
159     little_endian_store_16(event, pos, uid_counter);
160     pos += 2;
161     event[pos++] = (uint8_t) scope;
162     memcpy(&event[pos], uid, 8);
163     pos += 8;
164 
165     (*callback)(HCI_EVENT_PACKET, 0, event, pos);
166 }
167 
168 
169 // returns number of bytes stored
170 static uint16_t avrcp_target_pack_single_element_header(uint8_t * buffer, avrcp_media_attribute_id_t attr_id, uint16_t attr_value_size){
171     btstack_assert(attr_id > AVRCP_MEDIA_ATTR_ALL);
172     btstack_assert(attr_id < AVRCP_MEDIA_ATTR_NUM);
173     uint16_t pos = 0;
174     big_endian_store_32(buffer, pos, attr_id);
175     big_endian_store_16(buffer, pos + 4, RFC2978_CHARSET_MIB_UTF8);
176     big_endian_store_16(buffer, pos + 6, attr_value_size);
177     return 8;
178 }
179 
180 static uint16_t avrcp_now_playing_info_attr_id_value_len(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id){
181     char buffer[AVRCP_MAX_ATTRIBUTE_SIZE];
182     uint16_t str_len;
183     switch (attr_id) {
184         case AVRCP_MEDIA_ATTR_ALL:
185         case AVRCP_MEDIA_ATTR_NONE:
186             return 0;
187         case AVRCP_MEDIA_ATTR_TRACK:
188             str_len = btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%" PRIu32, connection->target_track_nr);
189             break;
190         case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS:
191             str_len = btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%" PRIu32, connection->target_total_tracks);
192             break;
193         case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS:
194             str_len = btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%" PRIu32, connection->target_song_length_ms);
195             break;
196         default:
197             str_len = connection->target_now_playing_info[(uint16_t)attr_id - 1].len;
198             break;
199     }
200     return str_len;
201 }
202 
203 static uint16_t avrcp_now_playing_info_value_len_with_headers(avrcp_connection_t * connection){
204     uint16_t playing_info_len = 0;
205 
206     uint8_t i;
207     for ( i = (uint8_t)AVRCP_MEDIA_ATTR_ALL + 1; i < (uint8_t) AVRCP_MEDIA_ATTR_NUM; i++){
208         avrcp_media_attribute_id_t attr_id = (avrcp_media_attribute_id_t) i;
209 
210         if ((connection->target_now_playing_info_attr_bitmap & (1 << attr_id)) == 0) {
211             continue;
212         }
213 
214         switch (attr_id) {
215             case AVRCP_MEDIA_ATTR_ALL:
216             case AVRCP_MEDIA_ATTR_NONE:
217             case AVRCP_MEDIA_ATTR_DEFAULT_COVER_ART:
218                 break;
219             default:
220                 playing_info_len += AVRCP_ATTR_HEADER_LEN + avrcp_now_playing_info_attr_id_value_len(connection, attr_id);
221                 break;
222         }
223     }
224     // for total num bytes that of the attributes + headers
225     playing_info_len += 1;
226     return playing_info_len;
227 }
228 
229 static uint8_t * avrcp_get_attribute_value_from_u32(avrcp_connection_t * connection, uint32_t value, uint16_t * num_bytes_to_copy){
230     *num_bytes_to_copy = 0;
231 
232     if (connection->attribute_value_len == 0){
233 		// "4294967296" = 10 chars + \0
234         connection->attribute_value_len = btstack_snprintf_assert_complete((char *)connection->attribute_value, 11, "%" PRIu32, value);
235         connection->attribute_value_offset = 0;
236     }
237     *num_bytes_to_copy = connection->attribute_value_len - connection->attribute_value_offset;
238     return connection->attribute_value + connection->attribute_value_offset;
239 }
240 
241 static uint8_t * avrcp_get_next_value_fragment_for_attribute_id(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id, uint16_t * num_bytes_to_copy){
242     switch (attr_id){
243         case AVRCP_MEDIA_ATTR_TRACK:
244             return avrcp_get_attribute_value_from_u32(connection, connection->target_track_nr, num_bytes_to_copy);
245         case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS:
246             return avrcp_get_attribute_value_from_u32(connection, connection->target_total_tracks, num_bytes_to_copy);
247         case AVRCP_MEDIA_ATTR_SONG_LENGTH_MS:
248             return avrcp_get_attribute_value_from_u32(connection, connection->target_song_length_ms, num_bytes_to_copy);
249         default:
250             break;
251     }
252     int attr_index = attr_id - 1;
253     if (connection->attribute_value_len == 0){
254         connection->attribute_value_len = avrcp_now_playing_info_attr_id_value_len(connection, attr_id);
255         connection->attribute_value_offset = 0;
256     }
257     *num_bytes_to_copy = connection->target_now_playing_info[attr_index].len - connection->attribute_value_offset;
258     return (uint8_t *) (connection->target_now_playing_info[attr_index].value + connection->attribute_value_offset);
259 }
260 
261 // TODO Review
262 static uint16_t avrcp_store_avctp_now_playing_info_fragment(avrcp_connection_t * connection, uint16_t packet_size, uint8_t * packet){
263     uint16_t num_free_bytes = packet_size;
264 
265     uint16_t bytes_stored = 0;
266 
267     while ((num_free_bytes > 0) && (connection->next_attr_id <= AVRCP_MEDIA_ATTR_SONG_LENGTH_MS)){
268         if ((connection->target_now_playing_info_attr_bitmap & (1 << (uint8_t)connection->next_attr_id)) == 0) {
269             connection->next_attr_id = (avrcp_media_attribute_id_t) (((int) connection->next_attr_id) + 1);
270             continue;
271         }
272 
273         // prepare attribute value
274         uint16_t num_bytes_to_copy;
275         uint8_t * attr_value_with_offset = avrcp_get_next_value_fragment_for_attribute_id(connection,
276                                                                                           connection->next_attr_id,
277                                                                                           &num_bytes_to_copy);
278 
279         // store header
280         if (connection->attribute_value_offset == 0){
281             // pack the whole attribute value header
282             if (connection->parser_attribute_header_pos == 0) {
283                 avrcp_target_pack_single_element_header(connection->parser_attribute_header, connection->next_attr_id,
284                                                         connection->attribute_value_len);
285             }
286         }
287 
288         if (connection->parser_attribute_header_pos < AVRCP_ATTRIBUTE_HEADER_LEN){
289             uint16_t num_header_bytes_to_store = btstack_min(num_free_bytes, AVRCP_ATTRIBUTE_HEADER_LEN - connection->parser_attribute_header_pos);
290             memcpy(packet + bytes_stored, connection->parser_attribute_header + connection->parser_attribute_header_pos, num_header_bytes_to_store);
291             connection->parser_attribute_header_pos += num_header_bytes_to_store;
292             bytes_stored += num_header_bytes_to_store;
293             num_free_bytes -= num_header_bytes_to_store;
294             connection->data_offset += num_header_bytes_to_store;
295 
296             if (num_free_bytes == 0){
297                 continue;
298             }
299         }
300 
301         // store value
302         uint16_t num_attr_value_bytes_to_store = btstack_min(num_free_bytes, connection->attribute_value_len - connection->attribute_value_offset);
303         memcpy(packet + bytes_stored, attr_value_with_offset, num_attr_value_bytes_to_store);
304         bytes_stored   += num_attr_value_bytes_to_store;
305         num_free_bytes -= num_attr_value_bytes_to_store;
306         connection->attribute_value_offset += num_attr_value_bytes_to_store;
307         connection->data_offset += num_attr_value_bytes_to_store;
308 
309         if (connection->attribute_value_offset == connection->attribute_value_len){
310             // C++ compatible version of connection->next_attr_id++
311             connection->next_attr_id = (avrcp_media_attribute_id_t) (((int) connection->next_attr_id) + 1);
312             connection->attribute_value_offset = 0;
313             connection->attribute_value_len = 0;
314             connection->parser_attribute_header_pos = 0;
315         }
316     }
317     return bytes_stored;
318 }
319 
320 static void avrcp_send_response_with_avctp_fragmentation(avrcp_connection_t * connection){
321     l2cap_reserve_packet_buffer();
322     uint8_t * packet = l2cap_get_outgoing_buffer();
323 
324     // transport header
325     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
326 
327     uint16_t max_payload_size;
328     connection->avctp_packet_type = avctp_get_packet_type(connection, &max_payload_size);
329     connection->avrcp_packet_type = avrcp_get_packet_type(connection);
330 
331     // AVCTP header
332     // transport header : transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
333     uint16_t pos = 0;
334     packet[pos++] = (connection->transaction_id << 4) | (connection->avctp_packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0;
335 
336     uint16_t param_len = connection->data_len;
337 
338     if (connection->avctp_packet_type == AVCTP_START_PACKET){
339         uint16_t max_frame_size = btstack_min(connection->l2cap_mtu, AVRCP_MAX_AV_C_MESSAGE_FRAME_SIZE);
340         // first packet: max_payload_size
341         // rest packets
342         uint16_t num_payload_bytes = param_len - max_payload_size;
343         uint16_t frame_size_for_continue_packet = max_frame_size - avctp_get_num_bytes_for_header(AVCTP_CONTINUE_PACKET);
344         uint16_t num_avctp_packets = (num_payload_bytes + frame_size_for_continue_packet - 1)/frame_size_for_continue_packet + 1;
345 		btstack_assert(num_avctp_packets <= 255);
346         packet[pos++] = (uint8_t) num_avctp_packets;
347     }
348 
349     uint16_t bytes_stored = 0;
350     uint8_t i;
351 
352     switch (connection->avctp_packet_type) {
353         case AVCTP_SINGLE_PACKET:
354         case AVCTP_START_PACKET:
355             // Profile IDentifier (PID)
356             packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
357             packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
358 
359             // AVRCP message
360             // command_type
361             packet[pos++] = connection->command_type;
362             // subunit_type | subunit ID
363             packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id;
364             // opcode
365             packet[pos++] = (uint8_t) connection->command_opcode;
366 
367             switch (connection->command_opcode) {
368                 case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT:
369                     big_endian_store_24(packet, pos, connection->company_id);
370                     pos += 3;
371                     packet[pos++] = connection->pdu_id;
372                     // AVRCP packet type
373 
374                     packet[pos++] = (uint8_t)connection->avrcp_packet_type;
375                     // parameter length
376                     big_endian_store_16(packet, pos, param_len);
377                     pos += 2;
378 
379                     switch (connection->pdu_id) {
380                         // message is small enough to fit the single packet, no need for extra check
381                         case AVRCP_PDU_ID_GET_CAPABILITIES:
382                             // capability ID
383                             packet[pos++] = connection->data[0];
384                             // num_capabilities
385                             packet[pos++] = connection->data[1];
386 
387                             switch ((avrcp_capability_id_t) connection->data[0]) {
388                                 case AVRCP_CAPABILITY_ID_EVENT:
389                                     for (i = (uint8_t) AVRCP_NOTIFICATION_EVENT_FIRST_INDEX;
390                                          i < (uint8_t) AVRCP_NOTIFICATION_EVENT_LAST_INDEX; i++) {
391                                         if ((connection->notifications_supported_by_target & (1 << i)) == 0) {
392                                             continue;
393                                         }
394                                         packet[pos++] = i;
395                                     }
396                                     break;
397                                 case AVRCP_CAPABILITY_ID_COMPANY:
398                                     // use Bluetooth SIG as default company
399                                     for (i = 0; i < connection->data[1]; i++) {
400                                         little_endian_store_24(packet, pos,
401                                                                connection->target_supported_companies[i]);
402                                         pos += 3;
403                                     }
404                                     break;
405                                 default:
406                                     // error response
407                                     break;
408                             }
409                             l2cap_send_prepared(connection->l2cap_signaling_cid, pos);
410                             return;
411 
412                         case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:
413                             packet[pos++] = count_set_bits_uint32(connection->target_now_playing_info_attr_bitmap);
414                             max_payload_size--;
415 
416                             bytes_stored = avrcp_store_avctp_now_playing_info_fragment(connection, max_payload_size, packet + pos);
417 
418                             connection->avrcp_frame_bytes_sent += bytes_stored + pos;
419                             l2cap_send_prepared(connection->l2cap_signaling_cid, pos + bytes_stored);
420                             return;
421 
422                         default:
423                             // error response and other OPCODEs
424                             break;
425                     }
426                     break;
427 
428                 case AVRCP_CMD_OPCODE_PASS_THROUGH:
429                     packet[pos++] = connection->operation_id;
430                     // parameter length
431                     packet[pos++] = (uint8_t) connection->data_len;
432                     pos += 2;
433                     break;
434                 case AVRCP_CMD_OPCODE_UNIT_INFO:
435                     break;
436                 case AVRCP_CMD_OPCODE_SUBUNIT_INFO:
437                     break;
438                 default:
439                     btstack_assert(false);
440                     return;
441             }
442             break;
443         case AVCTP_CONTINUE_PACKET:
444         case AVCTP_END_PACKET:
445             switch (connection->pdu_id) {
446                 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:
447                     bytes_stored = avrcp_store_avctp_now_playing_info_fragment(connection, max_payload_size, packet + pos);
448 
449                     connection->avrcp_frame_bytes_sent += bytes_stored + pos;
450                     l2cap_send_prepared(connection->l2cap_signaling_cid, pos + bytes_stored);
451                     return;
452 
453                 default:
454                     break;
455             }
456             break;
457         default:
458             btstack_assert(false);
459             return;
460     }
461 
462     // compare number of bytes to store with the remaining buffer size
463     uint16_t bytes_to_copy = btstack_min(connection->data_len - connection->data_offset, max_payload_size - pos);
464 
465     (void)memcpy(packet + pos, &connection->data[connection->data_offset], bytes_to_copy);
466     pos += bytes_to_copy;
467     connection->data_offset += bytes_to_copy;
468     connection->avrcp_frame_bytes_sent += pos;
469 
470     l2cap_send_prepared(connection->l2cap_signaling_cid, pos);
471 }
472 
473 static void avctp_send_reject_cmd_wrong_pid(avrcp_connection_t * connection){
474     l2cap_reserve_packet_buffer();
475     uint8_t * packet = l2cap_get_outgoing_buffer();
476 
477     // AVCTP header
478     // transport header : transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
479     packet[0] = (connection->transaction_id << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_RESPONSE_FRAME << 1) | 1;
480     big_endian_store_16(packet, 1, connection->message_body[0]);
481     l2cap_send_prepared(connection->l2cap_signaling_cid, 3);
482 }
483 
484 static void avrcp_target_custom_command_data_init(avrcp_connection_t * connection,
485     avrcp_command_opcode_t opcode, avrcp_command_type_t command_type,
486     avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id,
487     avrcp_pdu_id_t pdu_id, uint32_t company_id){
488 
489     connection->command_opcode = opcode;
490     connection->command_type = command_type;
491     connection->subunit_type = subunit_type;
492     connection->subunit_id = subunit_id;
493     connection->company_id = company_id << 16;
494     connection->pdu_id = pdu_id;
495     connection->data = NULL;
496     connection->data_offset = 0;
497     connection->data_len = 0;
498     connection->avrcp_frame_bytes_sent = 0;
499 }
500 
501 static void avrcp_target_vendor_dependent_response_data_init(avrcp_connection_t * connection, avrcp_command_type_t command_type, avrcp_pdu_id_t pdu_id){
502     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
503     connection->subunit_type   = AVRCP_SUBUNIT_TYPE_PANEL;
504     connection->subunit_id     = AVRCP_SUBUNIT_ID;
505     connection->company_id     = BT_SIG_COMPANY_ID;
506 
507     connection->command_type = command_type;
508     connection->pdu_id = pdu_id;
509     connection->data = connection->message_body;
510     connection->data_offset = 0;
511     connection->data_len = 0;
512     connection->avrcp_frame_bytes_sent = 0;
513 }
514 
515 static void avrcp_target_pass_through_command_data_init(avrcp_connection_t * connection, avrcp_command_type_t command_type, avrcp_operation_id_t opid){
516     connection->command_opcode = AVRCP_CMD_OPCODE_PASS_THROUGH;
517     connection->subunit_type   = AVRCP_SUBUNIT_TYPE_PANEL;
518     connection->subunit_id     = AVRCP_SUBUNIT_ID;
519 
520     connection->command_type = command_type;
521     connection->company_id = 0;
522     connection->pdu_id = AVRCP_PDU_ID_UNDEFINED;
523     connection->operation_id = opid;
524 
525     connection->data = connection->message_body;
526     connection->data_offset = 0;
527     connection->data_len = 0;
528     connection->avrcp_frame_bytes_sent = 0;
529 }
530 
531 
532 static uint8_t avrcp_target_vendor_dependent_response_accept(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t status){
533     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_ACCEPTED, pdu_id);
534     connection->data_len = 1;
535     connection->data[0] = status;
536 
537     connection->target_accept_response = true;
538     connection->state = AVCTP_W2_SEND_RESPONSE;
539     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
540     return ERROR_CODE_SUCCESS;
541 }
542 
543 static uint8_t avrcp_target_response_vendor_dependent_reject(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, avrcp_status_code_t status){
544     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_REJECTED, pdu_id);
545     connection->data_len = 1;
546     connection->data[0] = status;
547 
548     connection->state = AVCTP_W2_SEND_RESPONSE;
549     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
550     return ERROR_CODE_SUCCESS;
551 }
552 
553 static uint8_t avrcp_target_response_vendor_dependent_not_implemented(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t event_id){
554     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_NOT_IMPLEMENTED, pdu_id);
555     connection->data_len = 1;
556     connection->data[0] = event_id;
557 
558     connection->state = AVCTP_W2_SEND_RESPONSE;
559     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
560     return ERROR_CODE_SUCCESS;
561 }
562 
563 static uint8_t avrcp_target_response_vendor_dependent_interim(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t event_id, const uint8_t * value, uint16_t value_len){
564     btstack_assert(value_len + 1 < AVRCP_MAX_COMMAND_PARAMETER_LENGTH);
565     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_INTERIM, pdu_id);
566     connection->data_len = 1 + value_len;
567     connection->data[0] = event_id;
568 
569     if (value && (value_len > 0)){
570         (void)memcpy(connection->data + 1, value, value_len);
571     }
572 
573     connection->state = AVCTP_W2_SEND_RESPONSE;
574     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
575     return ERROR_CODE_SUCCESS;
576 }
577 
578 static uint8_t avrcp_target_response_addressed_player_changed_interim(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t event_id){
579     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_INTERIM, pdu_id);
580 
581     connection->data_len = 5;
582     connection->data[0] = event_id;
583     big_endian_store_16(connection->data, 1, connection->target_addressed_player_id);
584     big_endian_store_16(connection->data, 3, connection->target_uid_counter);
585 
586     connection->state = AVCTP_W2_SEND_RESPONSE;
587     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
588     return ERROR_CODE_SUCCESS;
589 }
590 
591 static uint8_t avrcp_target_pass_through_response(uint16_t avrcp_cid, avrcp_command_type_t ctype, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
592     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
593     if (!connection){
594         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
595     }
596     avrcp_target_pass_through_command_data_init(connection, ctype, opid);
597 
598     if (operands_length == 1){
599         connection->data_len = 1;
600         connection->message_body[0] = operand;
601     }
602 
603     connection->state = AVCTP_W2_SEND_RESPONSE;
604     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
605     return ERROR_CODE_SUCCESS;
606 }
607 
608 uint8_t avrcp_target_operation_rejected(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
609     return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_REJECTED, opid, operands_length, operand);
610 }
611 
612 uint8_t avrcp_target_operation_accepted(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
613     return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand);
614 }
615 
616 uint8_t avrcp_target_operation_not_implemented(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
617     return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand);
618 }
619 
620 uint8_t avrcp_target_set_unit_info(uint16_t avrcp_cid, avrcp_subunit_type_t unit_type, uint32_t company_id){
621     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
622     if (!connection){
623         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
624     }
625     connection->target_unit_type = unit_type;
626     connection->company_id = company_id;
627     return ERROR_CODE_SUCCESS;
628 }
629 
630 uint8_t avrcp_target_set_subunit_info(uint16_t avrcp_cid, avrcp_subunit_type_t subunit_type, const uint8_t * subunit_info_data, uint16_t subunit_info_data_size){
631     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
632     if (!connection){
633         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
634     }
635     connection->target_subunit_info_type = subunit_type;
636     connection->target_subunit_info_data = subunit_info_data;
637     connection->target_subunit_info_data_size = subunit_info_data_size;
638     return ERROR_CODE_SUCCESS;
639 }
640 
641 static uint8_t avrcp_target_unit_info(avrcp_connection_t * connection){
642     if (connection->state != AVCTP_CONNECTION_OPENED){
643         return ERROR_CODE_COMMAND_DISALLOWED;
644     }
645 
646     avrcp_target_custom_command_data_init(connection,
647                                           AVRCP_CMD_OPCODE_UNIT_INFO, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE,
648                                           AVRCP_SUBUNIT_TYPE_UNIT, AVRCP_SUBUNIT_ID_IGNORE, AVRCP_PDU_ID_UNDEFINED,
649                                           connection->company_id);
650 
651     uint8_t unit = 0;
652     connection->data = connection->message_body;
653     connection->data_len = 5;
654     connection->data[0] = 0x07;
655     connection->data[1] = (connection->target_unit_type << 4) | unit;
656     // company id is 3 bytes long
657     big_endian_store_24(connection->data, 2, connection->company_id);
658 
659     connection->state = AVCTP_W2_SEND_RESPONSE;
660     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
661     return ERROR_CODE_SUCCESS;
662 }
663 
664 static uint8_t avrcp_target_subunit_info(avrcp_connection_t * connection, uint8_t offset){
665     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
666     if (offset >= 32) return AVRCP_STATUS_INVALID_PARAMETER;
667 
668     avrcp_target_custom_command_data_init(connection, AVRCP_CMD_OPCODE_SUBUNIT_INFO,
669                                           AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE,
670                                           AVRCP_SUBUNIT_TYPE_UNIT, AVRCP_SUBUNIT_ID_IGNORE, AVRCP_PDU_ID_UNDEFINED,
671                                           connection->company_id);
672 
673     uint8_t page = offset / 4;
674     uint8_t extension_code = 7;
675     connection->data = connection->message_body;
676     connection->data_len = 5;
677     connection->data[0] = (page << 4) | extension_code;
678 
679     // mark non-existent entries with 0xff
680     memset(&connection->message_body[1], 0xFF, 4);
681     if ((connection->data != NULL) && (offset < connection->target_subunit_info_data_size)){
682         uint8_t bytes_to_copy = btstack_min(connection->target_subunit_info_data_size - offset, 4);
683         memcpy(&connection->data[1], &connection->target_subunit_info_data[offset], bytes_to_copy);
684     }
685 
686     connection->state = AVCTP_W2_SEND_RESPONSE;
687     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
688     return ERROR_CODE_SUCCESS;
689 }
690 
691 static uint8_t avrcp_target_response_vendor_dependent_supported_events(avrcp_connection_t * connection){
692     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_CAPABILITIES);
693 
694     uint8_t event_id;
695     uint8_t num_events = 0;
696     for (event_id = (uint8_t) AVRCP_NOTIFICATION_EVENT_FIRST_INDEX; event_id < (uint8_t) AVRCP_NOTIFICATION_EVENT_LAST_INDEX; event_id++){
697         if ((connection->notifications_supported_by_target & (1 << event_id)) == 0){
698             continue;
699         }
700         num_events++;
701     }
702 
703     connection->data[0] = AVRCP_CAPABILITY_ID_EVENT;
704     connection->data[1] = num_events;
705     connection->data_len = 2 + num_events;
706 
707     // fill the data later directly to the L2CAP outgoing buffer
708     connection->state = AVCTP_W2_SEND_RESPONSE;
709     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
710     return ERROR_CODE_SUCCESS;
711 }
712 
713 static uint8_t avrcp_target_response_vendor_dependent_supported_companies(avrcp_connection_t * connection){
714     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_CAPABILITIES);
715 
716     connection->data[0] = AVRCP_CAPABILITY_ID_COMPANY;
717     if (connection->target_supported_companies_num == 0){
718         connection->target_supported_companies_num = 1;
719         connection->target_supported_companies = default_companies;
720     }
721 
722     connection->data[1] = connection->target_supported_companies_num;
723     connection->data_len = 2 + connection->data[1] * 3;
724 
725     // fill the data later directly to the L2CAP outgoing buffer and
726     // use Bluetooth SIG as default company
727     connection->state = AVCTP_W2_SEND_RESPONSE;
728     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
729     return ERROR_CODE_SUCCESS;
730 }
731 
732 uint8_t avrcp_target_support_event(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){
733     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
734     if (!connection){
735         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
736     }
737 
738     if ((event_id < (uint8_t)AVRCP_NOTIFICATION_EVENT_FIRST_INDEX) || (event_id > (uint8_t)AVRCP_NOTIFICATION_EVENT_LAST_INDEX)){
739         return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
740     }
741 
742     connection->notifications_supported_by_target |= (1 << (uint8_t)event_id);
743     return ERROR_CODE_SUCCESS;
744 }
745 
746 uint8_t avrcp_target_support_companies(uint16_t avrcp_cid, uint8_t num_companies, const uint32_t *companies){
747     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
748     if (!connection){
749         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
750     }
751 
752     connection->target_supported_companies_num = num_companies;
753     connection->target_supported_companies     = companies;
754     return ERROR_CODE_SUCCESS;
755 }
756 
757 // TODO Review (use flags)
758 uint8_t avrcp_target_play_status(uint16_t avrcp_cid, uint32_t song_length_ms, uint32_t song_position_ms, avrcp_playback_status_t play_status){
759     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
760     if (!connection){
761         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
762     }
763     if (connection->state != AVCTP_CONNECTION_OPENED){
764         return ERROR_CODE_COMMAND_DISALLOWED;
765     }
766 
767     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_PLAY_STATUS);
768     connection->data_len = 9;
769     big_endian_store_32(connection->data, 0, song_length_ms);
770     big_endian_store_32(connection->data, 4, song_position_ms);
771     connection->data[8] = play_status;
772 
773     connection->state = AVCTP_W2_SEND_RESPONSE;
774     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
775     return ERROR_CODE_SUCCESS;
776 }
777 
778 static uint8_t avrcp_target_store_media_attr(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id, const char * value){
779     int index = attr_id - 1;
780     if (!value) return AVRCP_STATUS_INVALID_PARAMETER;
781 	uint16_t value_len = (uint16_t)strlen(value);
782 	btstack_assert(value_len <= 255);
783 	connection->target_now_playing_info[index].value = (uint8_t*)value;
784     connection->target_now_playing_info[index].len   = value_len;
785     return ERROR_CODE_SUCCESS;
786 }
787 
788 uint8_t avrcp_target_set_playback_status(uint16_t avrcp_cid, avrcp_playback_status_t playback_status){
789     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
790     if (!connection){
791         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
792     }
793     if (connection->target_playback_status == playback_status){
794         return ERROR_CODE_SUCCESS;
795     }
796 
797     connection->target_playback_status = playback_status;
798     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED)) {
799         connection->target_playback_status_changed = true;
800         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
801     }
802     return ERROR_CODE_SUCCESS;
803 }
804 
805 static void avrcp_target_register_track_changed(avrcp_connection_t * connection, const uint8_t * track_id){
806     if (track_id == NULL){
807         memset(connection->target_track_id, 0xFF, 8);
808         connection->target_track_selected = false;
809     } else {
810         (void)memcpy(connection->target_track_id, track_id, 8);
811         connection->target_track_selected = true;
812     }
813 
814     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED)) {
815         connection->target_track_changed = true;
816         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
817     }
818 }
819 
820 uint8_t avrcp_target_track_changed(uint16_t avrcp_cid, uint8_t * track_id){
821     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
822     if (!connection){
823         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
824     }
825     avrcp_target_register_track_changed(connection, track_id);
826     return ERROR_CODE_SUCCESS;
827 }
828 
829 uint8_t avrcp_target_set_now_playing_info(uint16_t avrcp_cid, const avrcp_track_t * current_track, uint16_t total_tracks){
830     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
831     if (!connection){
832         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
833     }
834     if (!current_track){
835         return ERROR_CODE_COMMAND_DISALLOWED;
836     }
837 
838     (void)memcpy(connection->target_track_id, current_track->track_id, 8);
839     connection->target_song_length_ms = current_track->song_length_ms;
840     connection->target_track_nr = current_track->track_nr;
841     connection->target_total_tracks = total_tracks;
842     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_TITLE, current_track->title);
843     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ARTIST, current_track->artist);
844     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ALBUM, current_track->album);
845     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_GENRE, current_track->genre);
846 
847     avrcp_target_register_track_changed(connection, current_track->track_id);
848     return ERROR_CODE_SUCCESS;
849 }
850 
851 
852 uint8_t avrcp_target_playing_content_changed(uint16_t avrcp_cid){
853     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
854     if (!connection){
855         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
856     }
857     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED)) {
858         connection->target_playing_content_changed = true;
859         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
860     }
861     return ERROR_CODE_SUCCESS;
862 }
863 
864 uint8_t avrcp_target_addressed_player_changed(uint16_t avrcp_cid, uint16_t player_id, uint16_t uid_counter){
865     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
866     if (!connection){
867         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
868     }
869 
870     if (connection->target_addressed_player_id == player_id){
871         return ERROR_CODE_SUCCESS;
872     }
873 
874     connection->target_uid_counter = uid_counter;
875     connection->target_addressed_player_id = player_id;
876 
877     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED)) {
878         connection->target_addressed_player_changed = true;
879         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
880     }
881     return ERROR_CODE_SUCCESS;
882 }
883 
884 uint8_t avrcp_target_uids_changed(uint16_t avrcp_cid, uint16_t uid_counter){
885     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
886     if (!connection){
887         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
888     }
889 
890     connection->target_uid_counter = uid_counter;
891 
892     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED)) {
893         connection->target_uids_changed = true;
894         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
895     }
896     return ERROR_CODE_SUCCESS;
897 }
898 
899 uint8_t avrcp_target_battery_status_changed(uint16_t avrcp_cid, avrcp_battery_status_t battery_status){
900     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
901     if (!connection){
902         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
903     }
904     if (connection->target_battery_status == battery_status){
905         return ERROR_CODE_SUCCESS;
906     }
907 
908     connection->target_battery_status = battery_status;
909 
910     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED)) {
911         connection->target_battery_status_changed = true;
912         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
913     }
914     return ERROR_CODE_SUCCESS;
915 }
916 
917 uint8_t avrcp_target_adjust_absolute_volume(uint16_t avrcp_cid, uint8_t absolute_volume){
918     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
919     if (!connection){
920         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
921     }
922 
923     connection->target_absolute_volume = absolute_volume;
924     return ERROR_CODE_SUCCESS;
925 }
926 
927 uint8_t avrcp_target_volume_changed(uint16_t avrcp_cid, uint8_t absolute_volume){
928     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
929     if (!connection){
930         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
931     }
932     if (connection->target_absolute_volume == absolute_volume){
933         return ERROR_CODE_SUCCESS;
934     }
935 
936     connection->target_absolute_volume = absolute_volume;
937 
938     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED )) {
939         connection->target_notify_absolute_volume_changed = true;
940         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
941     }
942     return ERROR_CODE_SUCCESS;
943 }
944 
945 static void avrcp_target_set_transaction_label_for_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification, uint8_t transaction_label){
946     if (notification > AVRCP_NOTIFICATION_EVENT_MAX_VALUE) return;
947     connection->target_notifications_transaction_label[notification] = transaction_label;
948 }
949 
950 static uint8_t avrcp_target_get_transaction_label_for_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification){
951     if (notification > AVRCP_NOTIFICATION_EVENT_MAX_VALUE) return 0;
952     return connection->target_notifications_transaction_label[notification];
953 }
954 
955 static bool avcrp_operation_id_is_valid(avrcp_operation_id_t operation_id){
956     if (operation_id < AVRCP_OPERATION_ID_RESERVED_1) return true;
957 
958     if (operation_id < AVRCP_OPERATION_ID_0) return false;
959     if (operation_id < AVRCP_OPERATION_ID_RESERVED_2) return true;
960 
961     if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false;
962     if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true;
963 
964     if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false;
965     if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true;
966 
967     if (operation_id < AVRCP_OPERATION_ID_SKIP) return false;
968     if (operation_id == AVRCP_OPERATION_ID_SKIP) return true;
969 
970     if (operation_id < AVRCP_OPERATION_ID_POWER) return false;
971     if (operation_id < AVRCP_OPERATION_ID_RESERVED_4) return true;
972 
973     if (operation_id < AVRCP_OPERATION_ID_ANGLE) return false;
974     if (operation_id < AVRCP_OPERATION_ID_RESERVED_5) return true;
975 
976     if (operation_id < AVRCP_OPERATION_ID_F1) return false;
977     if (operation_id < AVRCP_OPERATION_ID_RESERVED_6) return true;
978     if (operation_id < AVRCP_OPERATION_ID_RESERVED_7) return true;
979     return false;
980 }
981 
982 
983 #ifdef ENABLE_AVCTP_FRAGMENTATION
984 static void avctp_reassemble_message(avrcp_connection_t * connection, avctp_packet_type_t packet_type, uint8_t *packet, uint16_t size){
985     // after header (transaction label and packet type)
986     uint16_t pos;
987     uint16_t bytes_to_store;
988 
989     switch (packet_type){
990         case AVCTP_START_PACKET:
991             if (size < 2) return;
992 
993             // store header
994             pos = 0;
995             connection->avctp_reassembly_buffer[pos] = packet[pos];
996             pos++;
997             connection->avctp_reassembly_size = pos;
998 
999             // NOTE: num packets not needed for reassembly, ignoring it does not pose security risk -> no need to store it
1000             pos++;
1001 
1002             // PID in reassembled packet is at offset 1, it will be read later after the avctp_reassemble_message with AVCTP_END_PACKET is called
1003 
1004             bytes_to_store = btstack_min(size - pos, sizeof(connection->avctp_reassembly_buffer) - connection->avctp_reassembly_size);
1005             memcpy(&connection->avctp_reassembly_buffer[connection->avctp_reassembly_size], &packet[pos], bytes_to_store);
1006             connection->avctp_reassembly_size += bytes_to_store;
1007             break;
1008 
1009         case AVCTP_CONTINUE_PACKET:
1010         case AVCTP_END_PACKET:
1011             if (size < 1) return;
1012 
1013             // store remaining data, ignore header
1014             pos = 1;
1015             bytes_to_store = btstack_min(size - pos, sizeof(connection->avctp_reassembly_buffer) - connection->avctp_reassembly_size);
1016             memcpy(&connection->avctp_reassembly_buffer[connection->avctp_reassembly_size], &packet[pos], bytes_to_store);
1017             connection->avctp_reassembly_size += bytes_to_store;
1018             break;
1019 
1020         default:
1021             return;
1022     }
1023 }
1024 #endif
1025 
1026 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t * packet, uint16_t size){
1027     uint8_t avctp_header = packet[0];
1028     connection->transaction_id = avctp_header >> 4;
1029 
1030     avctp_packet_type_t avctp_packet_type = (avctp_packet_type_t) ((avctp_header & 0x0F) >> 2);
1031     switch (avctp_packet_type){
1032         case AVCTP_SINGLE_PACKET:
1033             break;
1034 
1035 #ifdef ENABLE_AVCTP_FRAGMENTATION
1036         case AVCTP_START_PACKET:
1037         case AVCTP_CONTINUE_PACKET:
1038             avctp_reassemble_message(connection, avctp_packet_type, packet, size);
1039             return;
1040 
1041         case AVCTP_END_PACKET:
1042             avctp_reassemble_message(connection, avctp_packet_type, packet, size);
1043 
1044             packet = connection->avctp_reassembly_buffer;
1045             size   = connection->avctp_reassembly_size;
1046             break;
1047 #endif
1048         default:
1049             return;
1050     }
1051 
1052     if (size < 6u) return;
1053 
1054     uint16_t pid = big_endian_read_16(packet, 1);
1055 
1056     if (pid != BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL){
1057         log_info("Invalid pid 0x%02x, expected 0x%02x", pid, BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL);
1058         connection->target_reject_transport_header = true;
1059         connection->target_invalid_pid = pid;
1060         connection->state = AVCTP_W2_SEND_RESPONSE;
1061         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1062         return;
1063     }
1064 
1065     // avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (packet[4] >> 3);
1066     // avrcp_subunit_id_t   subunit_id   = (avrcp_subunit_id_t) (packet[4] & 0x07);
1067 
1068     avrcp_command_opcode_t opcode = (avrcp_command_opcode_t) avrcp_cmd_opcode(packet,size);
1069 
1070     int pos = 6;
1071     uint16_t length;
1072     avrcp_pdu_id_t   pdu_id;
1073     // connection->data_len = 0;
1074     uint8_t offset;
1075     uint8_t operand;
1076     uint16_t event_mask;
1077     avrcp_operation_id_t operation_id;
1078 
1079     switch (opcode){
1080         case AVRCP_CMD_OPCODE_UNIT_INFO:
1081             avrcp_target_unit_info(connection);
1082             break;
1083         case AVRCP_CMD_OPCODE_SUBUNIT_INFO:
1084             if ((size - pos) < 3) return;
1085             // page: packet[pos] >> 4,
1086             offset =  4 * (packet[pos]>>4);
1087             // extension code (fixed 7) = packet[pos] & 0x0F
1088             // 4 bytes paga data, all 0xFF
1089             avrcp_target_subunit_info(connection, offset);
1090             break;
1091 
1092         case AVRCP_CMD_OPCODE_PASS_THROUGH:
1093             if (size < 8) return;
1094             log_info("AVRCP_OPERATION_ID 0x%02x, operands length %d", packet[6], packet[7]);
1095             operation_id = (avrcp_operation_id_t) (packet[6] & 0x7f);
1096             operand = 0;
1097             if ((packet[7] >= 1) && (size >= 9)){
1098                 operand = packet[8];
1099             }
1100 
1101             if (avcrp_operation_id_is_valid(operation_id)){
1102                 bool button_pressed = (packet[6] & 0x80) == 0;
1103 
1104                 avrcp_target_operation_accepted(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand);
1105                 avrcp_target_emit_operation(avrcp_target_context.avrcp_callback, connection->avrcp_cid,
1106                                                 operation_id, button_pressed, packet[7], operand);
1107             } else {
1108                 avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand);
1109             }
1110             break;
1111 
1112 
1113         case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT:
1114 
1115             if (size < 13) return;
1116 
1117             // pos = 6 - company id
1118             (void)memcpy(connection->message_body, &packet[pos], 3);
1119             // connection->data_len = 3;
1120             pos += 3;
1121             // pos = 9
1122             pdu_id = (avrcp_pdu_id_t) packet[pos++];
1123             // 1 - reserved
1124             pos++;
1125             // 2-3 param length,
1126             length = big_endian_read_16(packet, pos);
1127             pos += 2;
1128             // pos = 13
1129             switch (pdu_id){
1130                 case AVRCP_PDU_ID_ADD_TO_NOW_PLAYING:
1131                     if ( (pos + 11) > size){
1132                         avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND);
1133                         return;
1134                     }
1135 
1136                     connection->target_scope = packet[pos++];
1137                     if (connection->target_scope >= AVRCP_BROWSING_RFU){
1138                         avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
1139                         return;
1140                     }
1141                     memcpy(connection->target_track_id, &packet[pos], 8);
1142                     pos += 8;
1143                     connection->target_uid_counter = big_endian_read_16(packet,pos);
1144                     connection->state = AVCTP_W2_CHECK_DATABASE;
1145                     avrcp_target_emit_add_to_now_playing_item(avrcp_target_context.avrcp_callback, connection->avrcp_cid, connection->target_uid_counter, connection->target_scope,connection->target_track_id);
1146                     break;
1147 
1148                 case AVRCP_PDU_ID_PLAY_ITEM:
1149                     if ( (pos + 11) > size){
1150                         avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND);
1151                         return;
1152                     }
1153 
1154                     connection->target_scope = packet[pos++];
1155                     if (connection->target_scope >= AVRCP_BROWSING_RFU){
1156                         avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
1157                         return;
1158                     }
1159                     memcpy(connection->target_track_id, &packet[pos], 8);
1160                     pos += 8;
1161                     connection->target_uid_counter = big_endian_read_16(packet,pos);
1162                     connection->state = AVCTP_W2_CHECK_DATABASE;
1163                     avrcp_target_emit_respond_play_item(avrcp_target_context.avrcp_callback, connection->avrcp_cid, connection->target_uid_counter, connection->target_scope,connection->target_track_id);
1164                     break;
1165 
1166                 case AVRCP_PDU_ID_SET_ADDRESSED_PLAYER:{
1167                     if ((pos + 2) > size) return;
1168                     bool ok = length == 4;
1169                     if (avrcp_target_context.set_addressed_player_callback != NULL){
1170                         uint16_t player_id = big_endian_read_16(packet, pos);
1171                         ok = avrcp_target_context.set_addressed_player_callback(player_id);
1172                     }
1173                     if (ok){
1174                         avrcp_target_vendor_dependent_response_accept(connection, pdu_id, AVRCP_STATUS_SUCCESS);
1175                     } else {
1176                         avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PLAYER_ID);
1177                     }
1178                     break;
1179                 }
1180                 case AVRCP_PDU_ID_GET_CAPABILITIES:{
1181                     avrcp_capability_id_t capability_id = (avrcp_capability_id_t) packet[pos];
1182                     switch (capability_id){
1183                         case AVRCP_CAPABILITY_ID_EVENT:
1184                              avrcp_target_response_vendor_dependent_supported_events(connection);
1185                             break;
1186                         case AVRCP_CAPABILITY_ID_COMPANY:
1187                             avrcp_target_response_vendor_dependent_supported_companies(connection);
1188                             break;
1189                         default:
1190                             avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
1191                             break;
1192                     }
1193                     break;
1194                 }
1195                 case AVRCP_PDU_ID_GET_PLAY_STATUS:
1196                     avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_PLAY_STATUS_QUERY);
1197                     break;
1198                 case AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE:
1199                     if ((pos + 1) > size) return;
1200                     connection->target_abort_continue_response = true;
1201                     connection->state = AVCTP_W2_SEND_RESPONSE;
1202                     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1203                     break;
1204                 case AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE:
1205                     if ((pos + 1) > size) return;
1206                     if (packet[pos] != AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES){
1207                         avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND);
1208                         return;
1209                     }
1210                     connection->target_continue_response = true;
1211                     connection->target_now_playing_info_response = true;
1212                     connection->state = AVCTP_W2_SEND_RESPONSE;
1213                     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1214                     break;
1215                 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{
1216                     if ((pos + 9) > size) return;
1217                     uint8_t play_identifier[8];
1218                     memset(play_identifier, 0, 8);
1219                     if (memcmp(&packet[pos], play_identifier, 8) != 0) {
1220                         avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
1221                         return;
1222                     }
1223                     pos += 8;
1224                     uint8_t attribute_count = packet[pos++];
1225                     connection->next_attr_id = AVRCP_MEDIA_ATTR_NONE;
1226                     if (!attribute_count){
1227                         connection->next_attr_id = AVRCP_MEDIA_ATTR_TITLE;
1228                         connection->target_now_playing_info_attr_bitmap = 0xFE;
1229                     } else {
1230                         int i;
1231                         connection->next_attr_id = AVRCP_MEDIA_ATTR_TITLE;
1232                         connection->target_now_playing_info_attr_bitmap = 0;
1233                         if ((pos + attribute_count * 4) > size) return;
1234                         for (i=0; i < attribute_count; i++){
1235                             uint32_t attr_id = big_endian_read_32(packet, pos);
1236                             connection->target_now_playing_info_attr_bitmap |= (1 << attr_id);
1237                             pos += 4;
1238                         }
1239                     }
1240                     log_info("target_now_playing_info_attr_bitmap 0x%02x", connection->target_now_playing_info_attr_bitmap);
1241                     connection->target_now_playing_info_response = true;
1242                     connection->state = AVCTP_W2_SEND_RESPONSE;
1243                     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1244                     break;
1245                 }
1246                 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{
1247                     if ((pos + 1) > size) return;
1248                     avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) packet[pos];
1249 
1250                     avrcp_target_set_transaction_label_for_notification(connection, event_id, connection->transaction_id);
1251 
1252                     if (event_id < AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED ||
1253                         event_id > AVRCP_NOTIFICATION_EVENT_MAX_VALUE){
1254                         avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
1255                         return;
1256                     }
1257 
1258                     switch (event_id){
1259                         case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:
1260                         case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
1261                         case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_END:
1262                         case AVRCP_NOTIFICATION_EVENT_TRACK_REACHED_START:
1263                         case AVRCP_NOTIFICATION_EVENT_PLAYBACK_POS_CHANGED:
1264                         case AVRCP_NOTIFICATION_EVENT_SYSTEM_STATUS_CHANGED:
1265                         case AVRCP_NOTIFICATION_EVENT_MAX_VALUE:
1266                             avrcp_target_response_vendor_dependent_not_implemented(connection, pdu_id, event_id);
1267                             return;
1268                         default:
1269                             break;
1270                     }
1271 
1272                     event_mask = (1 << event_id);
1273                     connection->notifications_enabled |= event_mask;
1274 
1275                     switch (event_id){
1276                         case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:{
1277                             if (connection->target_uid_counter == 0){
1278                                 connection->target_uid_counter = 1;
1279                             }
1280                             uint8_t value[2];
1281                             big_endian_store_16(value, 0, connection->target_uid_counter);
1282                             avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, value, 2);
1283                             break;
1284                         }
1285 
1286                         case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:
1287                             if (connection->target_track_selected){
1288                                 if (connection->target_total_tracks > 0){
1289                                     avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, connection->target_track_id, 8);
1290                                     break;
1291                                 }
1292                                 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_SELECTED, 8);
1293                             } else {
1294                                 avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_NOT_SELECTED, 8);
1295                             }
1296                             break;
1297                         case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:
1298                             avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->target_playback_status, 1);
1299                             break;
1300                         case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:
1301                             avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, NULL, 0);
1302                             break;
1303                         case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:
1304                             avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->target_absolute_volume, 1);
1305                             break;
1306                         case AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED:
1307                             avrcp_target_response_vendor_dependent_interim(connection, pdu_id, event_id, (const uint8_t *)&connection->target_battery_status, 1);
1308                             break;
1309                         case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED:
1310                             avrcp_target_response_addressed_player_changed_interim(connection, pdu_id, event_id);
1311                             return;
1312                         default:
1313                             btstack_assert(false);
1314                             return;
1315                     }
1316                     break;
1317                 }
1318                 case AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME: {
1319                     if ((pos + 1) > size ){
1320                         avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND);
1321                         break;
1322                     }
1323 
1324                     if (length != 1){
1325                         avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_SPECIFIED_PARAMETER_NOT_FOUND);
1326                         break;
1327                     }
1328 
1329                     uint8_t absolute_volume = packet[pos];
1330                     if (absolute_volume >= 0x80) {
1331                         avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_SPECIFIED_PARAMETER_NOT_FOUND);
1332                         break;
1333                     }
1334                     connection->target_absolute_volume = absolute_volume;
1335 
1336                     avrcp_target_emit_volume_changed(avrcp_target_context.avrcp_callback, connection->avrcp_cid, connection->target_absolute_volume);
1337                     avrcp_target_vendor_dependent_response_accept(connection, pdu_id, connection->target_absolute_volume);
1338                     break;
1339                 }
1340                 default:
1341                     log_info("AVRCP target: unhandled pdu id 0x%02x", pdu_id);
1342                     avrcp_target_response_vendor_dependent_reject(connection, pdu_id, AVRCP_STATUS_INVALID_COMMAND);
1343                     break;
1344             }
1345             break;
1346         default:
1347             log_info("AVRCP target: opcode 0x%02x not implemented", avrcp_cmd_opcode(packet,size));
1348             break;
1349     }
1350 }
1351 
1352 static void avrcp_target_notification_init(avrcp_connection_t * connection, avrcp_notification_event_id_t notification_id, uint8_t * value, uint16_t value_len){
1353     btstack_assert(value_len + 1 < AVRCP_MAX_COMMAND_PARAMETER_LENGTH);
1354     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_CHANGED_STABLE, AVRCP_PDU_ID_REGISTER_NOTIFICATION);
1355     connection->transaction_id = avrcp_target_get_transaction_label_for_notification(connection, notification_id);
1356 
1357     connection->data_len = 1 + value_len;
1358     connection->data[0] = notification_id;
1359     if (value != NULL){
1360         (void)memcpy(connection->data + 1, value, value_len);
1361     }
1362 }
1363 
1364 static void avrcp_target_notification_addressed_player_changed_init(avrcp_connection_t * connection){
1365     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_CHANGED_STABLE, AVRCP_PDU_ID_REGISTER_NOTIFICATION);
1366     connection->transaction_id = avrcp_target_get_transaction_label_for_notification(connection, AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED);
1367 
1368     connection->data_len = 5;
1369     connection->data[0] = AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED;
1370     big_endian_store_16(connection->data, 1, connection->target_addressed_player_id);
1371     big_endian_store_16(connection->data, 3, connection->target_uid_counter);
1372 }
1373 
1374 
1375 static void avrcp_target_reset_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t notification_id){
1376     if (notification_id < AVRCP_NOTIFICATION_EVENT_FIRST_INDEX || notification_id > AVRCP_NOTIFICATION_EVENT_LAST_INDEX){
1377         return;
1378     }
1379     connection->notifications_enabled &= ~(1 << notification_id);
1380     connection->target_notifications_transaction_label[notification_id] = 0;
1381 }
1382 
1383 static void avrcp_request_next_avctp_segment(avrcp_connection_t * connection){
1384     // AVCTP
1385     switch (connection->avctp_packet_type){
1386         case AVCTP_END_PACKET:
1387         case AVCTP_SINGLE_PACKET:
1388             connection->state = AVCTP_CONNECTION_OPENED;
1389             break;
1390         default:
1391             connection->state = AVCTP_W2_SEND_RESPONSE;
1392             avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
1393             break;
1394     }
1395 }
1396 
1397 static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1398     avrcp_connection_t * connection;
1399     avrcp_notification_event_id_t notification_id = AVRCP_NOTIFICATION_EVENT_NONE;
1400 
1401     switch (packet_type){
1402         case L2CAP_DATA_PACKET:
1403             connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel);
1404             avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size);
1405             return;
1406 
1407         case HCI_EVENT_PACKET:
1408             if (hci_event_packet_get_type(packet) != L2CAP_EVENT_CAN_SEND_NOW){
1409                 return;
1410             }
1411 
1412             connection = avrcp_get_connection_for_l2cap_signaling_cid_for_role(AVRCP_TARGET, channel);
1413             if (connection == NULL){
1414                 return;
1415             }
1416 
1417             if (connection->state == AVCTP_W2_SEND_RESPONSE){
1418                 // start AVCTP
1419                 if (connection->target_reject_transport_header){
1420                     connection->target_reject_transport_header = false;
1421                     avctp_send_reject_cmd_wrong_pid(connection);
1422                     connection->state = AVCTP_CONNECTION_OPENED;
1423                     return;
1424                 }
1425                 // end AVCTP
1426 
1427                 // start AVRCP
1428                 if (connection->target_abort_continue_response){
1429                     connection->target_abort_continue_response = false;
1430                     avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_ACCEPTED, AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE);
1431                     break;
1432                 }
1433 
1434                 if (connection->target_now_playing_info_response){
1435                     connection->target_now_playing_info_response = false;
1436                     if (connection->target_continue_response){
1437                         connection->target_continue_response = false;
1438                         if (connection->data_len == 0){
1439                             avrcp_target_response_vendor_dependent_reject(connection, connection->pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
1440                             return;
1441                         }
1442                     } else {
1443                         avrcp_target_vendor_dependent_response_data_init(connection, AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE, AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES);
1444                         connection->data_len = avrcp_now_playing_info_value_len_with_headers(connection);
1445                     }
1446                     break;
1447                 }
1448 
1449                 // data already prepared
1450                 break;
1451             }
1452 
1453             // Notifications
1454 
1455             if (connection->target_track_changed){
1456                 connection->target_track_changed = false;
1457                 notification_id = AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED;
1458                 avrcp_target_notification_init(connection, notification_id, connection->target_track_id, 8);
1459                 break;
1460             }
1461 
1462             if (connection->target_playback_status_changed){
1463                 connection->target_playback_status_changed = false;
1464                 notification_id = AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED;
1465                 uint8_t playback_status = (uint8_t) connection->target_playback_status;
1466                 avrcp_target_notification_init(connection, notification_id, &playback_status, 1);
1467                 break;
1468             }
1469 
1470             if (connection->target_playing_content_changed){
1471                 connection->target_playing_content_changed = false;
1472                 notification_id = AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED;
1473                 avrcp_target_notification_init(connection, notification_id, NULL, 0);
1474                 break;
1475             }
1476 
1477             if (connection->target_battery_status_changed){
1478                 connection->target_battery_status_changed = false;
1479                 notification_id = AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED;
1480                 avrcp_target_notification_init(connection, notification_id, (uint8_t *)&connection->target_battery_status, 1);
1481                 break;
1482             }
1483 
1484             if (connection->target_notify_absolute_volume_changed){
1485                 connection->target_notify_absolute_volume_changed = false;
1486                 notification_id = AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED;
1487                 avrcp_target_notification_init(connection, notification_id, &connection->target_absolute_volume, 1);
1488                 break;
1489             }
1490 
1491             if (connection->target_addressed_player_changed){
1492                 connection->target_addressed_player_changed = false;
1493                 notification_id = AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED;
1494                 avrcp_target_notification_addressed_player_changed_init(connection);
1495                 break;
1496             }
1497 
1498             if (connection->target_uids_changed){
1499                 connection->target_uids_changed = false;
1500                 notification_id = AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED;
1501                 uint8_t value[2];
1502                 big_endian_store_16(value, 0, connection->target_uid_counter);
1503                 avrcp_target_notification_init(connection, notification_id, value, 2);
1504                 break;
1505             }
1506             // nothing to send, exit
1507             return;
1508 
1509         default:
1510             return;
1511     }
1512 
1513     avrcp_send_response_with_avctp_fragmentation(connection);
1514     avrcp_target_reset_notification(connection, notification_id);
1515     avrcp_request_next_avctp_segment(connection);
1516 }
1517 
1518 void avrcp_target_init(void){
1519     avrcp_target_context.role = AVRCP_TARGET;
1520     avrcp_target_context.packet_handler = avrcp_target_packet_handler;
1521     avrcp_register_target_packet_handler(&avrcp_target_packet_handler);
1522 }
1523 
1524 void avrcp_target_deinit(void){
1525     memset(&avrcp_target_context, 0, sizeof(avrcp_context_t));
1526 }
1527 
1528 void avrcp_target_register_packet_handler(btstack_packet_handler_t callback){
1529     btstack_assert(callback != NULL);
1530     avrcp_target_context.avrcp_callback = callback;
1531 }
1532 
1533 void avrcp_target_register_set_addressed_player_handler(bool (*callback)(uint16_t player_id)){
1534     btstack_assert(callback != NULL);
1535     avrcp_target_context.set_addressed_player_callback = callback;
1536 }
1537 
1538 static uint8_t avrcp_target_send_status_response(uint16_t avrcp_cid, avrcp_pdu_id_t pdu_id, avrcp_status_code_t status){
1539     avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(avrcp_cid, AVRCP_TARGET);
1540     if (connection == NULL){
1541         return ERROR_CODE_COMMAND_DISALLOWED;
1542     }
1543     if (connection->state != AVCTP_W2_CHECK_DATABASE){
1544         return ERROR_CODE_COMMAND_DISALLOWED;
1545     }
1546     if (status != AVRCP_STATUS_SUCCESS){
1547         return avrcp_target_response_vendor_dependent_reject(connection, pdu_id, status);
1548     }
1549     return avrcp_target_vendor_dependent_response_accept(connection, pdu_id, status);
1550 }
1551 
1552 uint8_t avrcp_target_send_response_for_play_item_cmd(uint16_t avrcp_cid, avrcp_status_code_t status){
1553     return avrcp_target_send_status_response(avrcp_cid, AVRCP_PDU_ID_PLAY_ITEM, status);
1554 }
1555 
1556 uint8_t avrcp_target_send_response_for_add_to_now_playing_cmd(uint16_t avrcp_cid, avrcp_status_code_t status){
1557     return avrcp_target_send_status_response(avrcp_cid, AVRCP_PDU_ID_ADD_TO_NOW_PLAYING, status);
1558 }