xref: /btstack/src/classic/avrcp_target.c (revision d1207cd89697c74faa15e9ddc6cd0d1f10bfc4fa)
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_target.c"
39 
40 #include <stdint.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <inttypes.h>
45 
46 #include "btstack.h"
47 #include "classic/avrcp.h"
48 
49 #define AVRCP_ATTR_HEADER_LEN  8
50 
51 static const uint8_t AVRCP_NOTIFICATION_TRACK_SELECTED[] = {0,0,0,0,0,0,0,0};
52 static const uint8_t AVRCP_NOTIFICATION_TRACK_NOT_SELECTED[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
53 
54 static avrcp_context_t avrcp_target_context;
55 
56 void avrcp_target_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name){
57     avrcp_create_sdp_record(0, service, service_record_handle, browsing, supported_features, service_name, service_provider_name);
58 }
59 
60 static void avrcp_target_emit_operation(btstack_packet_handler_t callback, uint16_t avrcp_cid, avrcp_operation_id_t operation_id, uint8_t operands_length, uint8_t operand){
61     if (!callback) return;
62     uint8_t event[8];
63     int pos = 0;
64     event[pos++] = HCI_EVENT_AVRCP_META;
65     event[pos++] = sizeof(event) - 2;
66     event[pos++] = AVRCP_SUBEVENT_OPERATION;
67     little_endian_store_16(event, pos, avrcp_cid);
68     pos += 2;
69     event[pos++] = operation_id;
70     event[pos++] = operands_length;
71     event[pos++] = operand;
72     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
73 }
74 
75 static void avrcp_target_emit_respond_vendor_dependent_query(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t subevent_id){
76     if (!callback) return;
77     uint8_t event[5];
78     int pos = 0;
79     event[pos++] = HCI_EVENT_AVRCP_META;
80     event[pos++] = sizeof(event) - 2;
81     event[pos++] = subevent_id;
82     little_endian_store_16(event, pos, avrcp_cid);
83     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
84 }
85 
86 static uint16_t avrcp_target_pack_single_element_attribute_number(uint8_t * packet, uint16_t pos, avrcp_media_attribute_id_t attr_id, uint32_t value){
87     if ((attr_id < 1) || (attr_id > AVRCP_MEDIA_ATTR_COUNT)) return 0;
88     uint16_t attr_value_length = sprintf((char *)(packet+pos+8), "%0" PRIu32, value);
89     big_endian_store_32(packet, pos, attr_id);
90     pos += 4;
91     big_endian_store_16(packet, pos, UTF8);
92     pos += 2;
93     big_endian_store_16(packet, pos, attr_value_length);
94     pos += 2;
95     return 8 + attr_value_length;
96 }
97 
98 static uint16_t avrcp_target_pack_single_element_attribute_string(uint8_t * packet, uint16_t pos, rfc2978_charset_mib_enumid_t mib_enumid, avrcp_media_attribute_id_t attr_id, uint8_t * attr_value, uint16_t attr_value_to_copy, uint16_t attr_value_size, uint8_t header){
99     if (attr_value_size == 0) return 0;
100     if ((attr_id < 1) || (attr_id > AVRCP_MEDIA_ATTR_COUNT)) return 0;
101     if (header){
102         big_endian_store_32(packet, pos, attr_id);
103         pos += 4;
104         big_endian_store_16(packet, pos, mib_enumid);
105         pos += 2;
106         big_endian_store_16(packet, pos, attr_value_size);
107         pos += 2;
108     }
109     memcpy(packet+pos, attr_value, attr_value_to_copy);
110     pos += attr_value_size;
111     return header * 8 + attr_value_size;
112 }
113 
114 
115 static int avrcp_target_send_now_playing_info(uint16_t cid, avrcp_connection_t * connection){
116     uint16_t pos = 0;
117     l2cap_reserve_packet_buffer();
118     uint8_t * packet = l2cap_get_outgoing_buffer();
119     uint16_t  size   = l2cap_get_remote_mtu_for_local_cid(connection->l2cap_signaling_cid);
120 
121     packet[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0;
122     // Profile IDentifier (PID)
123     packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
124     packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
125 
126     // command_type
127     packet[pos++] = connection->command_type;
128     // subunit_type | subunit ID
129     packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id;
130     // opcode
131     packet[pos++] = (uint8_t)connection->command_opcode;
132 
133     // company id is 3 bytes long
134     big_endian_store_24(packet, pos, BT_SIG_COMPANY_ID);
135     pos += 3;
136 
137     packet[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
138 
139     // reserve byte for packet type
140     uint8_t pos_packet_type = pos;
141     pos++;
142 
143     uint16_t playing_info_buffer_len_position = pos;
144     pos += 2;
145 
146     if (connection->next_attr_id == AVRCP_MEDIA_ATTR_NONE){
147         packet[pos_packet_type] = AVRCP_SINGLE_PACKET;
148         connection->packet_type = AVRCP_SINGLE_PACKET;
149         packet[pos++] = count_set_bits_uint32(connection->now_playing_info_attr_bitmap);
150         connection->next_attr_id++;
151     }
152 
153     uint8_t fragmented = 0;
154     int num_free_bytes = size - pos - 2;
155     uint8_t MAX_NUMBER_ATTR_LEN = 10;
156 
157     while (!fragmented && num_free_bytes > 0 && connection->next_attr_id <= AVRCP_MEDIA_ATTR_SONG_LENGTH){
158         avrcp_media_attribute_id_t attr_id = connection->next_attr_id;
159         int attr_index = attr_id - 1;
160 
161         if (connection->now_playing_info_attr_bitmap & (1 << attr_id)){
162             int num_written_bytes = 0;
163             int num_bytes_to_write = 0;
164             switch (attr_id){
165                 case AVRCP_MEDIA_ATTR_NONE:
166                     break;
167                 case AVRCP_MEDIA_ATTR_TRACK:
168                     num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN;
169                     if (num_free_bytes >= num_bytes_to_write){
170                         num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->track_nr);
171                         break;
172                     }
173                     fragmented = 1;
174                     connection->fragmented_value_offset = 0;
175                     break;
176                 case AVRCP_MEDIA_ATTR_TOTAL_TRACKS:
177                     num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN;
178                     if (num_free_bytes >= num_bytes_to_write){
179                         num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->total_tracks);
180                         break;
181                     }
182                     fragmented = 1;
183                     connection->fragmented_value_offset = 0;
184                     break;
185                 case AVRCP_MEDIA_ATTR_SONG_LENGTH:
186                     num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN;
187                     if (num_free_bytes >= num_bytes_to_write){
188                         num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->song_length_ms);
189                         break;
190                     }
191                     fragmented = 1;
192                     connection->fragmented_value_offset = 0;
193                     break;
194                 default:{
195                     uint8_t   header = (connection->fragmented_value_offset == 0);
196                     uint8_t * attr_value =     (uint8_t *) (connection->now_playing_info[attr_index].value + connection->fragmented_value_offset);
197                     uint16_t  attr_value_len = connection->now_playing_info[attr_index].len - connection->fragmented_value_offset;
198 
199                     num_bytes_to_write = attr_value_len + header * AVRCP_ATTR_HEADER_LEN;
200                     if (num_bytes_to_write <= num_free_bytes){
201                         connection->fragmented_value_offset = 0;
202                         num_written_bytes = num_bytes_to_write;
203                         avrcp_target_pack_single_element_attribute_string(packet, pos, UTF8, attr_id, attr_value, attr_value_len, connection->now_playing_info[attr_index].len, header);
204                         break;
205                     }
206                     fragmented = 1;
207                     num_written_bytes = num_free_bytes;
208                     attr_value_len = num_free_bytes - header * AVRCP_ATTR_HEADER_LEN;
209                     avrcp_target_pack_single_element_attribute_string(packet, pos, UTF8, attr_id, attr_value, attr_value_len, connection->now_playing_info[attr_index].len, header);
210                     connection->fragmented_value_offset += attr_value_len;
211                     break;
212                 }
213             }
214             pos += num_written_bytes;
215             num_free_bytes -= num_written_bytes;
216         }
217         if (!fragmented){
218             connection->next_attr_id++;
219         }
220     }
221 
222     if (fragmented){
223         switch (connection->packet_type){
224             case AVRCP_SINGLE_PACKET:
225                 connection->packet_type = AVRCP_START_PACKET;
226                 break;
227             default:
228                 connection->packet_type = AVRCP_CONTINUE_PACKET;
229                 break;
230         }
231     } else {
232         if (connection->next_attr_id >= AVRCP_MEDIA_ATTR_SONG_LENGTH){ // DONE
233             if (connection->packet_type != AVRCP_SINGLE_PACKET){
234                 connection->packet_type = AVRCP_END_PACKET;
235             }
236         }
237     }
238     packet[pos_packet_type] = connection->packet_type;
239     // store attr value length
240     big_endian_store_16(packet, playing_info_buffer_len_position, pos - playing_info_buffer_len_position - 2);
241     return l2cap_send_prepared(cid, size);
242 }
243 
244 
245 
246 static int avrcp_target_send_response(uint16_t cid, avrcp_connection_t * connection){
247     int pos = 0;
248     l2cap_reserve_packet_buffer();
249     uint8_t * packet = l2cap_get_outgoing_buffer();
250 
251     // transport header
252     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
253 
254     // TODO: check for fragmentation
255     connection->packet_type = AVRCP_SINGLE_PACKET;
256 
257     packet[pos++] = (connection->transaction_label << 4) | (connection->packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0;
258     // Profile IDentifier (PID)
259     packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
260     packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
261     // command_type
262     packet[pos++] = connection->command_type;
263     // subunit_type | subunit ID
264     packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id;
265     // opcode
266     packet[pos++] = (uint8_t)connection->command_opcode;
267     // operands
268     memcpy(packet+pos, connection->cmd_operands, connection->cmd_operands_length);
269     // printf_hexdump(packet+pos, connection->cmd_operands_length);
270 
271     pos += connection->cmd_operands_length;
272     connection->wait_to_send = 0;
273     return l2cap_send_prepared(cid, pos);
274 }
275 
276 static uint8_t avrcp_target_response_reject(avrcp_connection_t * connection, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t opcode, avrcp_pdu_id_t pdu_id, avrcp_status_code_t status){
277     // AVRCP_CTYPE_RESPONSE_REJECTED
278     connection->command_type = AVRCP_CTYPE_RESPONSE_REJECTED;
279     connection->subunit_type = subunit_type;
280     connection->subunit_id =   subunit_id;
281     connection->command_opcode = opcode;
282     // company id is 3 bytes long
283     int pos = connection->cmd_operands_length;
284     connection->cmd_operands[pos++] = pdu_id;
285     connection->cmd_operands[pos++] = 0;
286     // param length
287     big_endian_store_16(connection->cmd_operands, pos, 1);
288     pos += 2;
289     connection->cmd_operands[pos++] = status;
290     connection->cmd_operands_length = pos;
291     connection->state = AVCTP_W2_SEND_RESPONSE;
292     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
293     return ERROR_CODE_SUCCESS;
294 }
295 
296 static uint8_t avrcp_target_response_not_implemented(avrcp_connection_t * connection, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t opcode, avrcp_pdu_id_t pdu_id, uint8_t event_id){
297     connection->command_type = AVRCP_CTYPE_RESPONSE_NOT_IMPLEMENTED;
298     connection->subunit_type = subunit_type;
299     connection->subunit_id =   subunit_id;
300     connection->command_opcode = opcode;
301 
302     // company id is 3 bytes long
303     int pos = connection->cmd_operands_length;
304     connection->cmd_operands[pos++] = pdu_id;
305     connection->cmd_operands[pos++] = 0;
306     // param length
307     big_endian_store_16(connection->cmd_operands, pos, 1);
308     pos += 2;
309     connection->cmd_operands[pos++] = event_id;
310     connection->cmd_operands_length = pos;
311 
312     connection->state = AVCTP_W2_SEND_RESPONSE;
313     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
314     return ERROR_CODE_SUCCESS;
315 }
316 
317 static uint8_t avrcp_target_response_vendor_dependent_interim(avrcp_connection_t * connection, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t opcode, avrcp_pdu_id_t pdu_id, uint8_t event_id, const uint8_t * value, uint16_t value_len){
318     connection->command_type = AVRCP_CTYPE_RESPONSE_INTERIM;
319     connection->subunit_type = subunit_type;
320     connection->subunit_id =   subunit_id;
321     connection->command_opcode = opcode;
322 
323     // company id is 3 bytes long
324     int pos = connection->cmd_operands_length;
325     connection->cmd_operands[pos++] = pdu_id;
326     connection->cmd_operands[pos++] = 0;
327     // param length
328     big_endian_store_16(connection->cmd_operands, pos, 1 + value_len);
329     pos += 2;
330     connection->cmd_operands[pos++] = event_id;
331     if (value && value_len > 0){
332         memcpy(connection->cmd_operands + pos, value, value_len);
333         pos += value_len;
334     }
335     connection->cmd_operands_length = pos;
336 
337     connection->state = AVCTP_W2_SEND_RESPONSE;
338     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
339     return ERROR_CODE_SUCCESS;
340 }
341 
342 // static uint8_t avrcp_target_response_vendor_dependent_changed(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id, uint8_t event_id){
343 //     connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
344 //     connection->command_type = AVRCP_CTYPE_RESPONSE_CHANGED_STABLE;
345 //     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
346 //     connection->subunit_id = AVRCP_SUBUNIT_ID;
347 
348 //     // company id is 3 bytes long
349 //     int pos = connection->cmd_operands_length;
350 //     connection->cmd_operands[pos++] = pdu_id;
351 //     connection->cmd_operands[pos++] = 0;
352 //     // param length
353 //     big_endian_store_16(connection->cmd_operands, pos, 1);
354 //     pos += 2;
355 //     connection->cmd_operands[pos++] = event_id;
356 //     connection->cmd_operands_length = pos;
357 
358 //     connection->state = AVCTP_W2_SEND_RESPONSE;
359 //     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
360 //     return ERROR_CODE_SUCCESS;
361 // }
362 
363 static uint8_t avrcp_target_pass_through_response(uint16_t avrcp_cid, avrcp_command_type_t cmd_type, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
364     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
365     if (!connection){
366         log_error("avrcp_target_operation_reject: could not find a connection.");
367         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
368     }
369     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
370     printf("avrcp_target_pass_through_response: operation 0x%02x, operands length %d\n", opid, operands_length);
371 
372     connection->command_type = cmd_type;
373     connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
374     connection->subunit_id =   AVRCP_SUBUNIT_ID;
375     connection->command_opcode = AVRCP_CMD_OPCODE_PASS_THROUGH;
376 
377     int pos = 0;
378     connection->cmd_operands[pos++] = opid;
379     connection->cmd_operands[pos++] = operands_length;
380     if (operands_length == 1){
381         connection->cmd_operands[pos++] = operand;
382     }
383     connection->cmd_operands_length = pos;
384 
385     connection->state = AVCTP_W2_SEND_RESPONSE;
386     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
387     return ERROR_CODE_SUCCESS;
388 }
389 
390 uint8_t avrcp_target_operation_rejected(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
391     return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_REJECTED, opid, operands_length, operand);
392 }
393 
394 uint8_t avrcp_target_operation_accepted(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
395     return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand);
396 }
397 
398 uint8_t avrcp_target_operation_not_implemented(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint8_t operands_length, uint8_t operand){
399     return avrcp_target_pass_through_response(avrcp_cid, AVRCP_CTYPE_RESPONSE_ACCEPTED, opid, operands_length, operand);
400 }
401 
402 void avrcp_target_set_unit_info(uint16_t avrcp_cid, avrcp_subunit_type_t unit_type, uint32_t company_id){
403     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
404     if (!connection){
405         log_error("avrcp_target_operation_reject: could not find a connection.");
406         return;
407     }
408     connection->unit_type = unit_type;
409     connection->company_id = company_id;
410 }
411 
412 void 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){
413     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
414     if (!connection){
415         log_error("avrcp_target_operation_reject: could not find a connection.");
416         return;
417     }
418     connection->subunit_info_type = subunit_type;
419     connection->subunit_info_data = subunit_info_data;
420     connection->subunit_info_data_size = subunit_info_data_size;
421 }
422 
423 static uint8_t avrcp_target_unit_info(avrcp_connection_t * connection){
424     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
425 
426     uint8_t unit = 0;
427     connection->command_type = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE;
428     connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
429     connection->subunit_id =   AVRCP_SUBUNIT_ID_IGNORE;
430     connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO;
431 
432     connection->cmd_operands_length = 5;
433     connection->cmd_operands[0] = 0x07;
434     connection->cmd_operands[1] = (connection->unit_type << 4) | unit;
435     // company id is 3 bytes long
436     big_endian_store_32(connection->cmd_operands, 2, connection->company_id);
437 
438     connection->state = AVCTP_W2_SEND_RESPONSE;
439     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
440     return ERROR_CODE_SUCCESS;
441 }
442 
443 static uint8_t avrcp_target_subunit_info(avrcp_connection_t * connection, uint8_t offset){
444     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
445     if (offset - 4 > connection->subunit_info_data_size) return AVRCP_STATUS_INVALID_PARAMETER;
446 
447     connection->command_opcode = AVRCP_CMD_OPCODE_SUBUNIT_INFO;
448     connection->command_type = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE;
449     connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
450     connection->subunit_id =   AVRCP_SUBUNIT_ID_IGNORE;
451     printf("avrcp_target_subunit_info  subunit_type %d\n", connection->subunit_type);
452 
453     uint8_t page = offset / 4;
454     uint8_t extension_code = 7;
455     connection->cmd_operands_length = 5;
456     connection->cmd_operands[0] = (page << 4) | extension_code;
457 
458     memcpy(connection->cmd_operands+1, connection->subunit_info_data + offset, 4);
459 
460     connection->state = AVCTP_W2_SEND_RESPONSE;
461     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
462     return ERROR_CODE_SUCCESS;
463 }
464 
465 static inline uint8_t avrcp_prepare_vendor_dependent_response(uint16_t avrcp_cid, avrcp_connection_t ** out_connection, avrcp_pdu_id_t pdu_id, uint16_t param_length){
466     *out_connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
467     if (!*out_connection){
468         log_error("avrcp tartget: could not find a connection.");
469         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
470     }
471 
472     if ((*out_connection)->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
473     (*out_connection)->command_opcode  = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
474     (*out_connection)->command_type    = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE;
475     (*out_connection)->subunit_type    = AVRCP_SUBUNIT_TYPE_PANEL;
476     (*out_connection)->subunit_id      = AVRCP_SUBUNIT_ID;
477 
478     (*out_connection)->cmd_operands[(*out_connection)->cmd_operands_length++] = pdu_id;
479     // reserved
480     (*out_connection)->cmd_operands[(*out_connection)->cmd_operands_length++] = 0;
481     // param length
482     big_endian_store_16((*out_connection)->cmd_operands, (*out_connection)->cmd_operands_length, param_length);
483     (*out_connection)->cmd_operands_length += 2;
484     return ERROR_CODE_SUCCESS;
485 }
486 
487 static uint8_t avrcp_target_capability(uint16_t avrcp_cid, avrcp_capability_id_t capability_id, uint8_t capabilities_num, uint8_t * capabilities, uint8_t size){
488     avrcp_connection_t * connection = NULL;
489     uint8_t status = avrcp_prepare_vendor_dependent_response(avrcp_cid, &connection, AVRCP_PDU_ID_GET_CAPABILITIES, 2+size);
490     if (status != ERROR_CODE_SUCCESS) return status;
491 
492     connection->cmd_operands[connection->cmd_operands_length++] = capability_id;
493     connection->cmd_operands[connection->cmd_operands_length++] = capabilities_num;
494     memcpy(connection->cmd_operands+connection->cmd_operands_length, capabilities, size);
495     connection->cmd_operands_length += size;
496 
497     connection->state = AVCTP_W2_SEND_RESPONSE;
498     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
499     return ERROR_CODE_SUCCESS;
500 }
501 
502 uint8_t avrcp_target_supported_events(uint16_t avrcp_cid, uint8_t capabilities_num, uint8_t * capabilities, uint8_t size){
503     return avrcp_target_capability(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT, capabilities_num, capabilities, size);
504 }
505 
506 uint8_t avrcp_target_supported_companies(uint16_t avrcp_cid, uint8_t capabilities_num, uint8_t * capabilities, uint8_t size ){
507     return avrcp_target_capability(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY, capabilities_num, capabilities, size);
508 }
509 
510 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){
511     avrcp_connection_t * connection = NULL;
512     uint8_t status = avrcp_prepare_vendor_dependent_response(avrcp_cid, &connection, AVRCP_PDU_ID_GET_PLAY_STATUS, 11);
513     if (status != ERROR_CODE_SUCCESS) return status;
514 
515     big_endian_store_32(connection->cmd_operands, connection->cmd_operands_length, song_length_ms);
516     connection->cmd_operands_length += 4;
517     big_endian_store_32(connection->cmd_operands, connection->cmd_operands_length, song_position_ms);
518     connection->cmd_operands_length += 4;
519     connection->cmd_operands[connection->cmd_operands_length++] = play_status;
520 
521     connection->state = AVCTP_W2_SEND_RESPONSE;
522     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
523     return ERROR_CODE_SUCCESS;
524 }
525 
526 static uint8_t avrcp_target_now_playing_info(avrcp_connection_t * connection){
527     connection->now_playing_info_response = 1;
528     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
529     connection->command_opcode  = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
530     connection->command_type    = AVRCP_CTYPE_RESPONSE_IMPLEMENTED_STABLE;
531     connection->subunit_type    = AVRCP_SUBUNIT_TYPE_PANEL;
532     connection->subunit_id      = AVRCP_SUBUNIT_ID;
533 
534     connection->state = AVCTP_W2_SEND_RESPONSE;
535     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
536     return ERROR_CODE_SUCCESS;
537 }
538 
539 static uint8_t avrcp_target_store_media_attr(avrcp_connection_t * connection, avrcp_media_attribute_id_t attr_id, const char * value){
540     int index = attr_id - 1;
541     if (!value) return AVRCP_STATUS_INVALID_PARAMETER;
542     connection->now_playing_info[index].value = (uint8_t*)value;
543     connection->now_playing_info[index].len   = strlen(value);
544     printf("store %lu bytes, %s\n",  strlen(value), value);
545     return ERROR_CODE_SUCCESS;
546 }
547 
548 uint8_t avrcp_target_set_playback_status(uint16_t avrcp_cid, avrcp_playback_status_t playback_status){
549     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
550     if (!connection){
551         log_error("avrcp_unit_info: could not find a connection.");
552         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
553     }
554     if (connection->playback_status == playback_status) return ERROR_CODE_SUCCESS;
555 
556     connection->playback_status = playback_status;
557     connection->playback_status_changed = 1;
558     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
559     return ERROR_CODE_SUCCESS;
560 }
561 
562 void avrcp_target_set_now_playing_info(uint16_t avrcp_cid, const avrcp_track_t * current_track, uint16_t total_tracks){
563     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
564     printf("avrcp_target_now_playing_info 0\n");
565     if (!connection){
566         printf("avrcp_unit_info: could not find a connection. cid 0x%02x\n", avrcp_cid);
567         return;
568     }
569     printf("avrcp_target_set_now_playing_info 1\n");
570     if (!current_track){
571         connection->track_selected = 0;
572         connection->playback_status = AVRCP_PLAYBACK_STATUS_ERROR;
573         return;
574     }
575     printf("avrcp_target_set_now_playing_info 2\n");
576 
577     printf("store track_id %s\n", current_track->track_id );
578     memcpy(connection->track_id, current_track->track_id, 8);
579     connection->song_length_ms = current_track->song_length_ms;
580     connection->track_nr = current_track->track_nr;
581     connection->total_tracks = total_tracks;
582     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_TITLE, current_track->title);
583     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ARTIST, current_track->artist);
584     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_ALBUM, current_track->album);
585     avrcp_target_store_media_attr(connection, AVRCP_MEDIA_ATTR_GENRE, current_track->genre);
586     connection->track_selected = 1;
587 
588     if (connection->notifications_enabled & (1 << AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED)) {
589         connection->track_changed = 1;
590         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
591     }
592     return;
593 }
594 
595 uint8_t avrcp_target_playing_content_changed(uint16_t avrcp_cid){
596     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
597     if (!connection){
598         log_error("avrcp_unit_info: could not find a connection.");
599         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
600     }
601     connection->playing_content_changed = 1;
602     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
603     return ERROR_CODE_SUCCESS;
604 }
605 
606 uint8_t avrcp_target_battery_status_changed(uint16_t avrcp_cid, avrcp_battery_status_t battery_status){
607     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
608     if (!connection){
609         log_error("avrcp_unit_info: could not find a connection.");
610         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
611     }
612     if (connection->battery_status == battery_status) return ERROR_CODE_SUCCESS;
613     connection->battery_status = battery_status;
614     connection->battery_status_changed = 1;
615     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
616     return ERROR_CODE_SUCCESS;
617 }
618 
619 uint8_t avrcp_target_volume_changed(uint16_t avrcp_cid, uint8_t volume_percentage){
620         avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
621     if (!connection){
622         log_error("avrcp_unit_info: could not find a connection.");
623         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
624     }
625     if (connection->volume_percentage == volume_percentage) return ERROR_CODE_SUCCESS;
626 
627     connection->volume_percentage = volume_percentage;
628     connection->volume_percentage_changed = 1;
629     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
630     return ERROR_CODE_SUCCESS;
631 }
632 
633 
634 static uint8_t * avrcp_get_company_id(uint8_t *packet, uint16_t size){
635     UNUSED(size);
636     return packet + 6;
637 }
638 
639 static uint8_t * avrcp_get_pdu(uint8_t *packet, uint16_t size){
640     UNUSED(size);
641     return packet + 9;
642 }
643 
644 static uint8_t avrcp_is_receive_pass_through_cmd(uint8_t operation_id){
645     return operation_id & 0x80;
646 }
647 
648 static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
649     UNUSED(connection);
650     UNUSED(packet);
651     UNUSED(size);
652 
653     // uint8_t opcode;
654 
655     uint8_t transport_header = packet[0];
656     connection->transaction_label = transport_header >> 4;
657     // uint8_t packet_type = (transport_header & 0x0F) >> 2;
658     // uint8_t frame_type = (transport_header & 0x03) >> 1;
659     // uint8_t ipid = transport_header & 0x01;
660     // uint8_t byte_value = packet[2];
661     // uint16_t pid = (byte_value << 8) | packet[2];
662 
663     // avrcp_command_type_t ctype = (avrcp_command_type_t) packet[3];
664     // uint8_t byte_value = packet[4];
665     avrcp_subunit_type_t subunit_type = (avrcp_subunit_type_t) (packet[4] >> 3);
666     avrcp_subunit_id_t   subunit_id   = (avrcp_subunit_id_t) (packet[4] & 0x07);
667     // opcode = packet[pos++];
668 
669     // printf("    Transport header 0x%02x (transaction_label %d, packet_type %d, frame_type %d, ipid %d), pid 0x%4x\n",
670     //     transport_header, transaction_label, packet_type, frame_type, ipid, pid);
671     // printf_hexdump(packet+pos, size-pos);
672 
673     avrcp_command_opcode_t opcode = avrcp_cmd_opcode(packet,size);
674     uint8_t * company_id = avrcp_get_company_id(packet, size);
675     uint8_t * pdu = avrcp_get_pdu(packet, size);
676     // uint16_t param_length = big_endian_read_16(pdu, 2);
677 
678     int pos = 4;
679     uint8_t   pdu_id;
680     connection->cmd_operands_length = 0;
681 
682     switch (opcode){
683         case AVRCP_CMD_OPCODE_UNIT_INFO:
684             avrcp_target_unit_info(connection);
685             break;
686         case AVRCP_CMD_OPCODE_SUBUNIT_INFO:{
687             uint8_t offset =  4 * (packet[pos+2]>>4);
688             avrcp_target_subunit_info(connection, offset);
689             break;
690         }
691         case AVRCP_CMD_OPCODE_PASS_THROUGH:{
692             log_info("AVRCP_OPERATION_ID 0x%02x, operands length %d, operand %d", packet[6], packet[7], packet[8]);
693             avrcp_operation_id_t operation_id = packet[6];
694 
695             if (avrcp_is_receive_pass_through_cmd(operation_id)){
696                 operation_id = packet[6] & 0x7F;
697             }
698 
699             switch (operation_id){
700                 case AVRCP_OPERATION_ID_PLAY:
701                 case AVRCP_OPERATION_ID_PAUSE:
702                 case AVRCP_OPERATION_ID_STOP:
703                     avrcp_target_operation_accepted(connection->avrcp_cid, packet[6], packet[7], packet[8]);
704                     avrcp_target_emit_operation(avrcp_target_context.avrcp_callback, connection->avrcp_cid, packet[6], packet[7], packet[8]);
705                     break;
706                 case AVRCP_OPERATION_ID_REWIND:
707                 case AVRCP_OPERATION_ID_FAST_FORWARD:
708                 case AVRCP_OPERATION_ID_FORWARD:
709                 case AVRCP_OPERATION_ID_BACKWARD:
710                 case AVRCP_OPERATION_ID_SKIP:
711                 case AVRCP_OPERATION_ID_VOLUME_UP:
712                 case AVRCP_OPERATION_ID_VOLUME_DOWN:
713                 case AVRCP_OPERATION_ID_MUTE:
714                 case AVRCP_OPERATION_ID_UNDEFINED:
715                     avrcp_target_operation_not_implemented(connection->avrcp_cid, packet[6], packet[7], packet[8]);
716                     return;
717                 default:
718                     avrcp_target_operation_not_implemented(connection->avrcp_cid, packet[6], packet[7], packet[8]);
719                     break;
720             }
721             break;
722         }
723 
724         case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT:
725             pdu_id = pdu[0];
726             // 1 - reserved
727             // 2-3 param length,
728             memcpy(connection->cmd_operands, company_id, 3);
729             connection->cmd_operands_length = 3;
730             switch (pdu_id){
731                 case AVRCP_PDU_ID_GET_CAPABILITIES:{
732                     avrcp_capability_id_t capability_id = (avrcp_capability_id_t) pdu[pos];
733                     switch (capability_id){
734                         case AVRCP_CAPABILITY_ID_EVENT:
735                             avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_EVENT_IDS_QUERY);
736                             break;
737                         case AVRCP_CAPABILITY_ID_COMPANY:
738                             avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_COMPANY_IDS_QUERY);
739                             break;
740                         default:
741                             avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
742                             break;
743                     }
744                     break;
745                 }
746                 case AVRCP_PDU_ID_GET_PLAY_STATUS:
747                     avrcp_target_emit_respond_vendor_dependent_query(avrcp_target_context.avrcp_callback, connection->avrcp_cid, AVRCP_SUBEVENT_PLAY_STATUS_QUERY);
748                     break;
749                 case AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE:
750                     if (pdu[4] != AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES){
751                         avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND);
752                         return;
753                     }
754                     connection->now_playing_info_response = 1;
755                     avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
756                     break;
757                 case AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES:{
758                     uint8_t play_identifier[8];
759                     memset(play_identifier, 0, 8);
760                     if (memcmp(pdu+pos, play_identifier, 8) != 0) {
761                         avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
762                         return;
763                     }
764                     pos += 8;
765                     uint8_t attribute_count = pdu[pos++];
766                     connection->next_attr_id = AVRCP_MEDIA_ATTR_NONE;
767                     if (!attribute_count){
768                         connection->now_playing_info_attr_bitmap = 0xFE;
769                     } else {
770                         int i;
771                         connection->now_playing_info_attr_bitmap = 0;
772                         for (i=0; i < attribute_count; i++){
773                             uint16_t attr_id = big_endian_read_16(pdu, pos);
774                             pos += 2;
775                             connection->now_playing_info_attr_bitmap |= (1 << attr_id);
776                         }
777                     }
778                     log_info("now_playing_info_attr_bitmap 0x%02x", connection->now_playing_info_attr_bitmap);
779                     avrcp_target_now_playing_info(connection);
780                     break;
781                 }
782                 case AVRCP_PDU_ID_REGISTER_NOTIFICATION:{
783                     // 0 - pdu id
784                     // 1 - reserved
785                     // 2-3 param length
786                     avrcp_notification_event_id_t event_id = (avrcp_notification_event_id_t) pdu[4];
787                     uint16_t event_mask = (1 << event_id);
788 
789                     switch (event_id){
790                         case AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED:
791                             connection->notifications_enabled |= event_mask;
792                             if (connection->track_selected){
793                                 avrcp_target_response_vendor_dependent_interim(connection, subunit_type, subunit_id, opcode, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_SELECTED, 8);
794                             } else {
795                                 avrcp_target_response_vendor_dependent_interim(connection, subunit_type, subunit_id, opcode, pdu_id, event_id, AVRCP_NOTIFICATION_TRACK_NOT_SELECTED, 8);
796                             }
797                             break;
798                         case AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED:
799                             connection->notifications_enabled |= event_mask;
800                             avrcp_target_response_vendor_dependent_interim(connection, subunit_type, subunit_id, opcode, pdu_id, event_id, (const uint8_t *)&connection->playback_status, 1);
801                             break;
802                         case AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED:
803                             connection->notifications_enabled |= event_mask;
804                             avrcp_target_response_vendor_dependent_interim(connection, subunit_type, subunit_id, opcode, pdu_id, event_id, NULL, 0);
805                             break;
806                         case AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED:
807                             connection->notifications_enabled |= event_mask;
808                             avrcp_target_response_vendor_dependent_interim(connection, subunit_type, subunit_id, opcode, pdu_id, event_id, (const uint8_t *)&connection->volume_percentage, 1);
809                             break;
810                         case AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED:
811                             connection->notifications_enabled |= event_mask;
812                             avrcp_target_response_vendor_dependent_interim(connection, subunit_type, subunit_id, opcode, pdu_id, event_id, (const uint8_t *)&connection->battery_status, 1);
813                             break;
814                         case AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED:
815                         case AVRCP_NOTIFICATION_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
816                         case AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED:
817                         case AVRCP_NOTIFICATION_EVENT_UIDS_CHANGED:
818                             avrcp_target_response_not_implemented(connection, subunit_type, subunit_id, opcode, pdu_id, event_id);
819                             return;
820                         default:
821                             avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_PARAMETER);
822                             return;
823                     }
824                     break;
825                 }
826                 default:
827                     printf("AVRCP target: unhandled pdu id 0x%02x\n", pdu_id);
828                     avrcp_target_response_reject(connection, subunit_type, subunit_id, opcode, pdu_id, AVRCP_STATUS_INVALID_COMMAND);
829                     break;
830             }
831             break;
832         default:
833             printf("AVRCP target: opcode 0x%02x not implemented\n", avrcp_cmd_opcode(packet,size));
834             break;
835     }
836 }
837 
838 static int avrcp_target_send_notification(uint16_t cid, avrcp_connection_t * connection, uint8_t notification_id, uint8_t * value, uint16_t value_len){
839     if (!connection){
840         log_error("avrcp tartget: could not find a connection.");
841         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
842     }
843 
844     connection->command_opcode  = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
845     connection->command_type    = AVRCP_CTYPE_RESPONSE_CHANGED_STABLE;
846     connection->subunit_type    = AVRCP_SUBUNIT_TYPE_PANEL;
847     connection->subunit_id      = AVRCP_SUBUNIT_ID;
848 
849     uint16_t pos = 0;
850     l2cap_reserve_packet_buffer();
851     uint8_t * packet = l2cap_get_outgoing_buffer();
852     uint16_t  size   = l2cap_get_remote_mtu_for_local_cid(connection->l2cap_signaling_cid);
853 
854     connection->packet_type = AVRCP_SINGLE_PACKET;
855     packet[pos++] = (connection->transaction_label << 4) | (connection->packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0;
856     // Profile IDentifier (PID)
857     packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
858     packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
859 
860     // command_type
861     packet[pos++] = connection->command_type;
862     // subunit_type | subunit ID
863     packet[pos++] = (connection->subunit_type << 3) | connection->subunit_id;
864     // opcode
865     packet[pos++] = (uint8_t)connection->command_opcode;
866 
867     // company id is 3 bytes long
868     big_endian_store_24(packet, pos, BT_SIG_COMPANY_ID);
869     pos += 3;
870 
871     packet[pos++] = AVRCP_PDU_ID_REGISTER_NOTIFICATION;
872     packet[pos++] = 0;
873     uint16_t remainig_outgoing_buffer_size = size > (value_len + 2 + 1) ? size - (value_len + 2 + 1): 0;
874     uint16_t caped_value_len = value_len > remainig_outgoing_buffer_size ? remainig_outgoing_buffer_size : value_len;
875     big_endian_store_16(packet, pos, caped_value_len);
876     pos += 2;
877     packet[pos++] = notification_id;
878 
879     memcpy(packet+pos, value, caped_value_len);
880     pos += caped_value_len;
881     connection->wait_to_send = 0;
882     return l2cap_send_prepared(cid, pos);
883 }
884 
885 static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
886     avrcp_connection_t * connection;
887     switch (packet_type) {
888         case L2CAP_DATA_PACKET:
889             connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_target_context);
890             if (!connection) break;
891             avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size);
892             break;
893         case HCI_EVENT_PACKET:
894             switch (hci_event_packet_get_type(packet)){
895                 case L2CAP_EVENT_CAN_SEND_NOW:{
896                     connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_target_context);
897                     if (!connection) break;
898 
899                     if (connection->now_playing_info_response){
900                         connection->now_playing_info_response = 0;
901                         avrcp_target_send_now_playing_info(connection->l2cap_signaling_cid, connection);
902                         break;
903                     }
904                     break;
905 
906                     if (connection->track_changed){
907                         connection->track_changed = 0;
908                         avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED, connection->track_id, 8);
909                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
910                         break;
911                     }
912 
913                     if (connection->playback_status_changed){
914                         connection->playback_status_changed = 0;
915                         avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED, &connection->playback_status_changed, 1);
916                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
917                         break;
918                     }
919 
920                     if (connection->playing_content_changed){
921                         connection->playing_content_changed = 0;
922                         avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED, NULL, 0);
923                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
924                         break;
925                     }
926 
927                     if (connection->battery_status_changed){
928                         connection->battery_status_changed = 0;
929                         avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED, (uint8_t *)&connection->battery_status, 1);
930                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
931                         break;
932                     }
933 
934                     if (connection->volume_percentage_changed){
935                         connection->volume_percentage_changed = 0;
936                         avrcp_target_send_notification(connection->l2cap_signaling_cid, connection, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED, &connection->volume_percentage, 1);
937                         avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
938                         break;
939                     }
940 
941                     switch (connection->state){
942                         case AVCTP_W2_SEND_RESPONSE:
943                             connection->state = AVCTP_CONNECTION_OPENED;
944                             // if (connection->now_playing_info_response){
945                             //     connection->now_playing_info_response = 0;
946                             //     avrcp_target_send_now_playing_info(connection->l2cap_signaling_cid, connection);
947                             //     break;
948                             // }
949                             avrcp_target_send_response(connection->l2cap_signaling_cid, connection);
950                             break;
951                         default:
952                             return;
953                     }
954                     break;
955             }
956             default:
957                 avrcp_packet_handler(packet_type, channel, packet, size, &avrcp_target_context);
958                 break;
959         }
960         default:
961             break;
962     }
963 }
964 
965 void avrcp_target_init(void){
966     avrcp_target_context.role = AVRCP_TARGET;
967     avrcp_target_context.connections = NULL;
968     avrcp_target_context.packet_handler = avrcp_controller_packet_handler;
969     l2cap_register_service(&avrcp_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0);
970 }
971 
972 void avrcp_target_register_packet_handler(btstack_packet_handler_t callback){
973     if (callback == NULL){
974         log_error("avrcp_register_packet_handler called with NULL callback");
975         return;
976     }
977     avrcp_target_context.avrcp_callback = callback;
978 }
979 
980 uint8_t avrcp_target_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){
981     return avrcp_connect(bd_addr, &avrcp_target_context, avrcp_cid);
982 }
983 
984 uint8_t avrcp_target_disconnect(uint16_t avrcp_cid){
985     avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context);
986     if (!connection){
987         log_error("avrcp_get_capabilities: could not find a connection.");
988         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
989     }
990     if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
991     l2cap_disconnect(connection->l2cap_signaling_cid, 0);
992     return ERROR_CODE_SUCCESS;
993 }
994 
995