1*01dc6e35SMilanka Ringwald /* 2*01dc6e35SMilanka Ringwald * Copyright (C) 2016 BlueKitchen GmbH 3*01dc6e35SMilanka Ringwald * 4*01dc6e35SMilanka Ringwald * Redistribution and use in source and binary forms, with or without 5*01dc6e35SMilanka Ringwald * modification, are permitted provided that the following conditions 6*01dc6e35SMilanka Ringwald * are met: 7*01dc6e35SMilanka Ringwald * 8*01dc6e35SMilanka Ringwald * 1. Redistributions of source code must retain the above copyright 9*01dc6e35SMilanka Ringwald * notice, this list of conditions and the following disclaimer. 10*01dc6e35SMilanka Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*01dc6e35SMilanka Ringwald * notice, this list of conditions and the following disclaimer in the 12*01dc6e35SMilanka Ringwald * documentation and/or other materials provided with the distribution. 13*01dc6e35SMilanka Ringwald * 3. Neither the name of the copyright holders nor the names of 14*01dc6e35SMilanka Ringwald * contributors may be used to endorse or promote products derived 15*01dc6e35SMilanka Ringwald * from this software without specific prior written permission. 16*01dc6e35SMilanka Ringwald * 4. Any redistribution, use, or modification is done solely for 17*01dc6e35SMilanka Ringwald * personal benefit and not for any commercial purpose or for 18*01dc6e35SMilanka Ringwald * monetary gain. 19*01dc6e35SMilanka Ringwald * 20*01dc6e35SMilanka Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*01dc6e35SMilanka Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*01dc6e35SMilanka Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*01dc6e35SMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*01dc6e35SMilanka Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*01dc6e35SMilanka Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*01dc6e35SMilanka Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*01dc6e35SMilanka Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*01dc6e35SMilanka Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*01dc6e35SMilanka Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*01dc6e35SMilanka Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*01dc6e35SMilanka Ringwald * SUCH DAMAGE. 32*01dc6e35SMilanka Ringwald * 33*01dc6e35SMilanka Ringwald * Please inquire about commercial licensing options at 34*01dc6e35SMilanka Ringwald * [email protected] 35*01dc6e35SMilanka Ringwald * 36*01dc6e35SMilanka Ringwald */ 37*01dc6e35SMilanka Ringwald 38*01dc6e35SMilanka Ringwald #define __BTSTACK_FILE__ "avrcp_target.c" 39*01dc6e35SMilanka Ringwald 40*01dc6e35SMilanka Ringwald #include <stdint.h> 41*01dc6e35SMilanka Ringwald #include <stdio.h> 42*01dc6e35SMilanka Ringwald #include <stdlib.h> 43*01dc6e35SMilanka Ringwald #include <string.h> 44*01dc6e35SMilanka Ringwald 45*01dc6e35SMilanka Ringwald #include "btstack.h" 46*01dc6e35SMilanka Ringwald #include "classic/avrcp.h" 47*01dc6e35SMilanka Ringwald 48*01dc6e35SMilanka Ringwald static avrcp_context_t avrcp_target_context; 49*01dc6e35SMilanka Ringwald 50*01dc6e35SMilanka Ringwald void avrcp_target_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint8_t browsing, uint16_t supported_features, const char * service_name, const char * service_provider_name){ 51*01dc6e35SMilanka Ringwald avrcp_create_sdp_record(0, service, service_record_handle, browsing, supported_features, service_name, service_provider_name); 52*01dc6e35SMilanka Ringwald } 53*01dc6e35SMilanka Ringwald 54*01dc6e35SMilanka Ringwald static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ 55*01dc6e35SMilanka Ringwald UNUSED(connection); 56*01dc6e35SMilanka Ringwald UNUSED(packet); 57*01dc6e35SMilanka Ringwald UNUSED(size); 58*01dc6e35SMilanka Ringwald } 59*01dc6e35SMilanka Ringwald 60*01dc6e35SMilanka Ringwald static void avrcp_target_handle_can_send_now(avrcp_connection_t * connection){ 61*01dc6e35SMilanka Ringwald switch (connection->state){ 62*01dc6e35SMilanka Ringwald default: 63*01dc6e35SMilanka Ringwald return; 64*01dc6e35SMilanka Ringwald } 65*01dc6e35SMilanka Ringwald } 66*01dc6e35SMilanka Ringwald 67*01dc6e35SMilanka Ringwald static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 68*01dc6e35SMilanka Ringwald avrcp_connection_t * connection; 69*01dc6e35SMilanka Ringwald switch (packet_type) { 70*01dc6e35SMilanka Ringwald case L2CAP_DATA_PACKET: 71*01dc6e35SMilanka Ringwald connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_target_context); 72*01dc6e35SMilanka Ringwald if (!connection) break; 73*01dc6e35SMilanka Ringwald avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); 74*01dc6e35SMilanka Ringwald break; 75*01dc6e35SMilanka Ringwald case HCI_EVENT_PACKET: 76*01dc6e35SMilanka Ringwald switch (hci_event_packet_get_type(packet)){ 77*01dc6e35SMilanka Ringwald case L2CAP_EVENT_CAN_SEND_NOW: 78*01dc6e35SMilanka Ringwald connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_target_context); 79*01dc6e35SMilanka Ringwald if (!connection) break; 80*01dc6e35SMilanka Ringwald avrcp_target_handle_can_send_now(connection); 81*01dc6e35SMilanka Ringwald break; 82*01dc6e35SMilanka Ringwald default: 83*01dc6e35SMilanka Ringwald avrcp_packet_handler(packet_type, channel, packet, size, &avrcp_target_context); 84*01dc6e35SMilanka Ringwald break; 85*01dc6e35SMilanka Ringwald } 86*01dc6e35SMilanka Ringwald default: 87*01dc6e35SMilanka Ringwald break; 88*01dc6e35SMilanka Ringwald } 89*01dc6e35SMilanka Ringwald } 90*01dc6e35SMilanka Ringwald 91*01dc6e35SMilanka Ringwald void avrcp_target_init(void){ 92*01dc6e35SMilanka Ringwald avrcp_target_context.role = AVRCP_TARGET; 93*01dc6e35SMilanka Ringwald avrcp_target_context.connections = NULL; 94*01dc6e35SMilanka Ringwald avrcp_target_context.packet_handler = avrcp_controller_packet_handler; 95*01dc6e35SMilanka Ringwald l2cap_register_service(&avrcp_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0); 96*01dc6e35SMilanka Ringwald } 97*01dc6e35SMilanka Ringwald 98*01dc6e35SMilanka Ringwald void avrcp_target_register_packet_handler(btstack_packet_handler_t callback){ 99*01dc6e35SMilanka Ringwald if (callback == NULL){ 100*01dc6e35SMilanka Ringwald log_error("avrcp_register_packet_handler called with NULL callback"); 101*01dc6e35SMilanka Ringwald return; 102*01dc6e35SMilanka Ringwald } 103*01dc6e35SMilanka Ringwald avrcp_target_context.avrcp_callback = callback; 104*01dc6e35SMilanka Ringwald } 105*01dc6e35SMilanka Ringwald 106*01dc6e35SMilanka Ringwald uint8_t avrcp_target_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){ 107*01dc6e35SMilanka Ringwald return avrcp_connect(bd_addr, &avrcp_target_context, avrcp_cid); 108*01dc6e35SMilanka Ringwald } 109*01dc6e35SMilanka Ringwald 110*01dc6e35SMilanka Ringwald uint8_t avrcp_target_disconnect(uint16_t avrcp_cid){ 111*01dc6e35SMilanka Ringwald avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context); 112*01dc6e35SMilanka Ringwald if (!connection){ 113*01dc6e35SMilanka Ringwald log_error("avrcp_get_capabilities: could not find a connection."); 114*01dc6e35SMilanka Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 115*01dc6e35SMilanka Ringwald } 116*01dc6e35SMilanka Ringwald if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 117*01dc6e35SMilanka Ringwald l2cap_disconnect(connection->l2cap_signaling_cid, 0); 118*01dc6e35SMilanka Ringwald return ERROR_CODE_SUCCESS; 119*01dc6e35SMilanka Ringwald } 120*01dc6e35SMilanka Ringwald 121