xref: /btstack/src/classic/avrcp_browsing.c (revision 98f1394d9d4c33f501ec5dcff54d145a92013c5e)
1 /*
2  * Copyright (C) 2016 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "avrcp_browsing.c"
39 
40 #include <stdint.h>
41 #include <string.h>
42 
43 #include "bluetooth_psm.h"
44 #include "bluetooth_sdp.h"
45 #include "btstack_debug.h"
46 #include "btstack_event.h"
47 #include "btstack_memory.h"
48 #include "classic/sdp_client.h"
49 #include "classic/sdp_util.h"
50 #include "classic/avrcp_browsing.h"
51 
52 typedef struct {
53     uint16_t browsing_cid;
54     uint16_t browsing_l2cap_psm;
55     uint16_t browsing_version;
56 } avrcp_browsing_sdp_query_context_t;
57 
58 static void avrcp_browsing_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
59 
60 // higher layer callbacks
61 static btstack_packet_handler_t           avrcp_browsing_callback;
62 static btstack_packet_handler_t avrcp_browsing_controller_packet_handler;
63 static btstack_packet_handler_t avrcp_browsing_target_packet_handler;
64 
65 // sdp query
66 static bd_addr_t avrcp_browsing_sdp_addr;
67 static btstack_context_callback_registration_t avrcp_browsing_handle_sdp_client_query_request;
68 static avrcp_browsing_sdp_query_context_t avrcp_browsing_sdp_query_context;
69 
70 static bool avrcp_browsing_l2cap_service_registered;
71 
72 
73 void avrcp_browsing_request_can_send_now(avrcp_browsing_connection_t * connection, uint16_t l2cap_cid){
74     connection->wait_to_send = true;
75     l2cap_request_can_send_now_event(l2cap_cid);
76 }
77 
78 static void avrcp_retry_timer_timeout_handler(btstack_timer_source_t * timer){
79     uint16_t avrcp_cid = (uint16_t)(uintptr_t) btstack_run_loop_get_timer_context(timer);
80     avrcp_connection_t * connection_controller = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
81     if (connection_controller == NULL) return;
82     avrcp_connection_t * connection_target = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
83     if (connection_target == NULL) return;
84 
85     if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)) return;
86 
87     if (connection_controller->browsing_connection->state == AVCTP_CONNECTION_W2_L2CAP_RETRY){
88         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
89         connection_target->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
90 
91         l2cap_ertm_create_channel(avrcp_browsing_packet_handler, connection_controller->remote_addr, connection_controller->browsing_l2cap_psm,
92                 &connection_controller->browsing_connection->ertm_config,
93                 connection_controller->browsing_connection->ertm_buffer,
94                 connection_controller->browsing_connection->ertm_buffer_size, NULL);
95     }
96 }
97 
98 static void avrcp_retry_timer_start(avrcp_connection_t * connection){
99     btstack_run_loop_set_timer_handler(&connection->retry_timer, avrcp_retry_timer_timeout_handler);
100     btstack_run_loop_set_timer_context(&connection->retry_timer, (void *)(uintptr_t)connection->avrcp_cid);
101 
102     // add some jitter/randomness to reconnect delay
103     uint32_t timeout = 100 + (btstack_run_loop_get_time_ms() & 0x7F);
104     btstack_run_loop_set_timer(&connection->retry_timer, timeout);
105 
106     btstack_run_loop_add_timer(&connection->retry_timer);
107 }
108 
109 // AVRCP Browsing Service functions
110 static void avrcp_browsing_finalize_connection(avrcp_connection_t * connection){
111     btstack_run_loop_remove_timer(&connection->retry_timer);
112     btstack_memory_avrcp_browsing_connection_free(connection->browsing_connection);
113     connection->browsing_connection = NULL;
114 }
115 
116 static void avrcp_browsing_emit_connection_established(uint16_t browsing_cid, bd_addr_t addr, uint8_t status){
117     btstack_assert(avrcp_browsing_callback != NULL);
118 
119     uint8_t event[12];
120     int pos = 0;
121     event[pos++] = HCI_EVENT_AVRCP_META;
122     event[pos++] = sizeof(event) - 2;
123     event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_ESTABLISHED;
124     event[pos++] = status;
125     reverse_bd_addr(addr,&event[pos]);
126     pos += 6;
127     little_endian_store_16(event, pos, browsing_cid);
128     pos += 2;
129     (*avrcp_browsing_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
130 }
131 
132 static void avrcp_browsing_emit_incoming_connection(uint16_t browsing_cid, bd_addr_t addr){
133     btstack_assert(avrcp_browsing_callback != NULL);
134 
135     uint8_t event[11];
136     int pos = 0;
137     event[pos++] = HCI_EVENT_AVRCP_META;
138     event[pos++] = sizeof(event) - 2;
139     event[pos++] = AVRCP_SUBEVENT_INCOMING_BROWSING_CONNECTION;
140     reverse_bd_addr(addr,&event[pos]);
141     pos += 6;
142     little_endian_store_16(event, pos, browsing_cid);
143     pos += 2;
144     (*avrcp_browsing_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
145 }
146 
147 static void avrcp_browsing_emit_connection_closed(uint16_t browsing_cid){
148     btstack_assert(avrcp_browsing_callback != NULL);
149 
150     uint8_t event[5];
151     int pos = 0;
152     event[pos++] = HCI_EVENT_AVRCP_META;
153     event[pos++] = sizeof(event) - 2;
154     event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_RELEASED;
155     little_endian_store_16(event, pos, browsing_cid);
156     pos += 2;
157     (*avrcp_browsing_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
158 }
159 
160 
161 static avrcp_browsing_connection_t * avrcp_browsing_create_connection(avrcp_connection_t * avrcp_connection, uint16_t avrcp_browsing_cid){
162     avrcp_browsing_connection_t * browsing_connection = btstack_memory_avrcp_browsing_connection_get();
163     if (!browsing_connection){
164         log_error("Not enough memory to create browsing connection");
165         return NULL;
166     }
167     browsing_connection->state = AVCTP_CONNECTION_IDLE;
168     browsing_connection->transaction_label = 0xFF;
169 
170     avrcp_connection->avrcp_browsing_cid = avrcp_browsing_cid;
171     avrcp_connection->browsing_connection = browsing_connection;
172 
173     log_info("avrcp_browsing_create_connection, avrcp cid 0x%02x", avrcp_connection->avrcp_browsing_cid);
174     return browsing_connection;
175 }
176 
177 static void avrcp_browsing_configure_ertm(avrcp_browsing_connection_t * browsing_connection, uint8_t * ertm_buffer, uint32_t ertm_buffer_size, l2cap_ertm_config_t * ertm_config){
178     browsing_connection->ertm_buffer = ertm_buffer;
179     browsing_connection->ertm_buffer_size = ertm_buffer_size;
180 
181     if (ertm_buffer_size > 0) {
182         (void)memcpy(&browsing_connection->ertm_config, ertm_config,
183                  sizeof(l2cap_ertm_config_t));
184         log_info("avrcp_browsing_configure_ertm");
185     }
186 }
187 
188 static avrcp_browsing_connection_t * avrcp_browsing_handle_incoming_connection(avrcp_connection_t * connection, uint16_t local_cid, uint16_t avrcp_browsing_cid){
189     if (connection->browsing_connection == NULL){
190         avrcp_browsing_create_connection(connection, avrcp_browsing_cid);
191     }
192     if (connection->browsing_connection) {
193         connection->browsing_connection->l2cap_browsing_cid = local_cid;
194         connection->browsing_connection->state = AVCTP_CONNECTION_W4_ERTM_CONFIGURATION;
195         btstack_run_loop_remove_timer(&connection->retry_timer);
196     }
197     return connection->browsing_connection;
198 }
199 
200 static void avrcp_browsing_handle_open_connection_for_role(avrcp_connection_t * connection, uint16_t local_cid){
201     connection->browsing_connection->l2cap_browsing_cid = local_cid;
202     connection->browsing_connection->incoming_declined = false;
203     connection->browsing_connection->state = AVCTP_CONNECTION_OPENED;
204     log_info("L2CAP_EVENT_CHANNEL_OPENED browsing_avrcp_cid 0x%02x, l2cap_signaling_cid 0x%02x, role %d", connection->avrcp_cid, connection->l2cap_signaling_cid, connection->role);
205 }
206 
207 static avrcp_frame_type_t avrcp_get_frame_type(uint8_t header){
208     return (avrcp_frame_type_t)((header & 0x02) >> 1);
209 }
210 
211 static void avrcp_browsing_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
212     UNUSED(channel);
213     UNUSED(size);
214     bd_addr_t event_addr;
215     uint16_t local_cid;
216     uint8_t  status;
217     bool decline_connection;
218     bool outoing_active;
219 
220     avrcp_connection_t * connection_controller;
221     avrcp_connection_t * connection_target;
222 
223     switch (packet_type){
224         case L2CAP_DATA_PACKET:
225             switch (avrcp_get_frame_type(packet[0])){
226                 case AVRCP_RESPONSE_FRAME:
227                     (*avrcp_browsing_controller_packet_handler)(packet_type, channel, packet, size);
228                     break;
229                 case AVRCP_COMMAND_FRAME:
230                 default:    // make compiler happy
231                     (*avrcp_browsing_target_packet_handler)(packet_type, channel, packet, size);
232                     break;
233             }
234             break;
235         case HCI_EVENT_PACKET:
236             btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
237             btstack_assert(avrcp_browsing_target_packet_handler != NULL);
238 
239             switch (hci_event_packet_get_type(packet)) {
240 
241                 case L2CAP_EVENT_INCOMING_CONNECTION:
242                     btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
243                     btstack_assert(avrcp_browsing_target_packet_handler != NULL);
244 
245                     l2cap_event_incoming_connection_get_address(packet, event_addr);
246                     local_cid = l2cap_event_incoming_connection_get_local_cid(packet);
247                     outoing_active = false;
248 
249                     connection_target = avrcp_get_connection_for_bd_addr_for_role(AVRCP_TARGET, event_addr);
250                     connection_controller = avrcp_get_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, event_addr);
251 
252                     if (connection_target == NULL || connection_controller == NULL) {
253                         l2cap_decline_connection(local_cid);
254                         return;
255                     }
256 
257                     if (connection_target->browsing_connection != NULL){
258                         if (connection_target->browsing_connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED){
259                             outoing_active = true;
260                             connection_target->browsing_connection->incoming_declined = true;
261                         }
262                     }
263 
264                     if (connection_controller->browsing_connection != NULL){
265                         if (connection_controller->browsing_connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED) {
266                             outoing_active = true;
267                             connection_controller->browsing_connection->incoming_declined = true;
268                         }
269                     }
270 
271                     decline_connection = outoing_active;
272                     if (decline_connection == false){
273                         uint16_t avrcp_browsing_cid;
274                         if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)){
275                             avrcp_browsing_cid = avrcp_get_next_cid(AVRCP_CONTROLLER);
276                         } else {
277                             avrcp_browsing_cid = connection_controller->avrcp_browsing_cid;
278                         }
279 
280                         // create two connection objects (both)
281                         connection_target->browsing_connection     = avrcp_browsing_handle_incoming_connection(connection_target, local_cid, avrcp_browsing_cid);
282                         connection_controller->browsing_connection = avrcp_browsing_handle_incoming_connection(connection_controller, local_cid, avrcp_browsing_cid);
283 
284                         if ((connection_target->browsing_connection  == NULL) || (connection_controller->browsing_connection == NULL)){
285                             decline_connection = true;
286                             if (connection_target->browsing_connection) {
287                                 avrcp_browsing_finalize_connection(connection_target);
288                             }
289                             if (connection_controller->browsing_connection) {
290                                 avrcp_browsing_finalize_connection(connection_controller);
291                             }
292                         }
293                     }
294                     if (decline_connection){
295                         l2cap_decline_connection(local_cid);
296                     } else {
297                         log_info("AVRCP: L2CAP_EVENT_INCOMING_CONNECTION browsing_avrcp_cid 0x%02x", connection_controller->avrcp_browsing_cid);
298                         avrcp_browsing_emit_incoming_connection(connection_controller->avrcp_browsing_cid, event_addr);
299                     }
300                     break;
301 
302                 case L2CAP_EVENT_CHANNEL_OPENED:
303                     l2cap_event_channel_opened_get_address(packet, event_addr);
304                     status = l2cap_event_channel_opened_get_status(packet);
305                     local_cid = l2cap_event_channel_opened_get_local_cid(packet);
306 
307                     connection_controller = avrcp_get_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, event_addr);
308                     connection_target = avrcp_get_connection_for_bd_addr_for_role(AVRCP_TARGET, event_addr);
309 
310                     // incoming: structs are already created in L2CAP_EVENT_INCOMING_CONNECTION
311                     // outgoing: structs are cteated in avrcp_connect() and avrcp_browsing_connect()
312                     if ((connection_controller == NULL) || (connection_target == NULL)) {
313                         break;
314                     }
315                     if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)) {
316                         break;
317                     }
318 
319                     switch (status){
320                         case ERROR_CODE_SUCCESS:
321                             avrcp_browsing_handle_open_connection_for_role(connection_target, local_cid);
322                             avrcp_browsing_handle_open_connection_for_role(connection_controller, local_cid);
323                             avrcp_browsing_emit_connection_established(connection_controller->avrcp_browsing_cid, event_addr, status);
324                             return;
325                         case L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_RESOURCES:
326                             if (connection_controller->browsing_connection->incoming_declined == true){
327                                 log_info("Incoming browsing connection was declined, and the outgoing failed");
328                                 connection_controller->browsing_connection->state = AVCTP_CONNECTION_W2_L2CAP_RETRY;
329                                 connection_controller->browsing_connection->incoming_declined = false;
330                                 connection_target->browsing_connection->state = AVCTP_CONNECTION_W2_L2CAP_RETRY;
331                                 connection_target->browsing_connection->incoming_declined = false;
332                                 avrcp_retry_timer_start(connection_controller);
333                                 return;
334                             }
335                             break;
336                         default:
337                             break;
338                     }
339                     log_info("L2CAP connection to connection %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
340                     avrcp_browsing_emit_connection_established(connection_controller->avrcp_browsing_cid, event_addr, status);
341                     avrcp_browsing_finalize_connection(connection_controller);
342                     avrcp_browsing_finalize_connection(connection_target);
343                     break;
344 
345                 case L2CAP_EVENT_CHANNEL_CLOSED:
346                     local_cid = l2cap_event_channel_closed_get_local_cid(packet);
347 
348                     connection_controller = avrcp_get_connection_for_browsing_l2cap_cid_for_role(AVRCP_CONTROLLER, local_cid);
349                     connection_target = avrcp_get_connection_for_browsing_l2cap_cid_for_role(AVRCP_TARGET, local_cid);
350                     if ((connection_controller == NULL) || (connection_target == NULL)) {
351                         break;
352                     }
353                     if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)) {
354                         break;
355                     }
356                     avrcp_browsing_emit_connection_closed(connection_controller->avrcp_browsing_cid);
357                     avrcp_browsing_finalize_connection(connection_controller);
358                     avrcp_browsing_finalize_connection(connection_target);
359                     break;
360 
361                 case L2CAP_EVENT_CAN_SEND_NOW:
362                     local_cid = l2cap_event_can_send_now_get_local_cid(packet);
363                     connection_target = avrcp_get_connection_for_browsing_l2cap_cid_for_role(AVRCP_TARGET, local_cid);
364                     if ((connection_target != NULL) && (connection_target->browsing_connection != NULL) && connection_target->browsing_connection->wait_to_send) {
365                         connection_target->browsing_connection->wait_to_send = false;
366                         (*avrcp_browsing_target_packet_handler)(HCI_EVENT_PACKET, channel, packet, size);
367                         break;
368                     }
369                     connection_controller = avrcp_get_connection_for_browsing_l2cap_cid_for_role(AVRCP_CONTROLLER, local_cid);
370                     if ((connection_controller != NULL) && (connection_controller->browsing_connection != NULL) && connection_controller->browsing_connection->wait_to_send) {
371                         connection_controller->browsing_connection->wait_to_send = false;
372                         (*avrcp_browsing_controller_packet_handler)(HCI_EVENT_PACKET, channel, packet, size);
373                         break;
374                     }
375                     break;
376 
377                 default:
378                     break;
379             }
380             break;
381         default:
382             break;
383     }
384 
385 }
386 
387 void avrcp_browsing_init(void){
388     if (avrcp_browsing_l2cap_service_registered) return;
389     int status = l2cap_register_service(&avrcp_browsing_packet_handler, PSM_AVCTP_BROWSING, 0xffff, LEVEL_2);
390 
391     if (status != ERROR_CODE_SUCCESS) return;
392     avrcp_browsing_l2cap_service_registered = true;
393 }
394 
395 void avrcp_browsing_deinit(void){
396     avrcp_browsing_callback = NULL;
397     avrcp_browsing_controller_packet_handler = NULL;
398     avrcp_browsing_target_packet_handler = NULL;
399 
400     (void) memset(avrcp_browsing_sdp_addr, 0, 6);
401     (void) memset(&avrcp_browsing_handle_sdp_client_query_request, 0, sizeof(avrcp_browsing_handle_sdp_client_query_request));
402     (void) memset(&avrcp_browsing_sdp_query_context, 0, sizeof(avrcp_browsing_sdp_query_context_t));
403 
404     avrcp_browsing_l2cap_service_registered = false;
405 }
406 
407 static void avrcp_browsing_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
408     UNUSED(packet_type);
409     UNUSED(channel);
410     UNUSED(size);
411 
412     avrcp_connection_t * avrcp_target_connection = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_sdp_query_context.browsing_cid);
413     avrcp_connection_t * avrcp_controller_connection = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_sdp_query_context.browsing_cid);
414 
415     if ((avrcp_target_connection == NULL) || (avrcp_target_connection->browsing_connection == NULL)) return;
416     if (avrcp_target_connection->browsing_connection->state != AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE) return;
417 
418     if ((avrcp_controller_connection == NULL) || (avrcp_controller_connection->browsing_connection == NULL)) return;
419     if (avrcp_controller_connection->browsing_connection->state != AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE) return;
420 
421 
422     uint8_t status;
423     uint16_t browsing_l2cap_psm;
424 
425     switch (hci_event_packet_get_type(packet)){
426         case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
427             avrcp_handle_sdp_client_query_attribute_value(packet);
428             break;
429 
430         case SDP_EVENT_QUERY_COMPLETE:
431             status = sdp_event_query_complete_get_status(packet);
432 
433             if (status != ERROR_CODE_SUCCESS){
434                 avrcp_browsing_emit_connection_established(avrcp_target_connection->avrcp_browsing_cid, avrcp_browsing_sdp_addr, status);
435                 avrcp_browsing_finalize_connection(avrcp_target_connection);
436                 avrcp_browsing_finalize_connection(avrcp_controller_connection);
437                 break;
438             }
439 
440             browsing_l2cap_psm = avrcp_sdp_query_browsing_l2cap_psm();
441             if (!browsing_l2cap_psm){
442                 avrcp_browsing_emit_connection_established(avrcp_target_connection->avrcp_browsing_cid, avrcp_browsing_sdp_addr, SDP_SERVICE_NOT_FOUND);
443                 avrcp_browsing_finalize_connection(avrcp_target_connection);
444                 avrcp_browsing_finalize_connection(avrcp_controller_connection);
445                 break;
446             }
447 
448             l2cap_ertm_create_channel(avrcp_browsing_packet_handler, avrcp_browsing_sdp_addr, browsing_l2cap_psm,
449                                             &avrcp_controller_connection->browsing_connection->ertm_config,
450                                             avrcp_controller_connection->browsing_connection->ertm_buffer,
451                                             avrcp_controller_connection->browsing_connection->ertm_buffer_size, NULL);
452             break;
453 
454         default:
455             break;
456     }
457     // register the SDP Query request to check if there is another connection waiting for the query
458     // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
459     (void) sdp_client_register_query_callback(&avrcp_browsing_handle_sdp_client_query_request);
460 }
461 
462 static void avrcp_browsing_handle_start_sdp_client_query(void * context){
463     UNUSED(context);
464     // TODO
465 
466     btstack_linked_list_t connections = avrcp_get_connections();
467     btstack_linked_list_iterator_t it;
468     btstack_linked_list_iterator_init(&it, &connections);
469     while (btstack_linked_list_iterator_has_next(&it)){
470         avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it);
471         if (connection->browsing_connection == NULL) continue;
472         if (connection->browsing_connection->state != AVCTP_CONNECTION_W2_SEND_SDP_QUERY) continue;
473         connection->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
474 
475         // prevent triggering SDP query twice (for each role once)
476         avrcp_connection_t * connection_with_opposite_role;
477         switch (connection->role){
478             case AVRCP_CONTROLLER:
479                 connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, connection->avrcp_cid);
480                 break;
481             case AVRCP_TARGET:
482                 connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, connection->avrcp_cid);
483                 break;
484             default:
485                 btstack_assert(false);
486                 return;
487         }
488         if (connection->browsing_connection != NULL){
489             connection_with_opposite_role->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
490         }
491 
492         avrcp_browsing_sdp_query_context.browsing_l2cap_psm = 0;
493         avrcp_browsing_sdp_query_context.browsing_version = 0;
494         avrcp_browsing_sdp_query_context.browsing_cid = connection->avrcp_browsing_cid;
495 
496         sdp_client_query_uuid16(&avrcp_browsing_handle_sdp_client_query_result, (uint8_t *) connection->remote_addr, BLUETOOTH_PROTOCOL_AVCTP);
497         return;
498     }
499 }
500 
501 
502 uint8_t avrcp_browsing_connect(bd_addr_t remote_addr, uint8_t * ertm_buffer, uint32_t ertm_buffer_size, l2cap_ertm_config_t * ertm_config, uint16_t * avrcp_browsing_cid){
503     btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
504     btstack_assert(avrcp_browsing_target_packet_handler != NULL);
505 
506     avrcp_connection_t * connection_controller = avrcp_get_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, remote_addr);
507     if (!connection_controller){
508         return ERROR_CODE_COMMAND_DISALLOWED;
509     }
510     avrcp_connection_t * connection_target = avrcp_get_connection_for_bd_addr_for_role(AVRCP_TARGET, remote_addr);
511     if (!connection_target){
512         return ERROR_CODE_COMMAND_DISALLOWED;
513     }
514 
515     if (connection_controller->browsing_connection){
516         return ERROR_CODE_COMMAND_DISALLOWED;
517     }
518     if (connection_target->browsing_connection){
519         return ERROR_CODE_COMMAND_DISALLOWED;
520     }
521 
522     uint16_t cid = avrcp_get_next_cid(AVRCP_CONTROLLER);
523 
524     connection_controller->browsing_connection = avrcp_browsing_create_connection(connection_controller, cid);
525     if (!connection_controller->browsing_connection) return BTSTACK_MEMORY_ALLOC_FAILED;
526 
527     connection_target->browsing_connection = avrcp_browsing_create_connection(connection_target, cid);
528     if (!connection_target->browsing_connection){
529         avrcp_browsing_finalize_connection(connection_controller);
530         return BTSTACK_MEMORY_ALLOC_FAILED;
531     }
532     avrcp_browsing_configure_ertm(connection_controller->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
533     avrcp_browsing_configure_ertm(connection_target->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
534 
535     if (avrcp_browsing_cid != NULL){
536         *avrcp_browsing_cid = cid;
537     }
538 
539     if (connection_controller->browsing_l2cap_psm == 0){
540         memcpy(avrcp_browsing_sdp_addr, remote_addr, 6);
541         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W2_SEND_SDP_QUERY;
542         connection_target->browsing_connection->state     = AVCTP_CONNECTION_W2_SEND_SDP_QUERY;
543         avrcp_browsing_handle_sdp_client_query_request.callback = &avrcp_browsing_handle_start_sdp_client_query;
544 
545         // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
546         (void) sdp_client_register_query_callback(&avrcp_browsing_handle_sdp_client_query_request);
547         return ERROR_CODE_SUCCESS;
548     } else {
549         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
550         connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
551 
552         return l2cap_ertm_create_channel(avrcp_browsing_packet_handler, remote_addr, connection_controller->browsing_l2cap_psm,
553                                          &connection_controller->browsing_connection->ertm_config,
554                                          connection_controller->browsing_connection->ertm_buffer,
555                                          connection_controller->browsing_connection->ertm_buffer_size, NULL);
556     }
557 }
558 
559 uint8_t avrcp_browsing_configure_incoming_connection(uint16_t avrcp_browsing_cid, uint8_t * ertm_buffer, uint32_t ertm_buffer_size, l2cap_ertm_config_t * ertm_config){
560     avrcp_connection_t * connection_controller = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
561     if (!connection_controller){
562         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
563     }
564     avrcp_connection_t * connection_target = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
565     if (!connection_target){
566         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
567     }
568 
569     if (!connection_controller->browsing_connection){
570         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
571     }
572     if (!connection_target->browsing_connection){
573         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
574     }
575 
576     if (connection_controller->browsing_connection->state != AVCTP_CONNECTION_W4_ERTM_CONFIGURATION){
577         return ERROR_CODE_COMMAND_DISALLOWED;
578     }
579 
580     avrcp_browsing_configure_ertm(connection_controller->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
581     avrcp_browsing_configure_ertm(connection_target->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
582 
583     connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
584     connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
585 
586     l2cap_ertm_accept_connection(connection_controller->browsing_connection->l2cap_browsing_cid,
587         &connection_controller->browsing_connection->ertm_config,
588         connection_controller->browsing_connection->ertm_buffer,
589         connection_controller->browsing_connection->ertm_buffer_size);
590     return ERROR_CODE_SUCCESS;
591 }
592 
593 
594 uint8_t avrcp_browsing_decline_incoming_connection(uint16_t avrcp_browsing_cid){
595     avrcp_connection_t * connection_controller = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
596     if (!connection_controller){
597         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
598     }
599     avrcp_connection_t * connection_target = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
600     if (!connection_target){
601         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
602     }
603 
604     if (!connection_controller->browsing_connection){
605         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
606     }
607     if (!connection_target->browsing_connection){
608         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
609     }
610 
611     if (connection_controller->browsing_connection->state != AVCTP_CONNECTION_W4_ERTM_CONFIGURATION){
612         return ERROR_CODE_COMMAND_DISALLOWED;
613     }
614 
615     l2cap_decline_connection(connection_controller->browsing_connection->l2cap_browsing_cid);
616 
617     avrcp_browsing_finalize_connection(connection_controller);
618     avrcp_browsing_finalize_connection(connection_target);
619     return ERROR_CODE_SUCCESS;
620 }
621 
622 uint8_t avrcp_browsing_disconnect(uint16_t avrcp_browsing_cid){
623     avrcp_connection_t * connection_controller = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
624     if (!connection_controller){
625         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
626     }
627     avrcp_connection_t * connection_target = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
628     if (!connection_target){
629         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
630     }
631 
632     if (!connection_controller->browsing_connection){
633         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
634     }
635     if (!connection_target->browsing_connection){
636         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
637     }
638 
639     l2cap_disconnect(connection_controller->browsing_connection->l2cap_browsing_cid);
640     return ERROR_CODE_SUCCESS;
641 }
642 
643 void avrcp_browsing_register_controller_packet_handler(btstack_packet_handler_t callback){
644     avrcp_browsing_controller_packet_handler = callback;
645 }
646 
647 void avrcp_browsing_register_target_packet_handler(btstack_packet_handler_t callback){
648     avrcp_browsing_target_packet_handler = callback;
649 }
650 
651 void avrcp_browsing_register_packet_handler(btstack_packet_handler_t callback){
652     btstack_assert(callback != NULL);
653     avrcp_browsing_callback = callback;
654 }
655