/* * Copyright (C) 2016 BlueKitchen GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * 4. Any redistribution, use, or modification is done solely for * personal benefit and not for any commercial purpose or for * monetary gain. * * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Please inquire about commercial licensing options at * contact@bluekitchen-gmbh.com * */ #define __BTSTACK_FILE__ "avrcp_target.c" #include #include #include #include #include "btstack.h" #include "classic/avrcp.h" static avrcp_context_t avrcp_target_context; 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){ avrcp_create_sdp_record(0, service, service_record_handle, browsing, supported_features, service_name, service_provider_name); } static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){ UNUSED(connection); UNUSED(packet); UNUSED(size); } static void avrcp_target_handle_can_send_now(avrcp_connection_t * connection){ switch (connection->state){ default: return; } } static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ avrcp_connection_t * connection; switch (packet_type) { case L2CAP_DATA_PACKET: connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_target_context); if (!connection) break; avrcp_handle_l2cap_data_packet_for_signaling_connection(connection, packet, size); break; case HCI_EVENT_PACKET: switch (hci_event_packet_get_type(packet)){ case L2CAP_EVENT_CAN_SEND_NOW: connection = get_avrcp_connection_for_l2cap_signaling_cid(channel, &avrcp_target_context); if (!connection) break; avrcp_target_handle_can_send_now(connection); break; default: avrcp_packet_handler(packet_type, channel, packet, size, &avrcp_target_context); break; } default: break; } } void avrcp_target_init(void){ avrcp_target_context.role = AVRCP_TARGET; avrcp_target_context.connections = NULL; avrcp_target_context.packet_handler = avrcp_controller_packet_handler; l2cap_register_service(&avrcp_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0); } void avrcp_target_register_packet_handler(btstack_packet_handler_t callback){ if (callback == NULL){ log_error("avrcp_register_packet_handler called with NULL callback"); return; } avrcp_target_context.avrcp_callback = callback; } uint8_t avrcp_target_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){ return avrcp_connect(bd_addr, &avrcp_target_context, avrcp_cid); } uint8_t avrcp_target_disconnect(uint16_t avrcp_cid){ avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_target_context); if (!connection){ log_error("avrcp_get_capabilities: could not find a connection."); return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; } if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; l2cap_disconnect(connection->l2cap_signaling_cid, 0); return ERROR_CODE_SUCCESS; }