xref: /btstack/src/classic/avrcp_browsing_controller.c (revision b99ca858cd8c5686b3847d38bf8caa6361ca629c)
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_browsing_controller.c"
39 
40 #include <stdint.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <inttypes.h>
45 #include "btstack.h"
46 #include "classic/avrcp.h"
47 #include "classic/avrcp_browsing_controller.h"
48 
49 #define PSM_AVCTP_BROWSING              0x001b
50 
51 static void avrcp_browser_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, avrcp_context_t * context);
52 static void avrcp_browsing_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
53 
54 static void avrcp_emit_browsing_connection_established(btstack_packet_handler_t callback, uint16_t browsing_cid, bd_addr_t addr, uint8_t status){
55     btstack_assert(callback != NULL);
56 
57     uint8_t event[12];
58     int pos = 0;
59     event[pos++] = HCI_EVENT_AVRCP_META;
60     event[pos++] = sizeof(event) - 2;
61     event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_ESTABLISHED;
62     event[pos++] = status;
63     reverse_bd_addr(addr,&event[pos]);
64     pos += 6;
65     little_endian_store_16(event, pos, browsing_cid);
66     pos += 2;
67     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
68 }
69 
70 static void avrcp_emit_incoming_browsing_connection(btstack_packet_handler_t callback, uint16_t browsing_cid, bd_addr_t addr){
71     btstack_assert(callback != NULL);
72 
73     uint8_t event[11];
74     int pos = 0;
75     event[pos++] = HCI_EVENT_AVRCP_META;
76     event[pos++] = sizeof(event) - 2;
77     event[pos++] = AVRCP_SUBEVENT_INCOMING_BROWSING_CONNECTION;
78     reverse_bd_addr(addr,&event[pos]);
79     pos += 6;
80     little_endian_store_16(event, pos, browsing_cid);
81     pos += 2;
82     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
83 }
84 
85 static void avrcp_emit_browsing_connection_closed(btstack_packet_handler_t callback, uint16_t browsing_cid){
86     btstack_assert(callback != NULL);
87 
88     uint8_t event[5];
89     int pos = 0;
90     event[pos++] = HCI_EVENT_AVRCP_META;
91     event[pos++] = sizeof(event) - 2;
92     event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_RELEASED;
93     little_endian_store_16(event, pos, browsing_cid);
94     pos += 2;
95     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
96 }
97 
98 static void avrcp_browser_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, avrcp_context_t * context){
99     UNUSED(channel);
100     UNUSED(size);
101     bd_addr_t event_addr;
102     uint16_t local_cid;
103     uint8_t  status;
104     avrcp_browsing_connection_t * browsing_connection = NULL;
105     avrcp_connection_t * avrcp_connection = NULL;
106 
107     if (packet_type != HCI_EVENT_PACKET) return;
108 
109     switch (hci_event_packet_get_type(packet)) {
110         case HCI_EVENT_DISCONNECTION_COMPLETE:
111             avrcp_emit_browsing_connection_closed(context->browsing_avrcp_callback, 0);
112             break;
113         case L2CAP_EVENT_INCOMING_CONNECTION:
114             l2cap_event_incoming_connection_get_address(packet, event_addr);
115             local_cid = l2cap_event_incoming_connection_get_local_cid(packet);
116             avrcp_connection = get_avrcp_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, event_addr);
117             if (!avrcp_connection) {
118                 log_error("No previously created AVRCP controller connections");
119                 l2cap_decline_connection(local_cid);
120                 break;
121             }
122             browsing_connection = avrcp_browsing_create_connection(avrcp_connection);
123             browsing_connection->l2cap_browsing_cid = local_cid;
124             browsing_connection->state = AVCTP_CONNECTION_W4_ERTM_CONFIGURATION;
125             log_info("Emit AVRCP_SUBEVENT_INCOMING_BROWSING_CONNECTION browsing_cid 0x%02x, l2cap_signaling_cid 0x%02x\n", avrcp_connection->avrcp_browsing_cid, browsing_connection->l2cap_browsing_cid);
126             avrcp_emit_incoming_browsing_connection(context->browsing_avrcp_callback, avrcp_connection->avrcp_browsing_cid, event_addr);
127             break;
128 
129         case L2CAP_EVENT_CHANNEL_OPENED:
130             l2cap_event_channel_opened_get_address(packet, event_addr);
131             status = l2cap_event_channel_opened_get_status(packet);
132             local_cid = l2cap_event_channel_opened_get_local_cid(packet);
133 
134             avrcp_connection = get_avrcp_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, event_addr);
135             if (!avrcp_connection){
136                 log_error("Failed to find AVRCP connection for bd_addr %s", bd_addr_to_str(event_addr));
137                 avrcp_emit_browsing_connection_established(context->browsing_avrcp_callback, local_cid, event_addr, L2CAP_LOCAL_CID_DOES_NOT_EXIST);
138                 l2cap_disconnect(local_cid, 0); // reason isn't used
139                 break;
140             }
141 
142             browsing_connection = avrcp_connection->browsing_connection;
143             if (status != ERROR_CODE_SUCCESS){
144                 log_info("L2CAP connection to connection %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
145                 avrcp_emit_browsing_connection_established(context->browsing_avrcp_callback, avrcp_connection->avrcp_browsing_cid, event_addr, status);
146                 btstack_memory_avrcp_browsing_connection_free(browsing_connection);
147                 avrcp_connection->browsing_connection = NULL;
148                 break;
149             }
150             browsing_connection->l2cap_browsing_cid = local_cid;
151 
152             log_info("L2CAP_EVENT_CHANNEL_OPENED browsing cid 0x%02x, l2cap cid 0x%02x", avrcp_connection->avrcp_browsing_cid, browsing_connection->l2cap_browsing_cid);
153             browsing_connection->state = AVCTP_CONNECTION_OPENED;
154             avrcp_emit_browsing_connection_established(context->browsing_avrcp_callback, avrcp_connection->avrcp_browsing_cid, event_addr, ERROR_CODE_SUCCESS);
155             break;
156 
157         case L2CAP_EVENT_CHANNEL_CLOSED:
158             local_cid = l2cap_event_channel_closed_get_local_cid(packet);
159             avrcp_connection = get_avrcp_connection_for_browsing_l2cap_cid_for_role(context->role, local_cid);
160 
161             if (avrcp_connection && avrcp_connection->browsing_connection){
162                 avrcp_emit_browsing_connection_closed(context->browsing_avrcp_callback, avrcp_connection->avrcp_browsing_cid);
163                 // free connection
164                 btstack_memory_avrcp_browsing_connection_free(avrcp_connection->browsing_connection);
165                 avrcp_connection->browsing_connection = NULL;
166                 break;
167             }
168             break;
169         default:
170             break;
171     }
172 }
173 
174 static int avrcp_browsing_controller_send_get_folder_items_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
175     uint8_t command[100];
176     int pos = 0;
177     // transport header
178     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
179     command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
180     // Profile IDentifier (PID)
181     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
182     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
183     command[pos++] = AVRCP_PDU_ID_GET_FOLDER_ITEMS;
184 
185     uint32_t attribute_count = 0;
186     uint32_t attributes_to_copy = 0;
187 
188     switch (connection->attr_bitmap){
189         case AVRCP_MEDIA_ATTR_NONE:
190             attribute_count = AVRCP_MEDIA_ATTR_NONE; // 0xFFFFFFFF
191             break;
192         case AVRCP_MEDIA_ATTR_ALL:
193             attribute_count = AVRCP_MEDIA_ATTR_ALL;  // 0
194             break;
195         default:
196             attribute_count    = count_set_bits_uint32(connection->attr_bitmap & 0xff);
197             attributes_to_copy = attribute_count;
198             break;
199     }
200     big_endian_store_16(command, pos, 9 + 1 + (attribute_count*4));
201     pos += 2;
202 
203     command[pos++] = connection->scope;
204     big_endian_store_32(command, pos, connection->start_item);
205     pos += 4;
206     big_endian_store_32(command, pos, connection->end_item);
207     pos += 4;
208     command[pos++] = attribute_count;
209 
210     int bit_position = 1;
211     while (attributes_to_copy){
212         if (connection->attr_bitmap & (1 << bit_position)){
213             big_endian_store_32(command, pos, bit_position);
214             pos += 4;
215             attributes_to_copy--;
216         }
217         bit_position++;
218     }
219     return l2cap_send(cid, command, pos);
220 }
221 
222 
223 static int avrcp_browsing_controller_send_get_item_attributes_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
224     uint8_t command[100];
225     int pos = 0;
226     // transport header
227     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
228     command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
229     // Profile IDentifier (PID)
230     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
231     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
232     command[pos++] = AVRCP_PDU_ID_GET_ITEM_ATTRIBUTES;
233 
234     uint32_t attribute_count;
235     uint32_t attributes_to_copy = 0;
236 
237     switch (connection->attr_bitmap){
238         case AVRCP_MEDIA_ATTR_NONE:
239         case AVRCP_MEDIA_ATTR_ALL:
240             attribute_count = 0;
241             break;
242         default:
243             attribute_count = count_set_bits_uint32(connection->attr_bitmap & 0xff);
244             attributes_to_copy = attribute_count;
245             break;
246     }
247 
248     big_endian_store_16(command, pos, 12 + (attribute_count*4));
249     pos += 2;
250 
251     command[pos++] = connection->scope;
252     (void)memcpy(command + pos, connection->folder_uid, 8);
253     pos += 8;
254     big_endian_store_16(command, pos, connection->uid_counter);
255     pos += 2;
256     command[pos++] = attribute_count;
257 
258     int bit_position = 1;
259     while (attributes_to_copy){
260         if (connection->attr_bitmap & (1 << bit_position)){
261             big_endian_store_32(command, pos, bit_position);
262             pos += 4;
263             attributes_to_copy--;
264         }
265         bit_position++;
266     }
267 
268     return l2cap_send(cid, command, pos);
269 }
270 
271 
272 static int avrcp_browsing_controller_send_change_path_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
273     uint8_t command[100];
274     int pos = 0;
275     // transport header
276     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
277     command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
278     // Profile IDentifier (PID)
279     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
280     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
281     command[pos++] = AVRCP_PDU_ID_CHANGE_PATH;
282 
283     big_endian_store_16(command, pos, 11);
284     pos += 2;
285     pos += 2;
286     command[pos++] = connection->direction;
287     (void)memcpy(command + pos, connection->folder_uid, 8);
288     pos += 8;
289     return l2cap_send(cid, command, pos);
290 }
291 
292 static int avrcp_browsing_controller_send_search_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
293     uint8_t command[100];
294     int pos = 0;
295     // transport header
296     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
297     command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
298     // Profile IDentifier (PID)
299     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
300     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
301     command[pos++] = AVRCP_PDU_ID_SEARCH;
302 
303     big_endian_store_16(command, pos, 4 + connection->search_str_len);
304     pos += 2;
305 
306     big_endian_store_16(command, pos, 0x006A);
307     pos += 2;
308     big_endian_store_16(command, pos, connection->search_str_len);
309     pos += 2;
310 
311     (void)memcpy(command + pos, connection->search_str,
312                  connection->search_str_len);
313     pos += connection->search_str_len;
314     return l2cap_send(cid, command, pos);
315 }
316 
317 static int avrcp_browsing_controller_send_set_browsed_player_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
318     uint8_t command[100];
319     int pos = 0;
320     // transport header
321     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
322     command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
323     // Profile IDentifier (PID)
324     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
325     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
326     command[pos++] = AVRCP_PDU_ID_SET_BROWSED_PLAYER;
327 
328     big_endian_store_16(command, pos, 2);
329     pos += 2;
330     big_endian_store_16(command, pos, connection->browsed_player_id);
331     pos += 2;
332     return l2cap_send(cid, command, pos);
333 }
334 
335 static int avrcp_browsing_controller_send_get_total_nr_items_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
336     uint8_t command[7];
337     int pos = 0;
338     // transport header
339     // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
340     command[pos++] = (connection->transaction_label << 4) | (AVRCP_SINGLE_PACKET << 2) | (AVRCP_COMMAND_FRAME << 1) | 0;
341     // Profile IDentifier (PID)
342     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
343     command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
344     command[pos++] = AVRCP_PDU_ID_GET_TOTAL_NUMBER_OF_ITEMS;
345 
346     big_endian_store_16(command, pos, 1);
347     pos += 2;
348     command[pos++] = connection->get_total_nr_items_scope;
349     return l2cap_send(cid, command, pos);
350 }
351 
352 static void avrcp_browsing_controller_handle_can_send_now(avrcp_browsing_connection_t * connection){
353     switch (connection->state){
354         case AVCTP_CONNECTION_OPENED:
355             if (connection->set_browsed_player_id){
356                 connection->state = AVCTP_W2_RECEIVE_RESPONSE;
357                 connection->set_browsed_player_id = 0;
358                 avrcp_browsing_controller_send_set_browsed_player_cmd(connection->l2cap_browsing_cid, connection);
359                 break;
360             }
361 
362             if (connection->get_total_nr_items){
363                 connection->state = AVCTP_W2_RECEIVE_RESPONSE;
364                 connection->get_total_nr_items = 0;
365                 avrcp_browsing_controller_send_get_total_nr_items_cmd(connection->l2cap_browsing_cid, connection);
366                 break;
367             }
368 
369             if (connection->get_folder_items){
370                 connection->state = AVCTP_W2_RECEIVE_RESPONSE;
371                 connection->get_folder_items = 0;
372                 avrcp_browsing_controller_send_get_folder_items_cmd(connection->l2cap_browsing_cid, connection);
373                 break;
374             }
375 
376             if (connection->get_item_attributes){
377                 connection->state = AVCTP_W2_RECEIVE_RESPONSE;
378                 connection->get_item_attributes = 0;
379                 avrcp_browsing_controller_send_get_item_attributes_cmd(connection->l2cap_browsing_cid, connection);
380                 break;
381             }
382 
383             if (connection->change_path){
384                 connection->state = AVCTP_W2_RECEIVE_RESPONSE;
385                 connection->change_path = 0;
386                 avrcp_browsing_controller_send_change_path_cmd(connection->l2cap_browsing_cid, connection);
387                 break;
388             }
389 
390             if (connection->search){
391                 connection->state = AVCTP_W2_RECEIVE_RESPONSE;
392                 connection->search = 0;
393                 avrcp_browsing_controller_send_search_cmd(connection->l2cap_browsing_cid, connection);
394                 break;
395             }
396             break;
397         default:
398             return;
399     }
400 }
401 
402 
403 static void avrcp_browsing_controller_emit_done_with_uid_counter(btstack_packet_handler_t callback, uint16_t browsing_cid, uint16_t uid_counter, uint8_t browsing_status, uint8_t bluetooth_status){
404     btstack_assert(callback != NULL);
405 
406     uint8_t event[9];
407     int pos = 0;
408     event[pos++] = HCI_EVENT_AVRCP_META;
409     event[pos++] = sizeof(event) - 2;
410     event[pos++] = AVRCP_SUBEVENT_BROWSING_DONE;
411     little_endian_store_16(event, pos, browsing_cid);
412     pos += 2;
413     little_endian_store_16(event, pos, uid_counter);
414     pos += 2;
415     event[pos++] = browsing_status;
416     event[pos++] = bluetooth_status;
417     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
418 }
419 
420 static void avrcp_parser_reset(avrcp_browsing_connection_t * connection){
421     connection->parser_attribute_header_pos = 0;
422     connection->parsed_attribute_value_offset = 0;
423     connection->parsed_num_attributes = 0;
424     connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER;
425 }
426 
427 
428 static void avrcp_browsing_parser_process_byte(uint8_t byte, avrcp_browsing_connection_t * connection){
429     uint8_t prepended_header_size = 1;
430     uint16_t attribute_total_value_len;
431 
432     switch(connection->parser_state){
433         case AVRCP_PARSER_GET_ATTRIBUTE_HEADER:
434             connection->parser_attribute_header[connection->parser_attribute_header_pos++] = byte;
435             if (connection->parser_attribute_header_pos < AVRCP_BROWSING_ITEM_HEADER_LEN) break;
436 
437             attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 1);
438             connection->parsed_attribute_value[connection->parsed_attribute_value_offset++] = connection->parser_attribute_header[0];   // prepend with item type
439             connection->parsed_attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTTE_SIZE - prepended_header_size);                 // reduce AVRCP_MAX_ATTRIBUTTE_SIZE for the size ot item type
440             connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_VALUE;
441             break;
442 
443         case AVRCP_PARSER_GET_ATTRIBUTE_VALUE:
444             connection->parsed_attribute_value[connection->parsed_attribute_value_offset++] = byte;
445             if (connection->parsed_attribute_value_offset < (connection->parsed_attribute_value_len + prepended_header_size)){
446                 break;
447             }
448             if (connection->parsed_attribute_value_offset < big_endian_read_16(connection->parser_attribute_header, 1)){
449                 connection->parser_state = AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE;
450                 break;
451             }
452             connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER;
453             (*avrcp_controller_context.browsing_avrcp_callback)(AVRCP_BROWSING_DATA_PACKET, connection->l2cap_browsing_cid, &connection->parsed_attribute_value[0], connection->parsed_attribute_value_offset);
454             connection->parsed_num_attributes++;
455             connection->parsed_attribute_value_offset = 0;
456             connection->parser_attribute_header_pos = 0;
457 
458             if (connection->parsed_num_attributes == connection->num_items){
459                 avrcp_parser_reset(connection);
460                 break;
461             }
462             break;
463 
464         case AVRCP_PARSER_IGNORE_REST_OF_ATTRIBUTE_VALUE:
465             connection->parsed_attribute_value_offset++;
466             if (connection->parsed_attribute_value_offset < (big_endian_read_16(connection->parser_attribute_header, 1) + prepended_header_size)){
467                 break;
468             }
469             connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_HEADER;
470             (*avrcp_controller_context.browsing_avrcp_callback)(AVRCP_BROWSING_DATA_PACKET, connection->l2cap_browsing_cid, &connection->parsed_attribute_value[0], connection->parsed_attribute_value_offset);
471             connection->parsed_num_attributes++;
472             connection->parsed_attribute_value_offset = 0;
473             connection->parser_attribute_header_pos = 0;
474 
475             if (connection->parsed_num_attributes == connection->num_items){
476                 avrcp_parser_reset(connection);
477                 break;
478             }
479             break;
480         default:
481             break;
482     }
483 }
484 
485 static void avrcp_browsing_parse_and_emit_element_attrs(uint8_t * packet, uint16_t num_bytes_to_read, avrcp_browsing_connection_t * connection){
486     int i;
487     for (i=0;i<num_bytes_to_read;i++){
488         avrcp_browsing_parser_process_byte(packet[i], connection);
489     }
490 }
491 
492 static void avrcp_browsing_controller_emit_failed(btstack_packet_handler_t callback, uint16_t browsing_cid, uint8_t browsing_status, uint8_t bluetooth_status){
493     avrcp_browsing_controller_emit_done_with_uid_counter(callback, browsing_cid, 0, browsing_status, bluetooth_status);
494 }
495 
496 
497 static void avrcp_browsing_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
498     avrcp_browsing_connection_t * browsing_connection;
499     uint8_t transport_header;
500     int pos;
501 
502     switch (packet_type) {
503         case L2CAP_DATA_PACKET:
504             browsing_connection = get_avrcp_browsing_connection_for_l2cap_cid_for_role(AVRCP_CONTROLLER, channel);
505             if (!browsing_connection) break;
506             pos = 0;
507             transport_header = packet[pos++];
508             // Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
509             browsing_connection->transaction_label = transport_header >> 4;
510             avrcp_packet_type_t avctp_packet_type = (transport_header & 0x0F) >> 2;
511             switch (avctp_packet_type){
512                 case AVRCP_SINGLE_PACKET:
513                 case AVRCP_START_PACKET:
514                     pos += 2;
515                     browsing_connection->num_packets = 1;
516                     if (avctp_packet_type == AVRCP_START_PACKET){
517                         browsing_connection->num_packets = packet[pos++];
518                     }
519                     if ((pos + 4) > size){
520                         browsing_connection->state = AVCTP_CONNECTION_OPENED;
521                         avrcp_browsing_controller_emit_failed(avrcp_controller_context.browsing_avrcp_callback, channel, AVRCP_BROWSING_ERROR_CODE_INVALID_COMMAND, ERROR_CODE_SUCCESS);
522                         return;
523                     }
524                     browsing_connection->pdu_id = packet[pos++];
525                     pos += 2;
526                     browsing_connection->browsing_status = packet[pos++];
527                     if (browsing_connection->browsing_status != AVRCP_BROWSING_ERROR_CODE_SUCCESS){
528                         browsing_connection->state = AVCTP_CONNECTION_OPENED;
529                         avrcp_browsing_controller_emit_failed(avrcp_controller_context.browsing_avrcp_callback, channel, browsing_connection->browsing_status, ERROR_CODE_SUCCESS);
530                         return;
531                     }
532                     break;
533                 default:
534                     break;
535             }
536 
537             uint32_t i;
538             uint8_t folder_depth;
539 
540             switch(browsing_connection->pdu_id){
541                 case AVRCP_PDU_ID_CHANGE_PATH:
542                     break;
543                 case AVRCP_PDU_ID_SET_ADDRESSED_PLAYER:
544                     break;
545                 case AVRCP_PDU_ID_GET_TOTAL_NUMBER_OF_ITEMS:
546                     break;
547                 case AVRCP_PDU_ID_SET_BROWSED_PLAYER:
548                     browsing_connection->uid_counter =  big_endian_read_16(packet, pos);
549                     pos += 2;
550                     // num_items
551                     pos += 4;
552                     // charset
553                     pos += 2;
554                     folder_depth = packet[pos++];
555 
556                     for (i = 0; i < folder_depth; i++){
557                         uint16_t folder_name_length = big_endian_read_16(packet, pos);
558                         pos += 2;
559                         // reuse packet and add data type as a header
560                         packet[pos-1] = AVRCP_BROWSING_MEDIA_ROOT_FOLDER;
561                         (*avrcp_controller_context.browsing_avrcp_callback)(AVRCP_BROWSING_DATA_PACKET, channel, packet+pos-1, folder_name_length+1);
562                         pos += folder_name_length;
563                     }
564                     break;
565 
566                 case AVRCP_PDU_ID_GET_FOLDER_ITEMS:{
567                     switch (avctp_packet_type){
568                         case AVRCP_SINGLE_PACKET:
569                         case AVRCP_START_PACKET:
570                             avrcp_parser_reset(browsing_connection);
571                             browsing_connection->uid_counter =  big_endian_read_16(packet, pos);
572                             pos += 2;
573                             browsing_connection->num_items = big_endian_read_16(packet, pos); //num_items
574                             pos += 2;
575                             avrcp_browsing_parse_and_emit_element_attrs(packet+pos, size-pos, browsing_connection);
576                             break;
577 
578                         case AVRCP_CONTINUE_PACKET:
579                             avrcp_browsing_parse_and_emit_element_attrs(packet+pos, size-pos, browsing_connection);
580                             break;
581 
582                         case AVRCP_END_PACKET:
583                             avrcp_browsing_parse_and_emit_element_attrs(packet+pos, size-pos, browsing_connection);
584                             avrcp_parser_reset(browsing_connection);
585                             break;
586                         default:
587                             break;
588                     }
589                     break;
590                 }
591                 case AVRCP_PDU_ID_SEARCH:
592                     browsing_connection->uid_counter =  big_endian_read_16(packet, pos);
593                     pos += 2;
594                     break;
595                 case AVRCP_PDU_ID_GET_ITEM_ATTRIBUTES:
596                     packet[pos-1] = AVRCP_BROWSING_MEDIA_ELEMENT_ITEM_ATTRIBUTE;
597                     (*avrcp_controller_context.browsing_avrcp_callback)(AVRCP_BROWSING_DATA_PACKET, channel, packet+pos-1, size - pos + 1);
598                     break;
599                 default:
600                     log_info(" not parsed pdu ID 0x%02x", browsing_connection->pdu_id);
601                     break;
602             }
603 
604             switch (avctp_packet_type){
605                 case AVRCP_SINGLE_PACKET:
606                 case AVRCP_END_PACKET:
607                     browsing_connection->state = AVCTP_CONNECTION_OPENED;
608                     avrcp_browsing_controller_emit_done_with_uid_counter(avrcp_controller_context.browsing_avrcp_callback, channel, browsing_connection->uid_counter, browsing_connection->browsing_status, ERROR_CODE_SUCCESS);
609                     break;
610                 default:
611                     break;
612             }
613             break;
614 
615         case HCI_EVENT_PACKET:
616             switch (hci_event_packet_get_type(packet)){
617                 case L2CAP_EVENT_CAN_SEND_NOW:
618                     browsing_connection = get_avrcp_browsing_connection_for_l2cap_cid_for_role(AVRCP_CONTROLLER,channel);
619                     if (!browsing_connection) break;
620                     avrcp_browsing_controller_handle_can_send_now(browsing_connection);
621                     break;
622                 default:
623                     avrcp_browser_packet_handler(packet_type, channel, packet, size, &avrcp_controller_context);
624                     break;
625             }
626             break;
627 
628         default:
629             break;
630     }
631 }
632 
633 void avrcp_browsing_controller_init(void){
634     avrcp_controller_context.browsing_packet_handler = avrcp_browsing_controller_packet_handler;
635     l2cap_register_service(&avrcp_browsing_controller_packet_handler, PSM_AVCTP_BROWSING, 0xffff, gap_get_security_level());
636 }
637 
638 void avrcp_browsing_controller_register_packet_handler(btstack_packet_handler_t callback){
639     btstack_assert(callback != NULL);
640     avrcp_controller_context.browsing_avrcp_callback = callback;
641 }
642 
643 uint8_t avrcp_browsing_controller_connect(bd_addr_t bd_addr, uint8_t * ertm_buffer, uint32_t size, l2cap_ertm_config_t * ertm_config, uint16_t * avrcp_browsing_cid){
644     return avrcp_browsing_connect(bd_addr, AVRCP_CONTROLLER, avrcp_browsing_controller_packet_handler, ertm_buffer, size, ertm_config, avrcp_browsing_cid);
645 }
646 
647 uint8_t avrcp_browsing_controller_disconnect(uint16_t avrcp_browsing_cid){
648     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
649     if (!avrcp_connection){
650         log_error("avrcp_browsing_controller_disconnect: could not find a connection.");
651         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
652     }
653     if (avrcp_connection->browsing_connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
654 
655     l2cap_disconnect(avrcp_connection->browsing_connection->l2cap_browsing_cid, 0);
656     return ERROR_CODE_SUCCESS;
657 }
658 
659 uint8_t avrcp_browsing_controller_configure_incoming_connection(uint16_t avrcp_browsing_cid, uint8_t * ertm_buffer, uint32_t size, l2cap_ertm_config_t * ertm_config){
660     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
661     if (!avrcp_connection){
662         log_error("avrcp_browsing_controller_decline_incoming_connection: could not find a connection.");
663         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
664     }
665     if (!avrcp_connection->browsing_connection){
666         log_error("avrcp_browsing_controller_decline_incoming_connection: no browsing connection.");
667         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
668     }
669 
670     if (avrcp_connection->browsing_connection->state != AVCTP_CONNECTION_W4_ERTM_CONFIGURATION){
671         log_error("avrcp_browsing_controller_decline_incoming_connection: browsing connection in a wrong state.");
672         return ERROR_CODE_COMMAND_DISALLOWED;
673     }
674 
675     avrcp_connection->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
676     avrcp_connection->browsing_connection->ertm_buffer = ertm_buffer;
677     avrcp_connection->browsing_connection->ertm_buffer_size = size;
678     (void)memcpy(&avrcp_connection->browsing_connection->ertm_config,
679                  ertm_config, sizeof(l2cap_ertm_config_t));
680     l2cap_accept_ertm_connection(avrcp_connection->browsing_connection->l2cap_browsing_cid, &avrcp_connection->browsing_connection->ertm_config, avrcp_connection->browsing_connection->ertm_buffer, avrcp_connection->browsing_connection->ertm_buffer_size);
681     return ERROR_CODE_SUCCESS;
682 }
683 
684 uint8_t avrcp_browsing_controller_decline_incoming_connection(uint16_t avrcp_browsing_cid){
685     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
686     if (!avrcp_connection){
687         log_error("avrcp_browsing_controller_decline_incoming_connection: could not find a connection.");
688         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
689     }
690     if (!avrcp_connection->browsing_connection) return ERROR_CODE_SUCCESS;
691     if (avrcp_connection->browsing_connection->state > AVCTP_CONNECTION_W4_ERTM_CONFIGURATION) return ERROR_CODE_COMMAND_DISALLOWED;
692 
693     l2cap_decline_connection(avrcp_connection->browsing_connection->l2cap_browsing_cid);
694     // free connection
695     btstack_memory_avrcp_browsing_connection_free(avrcp_connection->browsing_connection);
696     avrcp_connection->browsing_connection = NULL;
697     return ERROR_CODE_SUCCESS;
698 }
699 
700 uint8_t avrcp_browsing_controller_get_item_attributes_for_scope(uint16_t avrcp_browsing_cid, uint8_t * uid, uint16_t uid_counter, uint32_t attr_bitmap, avrcp_browsing_scope_t scope){
701     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
702     if (!avrcp_connection){
703         log_error("avrcp_browsing_controller_get_item_attributes: could not find a connection.");
704         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
705     }
706     avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
707     if (connection->state != AVCTP_CONNECTION_OPENED){
708         log_error("avrcp_browsing_controller_get_item_attributes: connection in wrong state %d, expected %d.", connection->state, AVCTP_CONNECTION_OPENED);
709         return ERROR_CODE_COMMAND_DISALLOWED;
710     }
711 
712     connection->get_item_attributes = 1;
713     connection->scope = scope;
714     (void)memcpy(connection->folder_uid, uid, 8);
715     connection->uid_counter = uid_counter;
716     connection->attr_bitmap = attr_bitmap;
717 
718     avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
719     return ERROR_CODE_SUCCESS;
720 }
721 
722 /**
723  * @brief Retrieve a listing of the contents of a folder.
724  * @param scope    0-player list, 1-virtual file system, 2-search, 3-now playing
725  * @param start_item
726  * @param end_item
727  * @param attribute_count
728  * @param attribute_list
729  **/
730 static uint8_t avrcp_browsing_controller_get_folder_items(uint16_t avrcp_browsing_cid, avrcp_browsing_scope_t scope, uint32_t start_item, uint32_t end_item, uint32_t attr_bitmap){
731     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
732     if (!avrcp_connection){
733         log_error("avrcp_browsing_controller_disconnect: could not find a connection.");
734         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
735     }
736     avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
737     if (connection->state != AVCTP_CONNECTION_OPENED) {
738         log_error("avrcp_browsing_controller_get_folder_items: connection in wrong state %d, expected %d.", connection->state, AVCTP_CONNECTION_OPENED);
739         return ERROR_CODE_COMMAND_DISALLOWED;
740     }
741 
742     connection->get_folder_items = 1;
743     connection->scope = scope;
744     connection->start_item = start_item;
745     connection->end_item = end_item;
746     connection->attr_bitmap = attr_bitmap;
747 
748     avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
749     return ERROR_CODE_SUCCESS;
750 }
751 
752 uint8_t avrcp_browsing_controller_get_media_players(uint16_t avrcp_browsing_cid, uint32_t start_item, uint32_t end_item, uint32_t attr_bitmap){
753     return avrcp_browsing_controller_get_folder_items(avrcp_browsing_cid, AVRCP_BROWSING_MEDIA_PLAYER_LIST, start_item, end_item, attr_bitmap);
754 }
755 
756 uint8_t avrcp_browsing_controller_browse_file_system(uint16_t avrcp_browsing_cid, uint32_t start_item, uint32_t end_item, uint32_t attr_bitmap){
757     // return avrcp_browsing_controller_get_folder_items(avrcp_browsing_cid, 1, 0, 0xFFFFFFFF, attr_bitmap);
758     return avrcp_browsing_controller_get_folder_items(avrcp_browsing_cid, AVRCP_BROWSING_MEDIA_PLAYER_VIRTUAL_FILESYSTEM, start_item, end_item, attr_bitmap);
759 }
760 
761 uint8_t avrcp_browsing_controller_browse_media(uint16_t avrcp_browsing_cid, uint32_t start_item, uint32_t end_item, uint32_t attr_bitmap){
762     // return avrcp_browsing_controller_get_folder_items(avrcp_browsing_cid, 2, 0, 0xFFFFFFFF, 0, NULL);
763     return avrcp_browsing_controller_get_folder_items(avrcp_browsing_cid, AVRCP_BROWSING_SEARCH, start_item, end_item, attr_bitmap);
764 }
765 
766 uint8_t avrcp_browsing_controller_browse_now_playing_list(uint16_t avrcp_browsing_cid, uint32_t start_item, uint32_t end_item, uint32_t attr_bitmap){
767     return avrcp_browsing_controller_get_folder_items(avrcp_browsing_cid, AVRCP_BROWSING_NOW_PLAYING, start_item, end_item, attr_bitmap);
768 }
769 
770 
771 uint8_t avrcp_browsing_controller_set_browsed_player(uint16_t avrcp_browsing_cid, uint16_t browsed_player_id){
772     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
773     if (!avrcp_connection){
774         log_error("avrcp_browsing_controller_change_path: could not find a connection.");
775         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
776     }
777 
778     avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
779     if (connection->state != AVCTP_CONNECTION_OPENED){
780         log_error("avrcp_browsing_controller_change_path: connection in wrong state.");
781         return ERROR_CODE_COMMAND_DISALLOWED;
782     }
783 
784     connection->set_browsed_player_id = 1;
785     connection->browsed_player_id = browsed_player_id;
786     avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
787     return ERROR_CODE_SUCCESS;
788 }
789 
790 /**
791  * @brief Retrieve a listing of the contents of a folder.
792  * @param direction     0-folder up, 1-folder down
793  * @param folder_uid    8 bytes long
794  **/
795 uint8_t avrcp_browsing_controller_change_path(uint16_t avrcp_browsing_cid, uint8_t direction, uint8_t * folder_uid){
796     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
797     if (!avrcp_connection){
798         log_error("avrcp_browsing_controller_change_path: could not find a connection.");
799         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
800     }
801 
802     avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
803 
804     if ((connection == NULL) || (connection->state != AVCTP_CONNECTION_OPENED)){
805         log_error("avrcp_browsing_controller_change_path: connection in wrong state.");
806         return ERROR_CODE_COMMAND_DISALLOWED;
807     }
808 
809     if (!connection->browsed_player_id){
810         log_error("avrcp_browsing_controller_change_path: no browsed player set.");
811         return ERROR_CODE_COMMAND_DISALLOWED;
812     }
813     connection->change_path = 1;
814     connection->direction = direction;
815     memset(connection->folder_uid, 0, 8);
816     if (folder_uid){
817         (void)memcpy(connection->folder_uid, folder_uid, 8);
818     }
819 
820     avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
821     return ERROR_CODE_SUCCESS;
822 }
823 
824 uint8_t avrcp_browsing_controller_go_up_one_level(uint16_t avrcp_browsing_cid){
825     return avrcp_browsing_controller_change_path(avrcp_browsing_cid, 0, NULL);
826 }
827 
828 uint8_t avrcp_browsing_controller_go_down_one_level(uint16_t avrcp_browsing_cid, uint8_t * folder_uid){
829     return avrcp_browsing_controller_change_path(avrcp_browsing_cid, 1, folder_uid);
830 }
831 
832 uint8_t avrcp_browsing_controller_search(uint16_t avrcp_browsing_cid, uint16_t search_str_len, char * search_str){
833     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
834     if (!avrcp_connection){
835         log_error("avrcp_browsing_controller_change_path: could not find a connection.");
836         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
837     }
838 
839     avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
840 
841     if ((connection == NULL) || (connection->state != AVCTP_CONNECTION_OPENED)){
842         log_error("avrcp_browsing_controller_change_path: connection in wrong state.");
843         return ERROR_CODE_COMMAND_DISALLOWED;
844     }
845 
846     if (!connection->browsed_player_id){
847         log_error("avrcp_browsing_controller_change_path: no browsed player set.");
848         return ERROR_CODE_COMMAND_DISALLOWED;
849     }
850     if (!search_str || (search_str_len == 0)){
851         return AVRCP_BROWSING_ERROR_CODE_INVALID_COMMAND;
852     }
853 
854     connection->search = 1;
855 
856     connection->search_str_len = btstack_min(search_str_len, sizeof(connection->search_str)-1);
857     memset(connection->search_str, 0, sizeof(connection->search_str));
858     (void)memcpy(connection->search_str, search_str,
859                  connection->search_str_len);
860     avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
861     return ERROR_CODE_SUCCESS;
862 }
863 
864 uint8_t avrcp_browsing_controller_get_total_nr_items_for_scope(uint16_t avrcp_browsing_cid, avrcp_browsing_scope_t scope){
865     avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
866     if (!avrcp_connection){
867         log_error("avrcp_browsing_controller_change_path: could not find a connection.");
868         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
869     }
870 
871     avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
872 
873     if ((connection == NULL) || (connection->state != AVCTP_CONNECTION_OPENED)){
874         log_error("avrcp_browsing_controller_change_path: connection in wrong state.");
875         return ERROR_CODE_COMMAND_DISALLOWED;
876     }
877 
878     if (!connection->browsed_player_id){
879         log_error("avrcp_browsing_controller_change_path: no browsed player set.");
880         return ERROR_CODE_COMMAND_DISALLOWED;
881     }
882     connection->get_total_nr_items = 1;
883     connection->get_total_nr_items_scope = scope;
884     avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
885     return ERROR_CODE_SUCCESS;
886 }
887