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_retry_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 = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid); 71 if (connection_controller == NULL) return; 72 avrcp_connection_t * connection_target = avrcp_get_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_RETRY){ 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_retry_timer_start(avrcp_connection_t * connection){ 89 btstack_run_loop_set_timer_handler(&connection->retry_timer, avrcp_retry_timer_timeout_handler); 90 btstack_run_loop_set_timer_context(&connection->retry_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->retry_timer, timeout); 95 96 btstack_run_loop_add_timer(&connection->retry_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->retry_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->retry_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 = avrcp_get_connection_for_bd_addr_for_role(AVRCP_TARGET, event_addr); 240 connection_controller = avrcp_get_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 = avrcp_get_connection_for_bd_addr_for_role(AVRCP_CONTROLLER, event_addr); 298 connection_target = avrcp_get_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_RETRY; 319 connection_controller->browsing_connection->incoming_declined = false; 320 connection_target->browsing_connection->state = AVCTP_CONNECTION_W2_L2CAP_RETRY; 321 connection_target->browsing_connection->incoming_declined = false; 322 avrcp_retry_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 = avrcp_get_connection_for_browsing_l2cap_cid_for_role(AVRCP_CONTROLLER, local_cid); 339 connection_target = avrcp_get_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 = avrcp_get_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 = avrcp_get_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 = avrcp_get_connection_for_bd_addr_for_role(AVRCP_TARGET, avrcp_browsing_sdp_addr); 391 avrcp_connection_t * avrcp_controller_connection = avrcp_get_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 = avrcp_get_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 = avrcp_get_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 = avrcp_get_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 = avrcp_get_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 = avrcp_get_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 = avrcp_get_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 = avrcp_get_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 = avrcp_get_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