xref: /btstack/src/classic/avrcp_target.c (revision 01dc6e35bf6408272848487a7886e19b6f64a597)
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