avrcp.c (14fd128c5a215243caf91bd0ed0d9dbc2d299412) avrcp.c (36680482ae286412ad6855a67b92b3f5779b5a69)
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

--- 367 unchanged lines hidden (view full) ---

376 connection->transaction_label = 0xFF;
377 connection->max_num_fragments = 0xFF;
378 connection->avrcp_cid = avrcp_get_next_cid();
379 memcpy(connection->remote_addr, remote_addr, 6);
380 btstack_linked_list_add(&context->connections, (btstack_linked_item_t *) connection);
381 return connection;
382}
383
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

--- 367 unchanged lines hidden (view full) ---

376 connection->transaction_label = 0xFF;
377 connection->max_num_fragments = 0xFF;
378 connection->avrcp_cid = avrcp_get_next_cid();
379 memcpy(connection->remote_addr, remote_addr, 6);
380 btstack_linked_list_add(&context->connections, (btstack_linked_item_t *) connection);
381 return connection;
382}
383
384static void avrcp_finalize_connection(avrcp_connection_t * connection){
385 btstack_linked_list_remove(&sdp_query_context->connections, (btstack_linked_item_t*) connection);
384static void avrcp_finalize_connection(avrcp_connection_t * connection, avrcp_context_t * context){
385 btstack_linked_list_remove(&context->connections, (btstack_linked_item_t*) connection);
386 btstack_memory_avrcp_connection_free(connection);
387}
388
389void avrcp_emit_connection_established(btstack_packet_handler_t callback, uint16_t avrcp_cid, bd_addr_t addr, uint8_t status){
390 if (!callback) return;
391 uint8_t event[12];
392 int pos = 0;
393 event[pos++] = HCI_EVENT_AVRCP_META;

--- 156 unchanged lines hidden (view full) ---

550 break;
551
552 case SDP_EVENT_QUERY_COMPLETE:{
553 status = sdp_event_query_complete_get_status(packet);
554
555 if (status != ERROR_CODE_SUCCESS){
556 log_info("AVRCP: SDP query failed with status 0x%02x.", status);
557 avrcp_emit_connection_established(sdp_query_context->avrcp_callback, connection->avrcp_cid, connection->remote_addr, status);
386 btstack_memory_avrcp_connection_free(connection);
387}
388
389void avrcp_emit_connection_established(btstack_packet_handler_t callback, uint16_t avrcp_cid, bd_addr_t addr, uint8_t status){
390 if (!callback) return;
391 uint8_t event[12];
392 int pos = 0;
393 event[pos++] = HCI_EVENT_AVRCP_META;

--- 156 unchanged lines hidden (view full) ---

550 break;
551
552 case SDP_EVENT_QUERY_COMPLETE:{
553 status = sdp_event_query_complete_get_status(packet);
554
555 if (status != ERROR_CODE_SUCCESS){
556 log_info("AVRCP: SDP query failed with status 0x%02x.", status);
557 avrcp_emit_connection_established(sdp_query_context->avrcp_callback, connection->avrcp_cid, connection->remote_addr, status);
558 avrcp_finalize_connection(connection);
558 avrcp_finalize_connection(connection, sdp_query_context);
559 break;
560 }
561
562 if (!sdp_query_context->avrcp_l2cap_psm){
563 connection->state = AVCTP_CONNECTION_IDLE;
564 log_info("AVRCP: no suitable service found");
565 avrcp_emit_connection_established(sdp_query_context->avrcp_callback, connection->avrcp_cid, connection->remote_addr, SDP_SERVICE_NOT_FOUND);
559 break;
560 }
561
562 if (!sdp_query_context->avrcp_l2cap_psm){
563 connection->state = AVCTP_CONNECTION_IDLE;
564 log_info("AVRCP: no suitable service found");
565 avrcp_emit_connection_established(sdp_query_context->avrcp_callback, connection->avrcp_cid, connection->remote_addr, SDP_SERVICE_NOT_FOUND);
566 avrcp_finalize_connection(connection);
566 avrcp_finalize_connection(connection, sdp_query_context);
567 break;
568 }
569 connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
570 l2cap_create_channel(sdp_query_context->packet_handler, connection->remote_addr, sdp_query_context->avrcp_l2cap_psm, l2cap_max_mtu(), NULL);
571 break;
572 }
573 }
574}

--- 47 unchanged lines hidden (view full) ---

622 // TODO: validate if this cannot happen. If not, drop disconnect call
623 log_error("AVRCP connection lookup failed");
624 l2cap_disconnect(local_cid, 0); // reason isn't used
625 break;
626 }
627 if (status != ERROR_CODE_SUCCESS){
628 log_info("L2CAP connection to connection %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
629 avrcp_emit_connection_established(context->avrcp_callback, connection->avrcp_cid, event_addr, status);
567 break;
568 }
569 connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
570 l2cap_create_channel(sdp_query_context->packet_handler, connection->remote_addr, sdp_query_context->avrcp_l2cap_psm, l2cap_max_mtu(), NULL);
571 break;
572 }
573 }
574}

