xref: /btstack/src/classic/avrcp_browsing.c (revision 4783d25609a5032739e1b6e67d2236f2d80f2100)
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.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 
53 static void avrcp_browsing_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
54 
55 static btstack_packet_handler_t avrcp_browsing_callback;
56 
57 static bool l2cap_browsing_service_registered = false;
58 static btstack_packet_handler_t avrcp_browsing_controller_packet_handler;
59 static btstack_packet_handler_t avrcp_browsing_target_packet_handler;
60 
61 static bd_addr_t avrcp_browsing_sdp_addr;
62 
63 void avrcp_browsing_request_can_send_now(avrcp_browsing_connection_t * connection, uint16_t l2cap_cid){
64     connection->wait_to_send = true;
65     l2cap_request_can_send_now_event(l2cap_cid);
66 }
67 
68 static void avrcp_reconnect_timer_timeout_handler(btstack_timer_source_t * timer){
69     uint16_t avrcp_cid = (uint16_t)(uintptr_t) btstack_run_loop_get_timer_context(timer);
70     avrcp_connection_t * connection_controller = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
71     if (connection_controller == NULL) return;
72     avrcp_connection_t * connection_target = get_avrcp_connection_for_avrcp_cid_for_role(AVRCP_TARGET, avrcp_cid);
73     if (connection_target == NULL) return;
74 
75     if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)) return;
76 
77     if (connection_controller->browsing_connection->state == AVCTP_CONNECTION_W2_L2CAP_RECONNECT){
78         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
79         connection_target->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
80 
81         l2cap_create_ertm_channel(avrcp_browsing_packet_handler, connection_controller->remote_addr, connection_controller->browsing_l2cap_psm,
82                 &connection_controller->browsing_connection->ertm_config,
83                 connection_controller->browsing_connection->ertm_buffer,
84                 connection_controller->browsing_connection->ertm_buffer_size, NULL);
85     }
86 }
87 
88 static void avrcp_reconnect_timer_start(avrcp_connection_t * connection){
89     btstack_run_loop_set_timer_handler(&connection->reconnect_timer, avrcp_reconnect_timer_timeout_handler);
90     btstack_run_loop_set_timer_context(&connection->reconnect_timer, (void *)(uintptr_t)connection->avrcp_cid);
91 
92     // add some jitter/randomness to reconnect delay
93     uint32_t timeout = 100 + (btstack_run_loop_get_time_ms() & 0x7F);
94     btstack_run_loop_set_timer(&connection->reconnect_timer, timeout);
95 
96     btstack_run_loop_add_timer(&connection->reconnect_timer);
97 }
98 
99 // AVRCP Browsing Service functions
100 static void avrcp_browsing_finalize_connection(avrcp_connection_t * connection){
101     btstack_run_loop_remove_timer(&connection->reconnect_timer);
102     btstack_memory_avrcp_browsing_connection_free(connection->browsing_connection);
103     connection->browsing_connection = NULL;
104 }
105 
106 static void avrcp_browsing_emit_connection_established(uint16_t browsing_cid, bd_addr_t addr, uint8_t status){
107     btstack_assert(avrcp_browsing_callback != NULL);
108 
109     uint8_t event[12];
110     int pos = 0;
111     event[pos++] = HCI_EVENT_AVRCP_META;
112     event[pos++] = sizeof(event) - 2;
113     event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_ESTABLISHED;
114     event[pos++] = status;
115     reverse_bd_addr(addr,&event[pos]);
116     pos += 6;
117     little_endian_store_16(event, pos, browsing_cid);
118     pos += 2;
119     (*avrcp_browsing_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
120 }
121 
122 static void avrcp_browsing_emit_incoming_connection(uint16_t browsing_cid, bd_addr_t addr){
123     btstack_assert(avrcp_browsing_callback != NULL);
124 
125     uint8_t event[11];
126     int pos = 0;
127     event[pos++] = HCI_EVENT_AVRCP_META;
128     event[pos++] = sizeof(event) - 2;
129     event[pos++] = AVRCP_SUBEVENT_INCOMING_BROWSING_CONNECTION;
130     reverse_bd_addr(addr,&event[pos]);
131     pos += 6;
132     little_endian_store_16(event, pos, browsing_cid);
133     pos += 2;
134     (*avrcp_browsing_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
135 }
136 
137 static void avrcp_browsing_emit_connection_closed(uint16_t browsing_cid){
138     btstack_assert(avrcp_browsing_callback != NULL);
139 
140     uint8_t event[5];
141     int pos = 0;
142     event[pos++] = HCI_EVENT_AVRCP_META;
143     event[pos++] = sizeof(event) - 2;
144     event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_RELEASED;
145     little_endian_store_16(event, pos, browsing_cid);
146     pos += 2;
147     (*avrcp_browsing_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
148 }
149 
150 
151 static avrcp_browsing_connection_t * avrcp_browsing_create_connection(avrcp_connection_t * avrcp_connection, uint16_t avrcp_browsing_cid){
152     avrcp_browsing_connection_t * browsing_connection = btstack_memory_avrcp_browsing_connection_get();
153     if (!browsing_connection){
154         log_error("Not enough memory to create browsing connection");
155         return NULL;
156     }
157     browsing_connection->state = AVCTP_CONNECTION_IDLE;
158     browsing_connection->transaction_label = 0xFF;
159 
160     avrcp_connection->avrcp_browsing_cid = avrcp_browsing_cid;
161     avrcp_connection->browsing_connection = browsing_connection;
162 
163     log_info("avrcp_browsing_create_connection, avrcp cid 0x%02x", avrcp_connection->avrcp_browsing_cid);
164     return browsing_connection;
165 }
166 
167 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){
168     browsing_connection->ertm_buffer = ertm_buffer;
169     browsing_connection->ertm_buffer_size = ertm_buffer_size;
170 
171     if (ertm_buffer_size > 0) {
172         (void)memcpy(&browsing_connection->ertm_config, ertm_config,
173                  sizeof(l2cap_ertm_config_t));
174         log_info("avrcp_browsing_configure_ertm");
175     }
176 }
177 
178 static avrcp_browsing_connection_t * avrcp_browsing_handle_incoming_connection(avrcp_connection_t * connection, uint16_t local_cid, uint16_t avrcp_browsing_cid){
179     if (connection->browsing_connection == NULL){
180         avrcp_browsing_create_connection(connection, avrcp_browsing_cid);
181     }
182     if (connection->browsing_connection) {
183         connection->browsing_connection->l2cap_browsing_cid = local_cid;
184         connection->browsing_connection->state = AVCTP_CONNECTION_W4_ERTM_CONFIGURATION;
185         btstack_run_loop_remove_timer(&connection->reconnect_timer);
186     }
187     return connection->browsing_connection;
188 }
189 
190 static void avrcp_browsing_handle_open_connection_for_role(avrcp_connection_t * connection, uint16_t local_cid){
191     connection->browsing_connection->l2cap_browsing_cid = local_cid;
192     connection->browsing_connection->incoming_declined = false;
193     connection->browsing_connection->state = AVCTP_CONNECTION_OPENED;
194     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);
195 }
196 
197 static avrcp_frame_type_t avrcp_get_frame_type(uint8_t header){
198     return (avrcp_frame_type_t)((header & 0x02) >> 1);
199 }
200 
201 static void avrcp_browsing_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
202     UNUSED(channel);
203     UNUSED(size);
204     bd_addr_t event_addr;
205     uint16_t local_cid;
206     uint8_t  status;
207     bool decline_connection;
208     bool outoing_active;
209 
210     avrcp_connection_t * connection_controller;
211     avrcp_connection_t * connection_target;
212 
213     switch (packet_type){
214         case L2CAP_DATA_PACKET:
215             switch (avrcp_get_frame_type(packet[0])){
216                 case AVRCP_RESPONSE_FRAME:
217                     (*avrcp_browsing_controller_packet_handler)(packet_type, channel, packet, size);
218                     break;
219                 case AVRCP_COMMAND_FRAME:
220                 default:    // make compiler happy
221                     (*avrcp_browsing_target_packet_handler)(packet_type, channel, packet, size);
222                     break;
223             }
224             break;
225         case HCI_EVENT_PACKET:
226             btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
227             btstack_assert(avrcp_browsing_target_packet_handler != NULL);
228 
229             switch (hci_event_packet_get_type(packet)) {
230 
231                 case L2CAP_EVENT_INCOMING_CONNECTION:
232                     btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
233                     btstack_assert(avrcp_browsing_target_packet_handler != NULL);
234 
235                     l2cap_event_incoming_connection_get_address(packet, event_addr);
236                     local_cid = l2cap_event_incoming_connection_get_local_cid(packet);
237                     outoing_active = false;
238 
239                     connection_target = get_avrcp_connection_for_bd_addr_for_role(AVRCP_TARGET, event_addr);
240                     connection_controller = get_avrcp_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, event_addr);
241 
242                     if (connection_target == NULL || connection_controller == NULL) {
243                         l2cap_decline_connection(local_cid);
244                         return;
245                     }
246 
247                     if (connection_target->browsing_connection != NULL){
248                         if (connection_target->browsing_connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED){
249                             outoing_active = true;
250                             connection_target->browsing_connection->incoming_declined = true;
251                         }
252                     }
253 
254                     if (connection_controller->browsing_connection != NULL){
255                         if (connection_controller->browsing_connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED) {
256                             outoing_active = true;
257                             connection_controller->browsing_connection->incoming_declined = true;
258                         }
259                     }
260 
261                     decline_connection = outoing_active;
262                     if (decline_connection == false){
263                         uint16_t avrcp_browsing_cid;
264                         if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)){
265                             avrcp_browsing_cid = avrcp_get_next_cid(AVRCP_CONTROLLER);
266                         } else {
267                             avrcp_browsing_cid = connection_controller->avrcp_browsing_cid;
268                         }
269 
270                         // create two connection objects (both)
271                         connection_target->browsing_connection     = avrcp_browsing_handle_incoming_connection(connection_target, local_cid, avrcp_browsing_cid);
272                         connection_controller->browsing_connection = avrcp_browsing_handle_incoming_connection(connection_controller, local_cid, avrcp_browsing_cid);
273 
274                         if ((connection_target->browsing_connection  == NULL) || (connection_controller->browsing_connection == NULL)){
275                             decline_connection = true;
276                             if (connection_target->browsing_connection) {
277                                 avrcp_browsing_finalize_connection(connection_target);
278                             }
279                             if (connection_controller->browsing_connection) {
280                                 avrcp_browsing_finalize_connection(connection_controller);
281                             }
282                         }
283                     }
284                     if (decline_connection){
285                         l2cap_decline_connection(local_cid);
286                     } else {
287                         log_info("AVRCP: L2CAP_EVENT_INCOMING_CONNECTION browsing_avrcp_cid 0x%02x", connection_controller->avrcp_browsing_cid);
288                         avrcp_browsing_emit_incoming_connection(connection_controller->avrcp_browsing_cid, event_addr);
289                     }
290                     break;
291 
292                 case L2CAP_EVENT_CHANNEL_OPENED:
293                     l2cap_event_channel_opened_get_address(packet, event_addr);
294                     status = l2cap_event_channel_opened_get_status(packet);
295                     local_cid = l2cap_event_channel_opened_get_local_cid(packet);
296 
297                     connection_controller = get_avrcp_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, event_addr);
298                     connection_target = get_avrcp_connection_for_bd_addr_for_role(AVRCP_TARGET, event_addr);
299 
300                     // incoming: structs are already created in L2CAP_EVENT_INCOMING_CONNECTION
301                     // outgoing: structs are cteated in avrcp_connect() and avrcp_browsing_connect()
302                     if ((connection_controller == NULL) || (connection_target == NULL)) {
303                         break;
304                     }
305                     if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)) {
306                         break;
307                     }
308 
309                     switch (status){
310                         case ERROR_CODE_SUCCESS:
311                             avrcp_browsing_handle_open_connection_for_role(connection_target, local_cid);
312                             avrcp_browsing_handle_open_connection_for_role(connection_controller, local_cid);
313                             avrcp_browsing_emit_connection_established(connection_controller->avrcp_browsing_cid, event_addr, status);
314                             return;
315                         case L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_RESOURCES:
316                             if (connection_controller->browsing_connection->incoming_declined == true){
317                                 log_info("Incoming browsing connection was declined, and the outgoing failed");
318                                 connection_controller->browsing_connection->state = AVCTP_CONNECTION_W2_L2CAP_RECONNECT;
319                                 connection_controller->browsing_connection->incoming_declined = false;
320                                 connection_target->browsing_connection->state = AVCTP_CONNECTION_W2_L2CAP_RECONNECT;
321                                 connection_target->browsing_connection->incoming_declined = false;
322                                 avrcp_reconnect_timer_start(connection_controller);
323                                 return;
324                             }
325                             break;
326                         default:
327                             break;
328                     }
329                     log_info("L2CAP connection to connection %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
330                     avrcp_browsing_emit_connection_established(connection_controller->avrcp_browsing_cid, event_addr, status);
331                     avrcp_browsing_finalize_connection(connection_controller);
332                     avrcp_browsing_finalize_connection(connection_target);
333                     break;
334 
335                 case L2CAP_EVENT_CHANNEL_CLOSED:
336                     local_cid = l2cap_event_channel_closed_get_local_cid(packet);
337 
338                     connection_controller = get_avrcp_connection_for_browsing_l2cap_cid_for_role(AVRCP_CONTROLLER, local_cid);
339                     connection_target = get_avrcp_connection_for_browsing_l2cap_cid_for_role(AVRCP_TARGET, local_cid);
340                     if ((connection_controller == NULL) || (connection_target == NULL)) {
341                         break;
342                     }
343                     if ((connection_controller->browsing_connection == NULL) || (connection_target->browsing_connection == NULL)) {
344                         break;
345                     }
346                     avrcp_browsing_emit_connection_closed(connection_controller->avrcp_browsing_cid);
347                     avrcp_browsing_finalize_connection(connection_controller);
348                     avrcp_browsing_finalize_connection(connection_target);
349                     break;
350 
351                 case L2CAP_EVENT_CAN_SEND_NOW:
352                     local_cid = l2cap_event_can_send_now_get_local_cid(packet);
353                     connection_target = get_avrcp_connection_for_browsing_l2cap_cid_for_role(AVRCP_TARGET, local_cid);
354                     if ((connection_target != NULL) && (connection_target->browsing_connection != NULL) && connection_target->browsing_connection->wait_to_send) {
355                         connection_target->browsing_connection->wait_to_send = false;
356                         (*avrcp_browsing_target_packet_handler)(HCI_EVENT_PACKET, channel, packet, size);
357                         break;
358                     }
359                     connection_controller = get_avrcp_connection_for_browsing_l2cap_cid_for_role(AVRCP_CONTROLLER, local_cid);
360                     if ((connection_controller != NULL) && (connection_controller->browsing_connection != NULL) && connection_controller->browsing_connection->wait_to_send) {
361                         connection_controller->browsing_connection->wait_to_send = false;
362                         (*avrcp_browsing_controller_packet_handler)(HCI_EVENT_PACKET, channel, packet, size);
363                         break;
364                     }
365                     break;
366 
367                 default:
368                     break;
369             }
370             break;
371         default:
372             break;
373     }
374 
375 }
376 
377 void avrcp_browsing_init(void){
378     if (l2cap_browsing_service_registered) return;
379     int status = l2cap_register_service(&avrcp_browsing_packet_handler, PSM_AVCTP_BROWSING, 0xffff, LEVEL_2);
380 
381     if (status != ERROR_CODE_SUCCESS) return;
382     l2cap_browsing_service_registered = true;
383 }
384 
385 static void avrcp_browsing_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
386     UNUSED(packet_type);
387     UNUSED(channel);
388     UNUSED(size);
389 
390     avrcp_connection_t * avrcp_target_connection = get_avrcp_connection_for_bd_addr_for_role(AVRCP_TARGET, avrcp_browsing_sdp_addr);
391     avrcp_connection_t * avrcp_controller_connection = get_avrcp_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, avrcp_browsing_sdp_addr);
392 
393     uint8_t status;
394     uint16_t browsing_l2cap_psm;
395 
396     switch (hci_event_packet_get_type(packet)){
397         case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
398             avrcp_handle_sdp_client_query_attribute_value(packet);
399             break;
400 
401         case SDP_EVENT_QUERY_COMPLETE:
402             status = sdp_event_query_complete_get_status(packet);
403 
404             if (status != ERROR_CODE_SUCCESS){
405                 avrcp_browsing_emit_connection_established(avrcp_target_connection->avrcp_browsing_cid, avrcp_browsing_sdp_addr, status);
406                 avrcp_browsing_finalize_connection(avrcp_target_connection);
407                 avrcp_browsing_finalize_connection(avrcp_controller_connection);
408                 break;
409             }
410 
411             browsing_l2cap_psm = avrcp_sdp_sdp_query_browsing_l2cap_psm();
412             if (!browsing_l2cap_psm){
413                 avrcp_browsing_emit_connection_established(avrcp_target_connection->avrcp_browsing_cid, avrcp_browsing_sdp_addr, SDP_SERVICE_NOT_FOUND);
414                 avrcp_browsing_finalize_connection(avrcp_target_connection);
415                 avrcp_browsing_finalize_connection(avrcp_controller_connection);
416                 break;
417             }
418 
419             // l2cap_create_channel(&avrcp_packet_handler, sdp_query_context->remote_addr, sdp_query_context->avrcp_l2cap_psm, l2cap_max_mtu(), NULL);
420             l2cap_create_ertm_channel(avrcp_browsing_packet_handler, avrcp_browsing_sdp_addr, browsing_l2cap_psm,
421                                             &avrcp_controller_connection->browsing_connection->ertm_config,
422                                             avrcp_controller_connection->browsing_connection->ertm_buffer,
423                                             avrcp_controller_connection->browsing_connection->ertm_buffer_size, NULL);
424             break;
425 
426         default:
427             break;
428 
429     }
430 }
431 
432 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){
433     btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
434     btstack_assert(avrcp_browsing_target_packet_handler != NULL);
435 
436     avrcp_connection_t * connection_controller = get_avrcp_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, remote_addr);
437     if (!connection_controller){
438         return ERROR_CODE_COMMAND_DISALLOWED;
439     }
440     avrcp_connection_t * connection_target = get_avrcp_connection_for_bd_addr_for_role(AVRCP_TARGET, remote_addr);
441     if (!connection_target){
442         return ERROR_CODE_COMMAND_DISALLOWED;
443     }
444 
445     if (connection_controller->browsing_connection){
446         return ERROR_CODE_COMMAND_DISALLOWED;
447     }
448     if (connection_target->browsing_connection){
449         return ERROR_CODE_COMMAND_DISALLOWED;
450     }
451 
452     uint16_t cid = avrcp_get_next_cid(AVRCP_CONTROLLER);
453 
454     connection_controller->browsing_connection = avrcp_browsing_create_connection(connection_controller, cid);
455     if (!connection_controller->browsing_connection) return BTSTACK_MEMORY_ALLOC_FAILED;
456 
457     connection_target->browsing_connection = avrcp_browsing_create_connection(connection_target, cid);
458     if (!connection_target->browsing_connection){
459         avrcp_browsing_finalize_connection(connection_controller);
460         return BTSTACK_MEMORY_ALLOC_FAILED;
461     }
462     avrcp_browsing_configure_ertm(connection_controller->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
463     avrcp_browsing_configure_ertm(connection_target->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
464 
465     if (avrcp_browsing_cid != NULL){
466         *avrcp_browsing_cid = cid;
467     }
468 
469     if (connection_controller->browsing_l2cap_psm == 0){
470         memcpy(avrcp_browsing_sdp_addr, remote_addr, 6);
471         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
472         connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
473         return avrcp_start_sdp_query(&avrcp_browsing_handle_sdp_client_query_result, remote_addr, cid);
474     } else {
475         connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
476         connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
477 
478         return l2cap_create_ertm_channel(avrcp_browsing_packet_handler, remote_addr, connection_controller->browsing_l2cap_psm,
479                                          &connection_controller->browsing_connection->ertm_config,
480                                          connection_controller->browsing_connection->ertm_buffer,
481                                          connection_controller->browsing_connection->ertm_buffer_size, NULL);
482     }
483 }
484 
485 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){
486     avrcp_connection_t * connection_controller = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
487     if (!connection_controller){
488         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
489     }
490     avrcp_connection_t * connection_target = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
491     if (!connection_target){
492         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
493     }
494 
495     if (!connection_controller->browsing_connection){
496         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
497     }
498     if (!connection_target->browsing_connection){
499         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
500     }
501 
502     if (connection_controller->browsing_connection->state != AVCTP_CONNECTION_W4_ERTM_CONFIGURATION){
503         return ERROR_CODE_COMMAND_DISALLOWED;
504     }
505 
506     avrcp_browsing_configure_ertm(connection_controller->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
507     avrcp_browsing_configure_ertm(connection_target->browsing_connection, ertm_buffer, ertm_buffer_size, ertm_config);
508 
509     connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
510     connection_target->browsing_connection->state     = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
511 
512     l2cap_accept_ertm_connection(connection_controller->browsing_connection->l2cap_browsing_cid,
513         &connection_controller->browsing_connection->ertm_config,
514         connection_controller->browsing_connection->ertm_buffer,
515         connection_controller->browsing_connection->ertm_buffer_size);
516     return ERROR_CODE_SUCCESS;
517 }
518 
519 
520 uint8_t avrcp_browsing_decline_incoming_connection(uint16_t avrcp_browsing_cid){
521     avrcp_connection_t * connection_controller = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
522     if (!connection_controller){
523         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
524     }
525     avrcp_connection_t * connection_target = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
526     if (!connection_target){
527         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
528     }
529 
530     if (!connection_controller->browsing_connection){
531         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
532     }
533     if (!connection_target->browsing_connection){
534         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
535     }
536 
537     if (connection_controller->browsing_connection->state != AVCTP_CONNECTION_W4_ERTM_CONFIGURATION){
538         return ERROR_CODE_COMMAND_DISALLOWED;
539     }
540 
541     l2cap_decline_connection(connection_controller->browsing_connection->l2cap_browsing_cid);
542 
543     avrcp_browsing_finalize_connection(connection_controller);
544     avrcp_browsing_finalize_connection(connection_target);
545     return ERROR_CODE_SUCCESS;
546 }
547 
548 uint8_t avrcp_browsing_disconnect(uint16_t avrcp_browsing_cid){
549     avrcp_connection_t * connection_controller = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_cid);
550     if (!connection_controller){
551         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
552     }
553     avrcp_connection_t * connection_target = get_avrcp_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_cid);
554     if (!connection_target){
555         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
556     }
557 
558     if (!connection_controller->browsing_connection){
559         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
560     }
561     if (!connection_target->browsing_connection){
562         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
563     }
564 
565     l2cap_disconnect(connection_controller->browsing_connection->l2cap_browsing_cid, 0);
566     return ERROR_CODE_SUCCESS;
567 }
568 
569 void avrcp_browsing_register_controller_packet_handler(btstack_packet_handler_t callback){
570     avrcp_browsing_controller_packet_handler = callback;
571 }
572 
573 void avrcp_browsing_register_target_packet_handler(btstack_packet_handler_t callback){
574     avrcp_browsing_target_packet_handler = callback;
575 }
576 
577 void avrcp_browsing_register_packet_handler(btstack_packet_handler_t callback){
578     btstack_assert(callback != NULL);
579     avrcp_browsing_callback = callback;
580 }
581