xref: /btstack/src/classic/avrcp_browsing.c (revision 2f0acaf70c0e9fb38956385d868c32270b46a6e3)
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 static void avrcp_browsing_handle_sdp_query_complete(avrcp_connection_t * connection, uint8_t status){
388 
389     if (connection->browsing_connection == NULL) {
390         return;
391     }
392     if (connection->browsing_connection->state != AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE){
393         return;
394     }
395 
396     // l2cap available?
397     if (status == ERROR_CODE_SUCCESS){
398         if (connection->browsing_l2cap_psm == 0){
399             status = SDP_SERVICE_NOT_FOUND;
400         }
401     }
402 
403     if (status == ERROR_CODE_SUCCESS) {
404         // ready to connect
405         connection->browsing_connection->state = AVCTP_CONNECTION_W2_L2CAP_CONNECT;
406 
407         // check if both events have been handled
408         avrcp_connection_t *connection_with_opposite_role;
409         switch (connection->role) {
410             case AVRCP_CONTROLLER:
411                 connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET,
412                                                                                             connection->avrcp_cid);
413                 break;
414             case AVRCP_TARGET:
415                 connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER,
416                                                                                             connection->avrcp_cid);
417                 break;
418             default:
419                 btstack_assert(false);
420                 return;
421         }
422         if (connection_with_opposite_role->browsing_connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED) {
423 
424             connection->browsing_connection->state                    = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
425             connection_with_opposite_role->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
426 
427             l2cap_ertm_create_channel(avrcp_browsing_packet_handler,
428                                       connection->remote_addr,
429                                       connection->browsing_l2cap_psm,
430                                       &connection->browsing_connection->ertm_config,
431                                       connection->browsing_connection->ertm_buffer,
432                                       connection->browsing_connection->ertm_buffer_size,
433                                       NULL);
434         }
435     } else {
436         avrcp_browsing_finalize_connection(connection);
437         avrcp_browsing_emit_connection_established(connection->avrcp_browsing_cid, connection->remote_addr, status);
438     }
439 }
440 
441 void avrcp_browsing_init(void){
442     avrcp_register_browsing_sdp_query_complete_handler(&avrcp_browsing_handle_sdp_query_complete);
443     if (avrcp_browsing_l2cap_service_registered) return;
444     uint8_t status = l2cap_register_service(&avrcp_browsing_packet_handler, PSM_AVCTP_BROWSING, 0xffff, LEVEL_2);
445     avrcp_browsing_l2cap_service_registered = status == ERROR_CODE_SUCCESS;
446 }
447 
448 void avrcp_browsing_deinit(void){
449     avrcp_browsing_callback = NULL;
450     avrcp_browsing_controller_packet_handler = NULL;
451     avrcp_browsing_target_packet_handler = NULL;
452 
453     (void) memset(avrcp_browsing_sdp_addr, 0, 6);
454     (void) memset(&avrcp_browsing_handle_sdp_client_query_request, 0, sizeof(avrcp_browsing_handle_sdp_client_query_request));
455     (void) memset(&avrcp_browsing_sdp_query_context, 0, sizeof(avrcp_browsing_sdp_query_context_t));
456 
457     avrcp_browsing_l2cap_service_registered = false;
458 }
459 
460 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){
461     btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
462     btstack_assert(avrcp_browsing_target_packet_handler != NULL);
463 
464     avrcp_connection_t * connection_controller = avrcp_get_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, remote_addr);
465     if (!connection_controller){
466         return ERROR_CODE_COMMAND_DISALLOWED;
467     }
468     avrcp_connection_t * connection_target = avrcp_get_connection_for_bd_addr_for_role(AVRCP_TARGET, remote_addr);
469     if (!connection_target){
470         return ERROR_CODE_COMMAND_DISALLOWED;
471     }
472 
473     if (connection_controller->browsing_connection){
474         return ERROR_CODE_COMMAND_DISALLOWED;
475     }
476     if (connection_target->browsing_connection){
477         return ERROR_CODE_COMMAND_DISALLOWED;
478     }
479 
480     uint16_t cid = avrcp_get_next_cid(AVRCP_CONTROLLER);
481 
482     connection_controller->browsing_connection = avrcp_browsing_create_connection(connection_controller, cid);
483     if (!connection_controller->browsing_connection) return BTSTACK_MEMORY_ALLOC_FAILED;
484 
485     connection_target->browsing_connection = avrcp_browsing_create_connection(connection_target, cid);
486     if (!connection_target->browsing_connection){
487         avrcp_browsing_finalize_connection(connection_controller);
488         return BTSTACK_MEMORY_ALLOC_FAILED;
489     }
490     avrcp_browsing_configure_ertm(connection_controller->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
491     avrcp_browsing_configure_ertm(connection_target->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
492 
493     if (avrcp_browsing_cid != NULL){
494         *avrcp_browsing_cid = cid;
495     }
496 
497     if (connection_controller->browsing_l2cap_psm == 0){
498         memcpy(avrcp_browsing_sdp_addr, remote_addr, 6);
499         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
500         connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
501 
502         avrcp_trigger_sdp_query(connection_controller, connection_target);
503         return ERROR_CODE_SUCCESS;
504     } else {
505         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
506         connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
507 
508         return l2cap_ertm_create_channel(avrcp_browsing_packet_handler, remote_addr, connection_controller->browsing_l2cap_psm,
509                                          &connection_controller->browsing_connection->ertm_config,
510                                          connection_controller->browsing_connection->ertm_buffer,
511                                          connection_controller->browsing_connection->ertm_buffer_size, NULL);
512     }
513 }
514 
515 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){
516     avrcp_connection_t * connection_controller = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
517     if (!connection_controller){
518         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
519     }
520     avrcp_connection_t * connection_target = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
521     if (!connection_target){
522         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
523     }
524 
525     if (!connection_controller->browsing_connection){
526         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
527     }
528     if (!connection_target->browsing_connection){
529         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
530     }
531 
532     if (connection_controller->browsing_connection->state != AVCTP_CONNECTION_W4_ERTM_CONFIGURATION){
533         return ERROR_CODE_COMMAND_DISALLOWED;
534     }
535 
536     avrcp_browsing_configure_ertm(connection_controller->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
537     avrcp_browsing_configure_ertm(connection_target->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
538 
539     connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
540     connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
541 
542     l2cap_ertm_accept_connection(connection_controller->browsing_connection->l2cap_browsing_cid,
543         &connection_controller->browsing_connection->ertm_config,
544         connection_controller->browsing_connection->ertm_buffer,
545         connection_controller->browsing_connection->ertm_buffer_size);
546     return ERROR_CODE_SUCCESS;
547 }
548 
549 
550 uint8_t avrcp_browsing_decline_incoming_connection(uint16_t avrcp_browsing_cid){
551     avrcp_connection_t * connection_controller = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
552     if (!connection_controller){
553         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
554     }
555     avrcp_connection_t * connection_target = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
556     if (!connection_target){
557         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
558     }
559 
560     if (!connection_controller->browsing_connection){
561         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
562     }
563     if (!connection_target->browsing_connection){
564         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
565     }
566 
567     if (connection_controller->browsing_connection->state != AVCTP_CONNECTION_W4_ERTM_CONFIGURATION){
568         return ERROR_CODE_COMMAND_DISALLOWED;
569     }
570 
571     l2cap_decline_connection(connection_controller->browsing_connection->l2cap_browsing_cid);
572 
573     avrcp_browsing_finalize_connection(connection_controller);
574     avrcp_browsing_finalize_connection(connection_target);
575     return ERROR_CODE_SUCCESS;
576 }
577 
578 uint8_t avrcp_browsing_disconnect(uint16_t avrcp_browsing_cid){
579     avrcp_connection_t * connection_controller = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
580     if (!connection_controller){
581         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
582     }
583     avrcp_connection_t * connection_target = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
584     if (!connection_target){
585         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
586     }
587 
588     if (!connection_controller->browsing_connection){
589         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
590     }
591     if (!connection_target->browsing_connection){
592         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
593     }
594 
595     l2cap_disconnect(connection_controller->browsing_connection->l2cap_browsing_cid);
596     return ERROR_CODE_SUCCESS;
597 }
598 
599 void avrcp_browsing_register_controller_packet_handler(btstack_packet_handler_t callback){
600     avrcp_browsing_controller_packet_handler = callback;
601 }
602 
603 void avrcp_browsing_register_target_packet_handler(btstack_packet_handler_t callback){
604     avrcp_browsing_target_packet_handler = callback;
605 }
606 
607 void avrcp_browsing_register_packet_handler(btstack_packet_handler_t callback){
608     btstack_assert(callback != NULL);
609     avrcp_browsing_callback = callback;
610 }
611