--- 47 unchanged lines hidden (view full) ---

622 // TODO: validate if this cannot happen. If not, drop disconnect call
623 log_error("AVRCP connection lookup failed");
624 l2cap_disconnect(local_cid, 0); // reason isn't used
625 break;
626 }
627 if (status != ERROR_CODE_SUCCESS){
628 log_info("L2CAP connection to connection %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
629 avrcp_emit_connection_established(context->avrcp_callback, connection->avrcp_cid, event_addr, status);
630 avrcp_finalize_connection(connection);
630 avrcp_finalize_connection(connection, context);
631 break;
632 }
633
634 psm = l2cap_event_channel_opened_get_psm(packet);
635 if (psm == PSM_AVCTP){
636 connection->l2cap_signaling_cid = local_cid;
637 connection->l2cap_mtu = l2cap_event_channel_opened_get_remote_mtu(packet);
638 connection->song_length_ms = 0xFFFFFFFF;

--- 7 unchanged lines hidden (view full) ---

646 break;
647
648 case L2CAP_EVENT_CHANNEL_CLOSED:
649 // data: event (8), len(8), channel (16)
650 local_cid = l2cap_event_channel_closed_get_local_cid(packet);
651 connection = get_avrcp_connection_for_l2cap_signaling_cid(local_cid, context);
652 if (connection){
653 avrcp_emit_connection_closed(context->avrcp_callback, connection->avrcp_cid);
631 break;
632 }
633
634 psm = l2cap_event_channel_opened_get_psm(packet);
635 if (psm == PSM_AVCTP){
636 connection->l2cap_signaling_cid = local_cid;
637 connection->l2cap_mtu = l2cap_event_channel_opened_get_remote_mtu(packet);
638 connection->song_length_ms = 0xFFFFFFFF;

--- 7 unchanged lines hidden (view full) ---

646 break;
647
648 case L2CAP_EVENT_CHANNEL_CLOSED:
649 // data: event (8), len(8), channel (16)
650 local_cid = l2cap_event_channel_closed_get_local_cid(packet);
651 connection = get_avrcp_connection_for_l2cap_signaling_cid(local_cid, context);
652 if (connection){
653 avrcp_emit_connection_closed(context->avrcp_callback, connection->avrcp_cid);
654 avrcp_finalize_connection(connection);
654 avrcp_finalize_connection(connection, context);
655 break;
656 }
657 break;
658 default:
659 break;
660 }
661}
662

--- 20 unchanged lines hidden (view full) ---

683 connection->browsing_l2cap_psm = 0;
684 sdp_query_context = context;
685
686 uint8_t status = sdp_client_query_uuid16(&avrcp_handle_sdp_client_query_result, bd_addr, BLUETOOTH_PROTOCOL_AVCTP);
687
688 // free connection struct in case of SDP connection error
689 if (status){
690 log_info("AVRCP: SDP query failed with status 0x%02x.", status);
655 break;
656 }
657 break;
658 default:
659 break;
660 }
661}
662

--- 20 unchanged lines hidden (view full) ---

683 connection->browsing_l2cap_psm = 0;
684 sdp_query_context = context;
685
686 uint8_t status = sdp_client_query_uuid16(&avrcp_handle_sdp_client_query_result, bd_addr, BLUETOOTH_PROTOCOL_AVCTP);
687
688 // free connection struct in case of SDP connection error
689 if (status){
690 log_info("AVRCP: SDP query failed with status 0x%02x.", status);
691 avrcp_finalize_connection(connection);
691 avrcp_finalize_connection(connection, context);
692 }
693
694 return status;
695}
692 }
693
694 return status;
695}