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_controller.c" 39 40 #include <stdint.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 45 #include "btstack.h" 46 #include "classic/avrcp.h" 47 #include "classic/avrcp_browsing_controller.h" 48 49 void avrcp_browser_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, avrcp_context_t * context); 50 static void avrcp_browsing_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 51 52 static avrcp_connection_t * get_avrcp_connection_for_browsing_cid(uint16_t browsing_cid, avrcp_context_t * context){ 53 btstack_linked_list_iterator_t it; 54 btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &context->connections); 55 while (btstack_linked_list_iterator_has_next(&it)){ 56 avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it); 57 if (connection->avrcp_browsing_cid != browsing_cid) continue; 58 return connection; 59 } 60 return NULL; 61 } 62 63 static avrcp_connection_t * get_avrcp_connection_for_browsing_l2cap_cid(uint16_t browsing_l2cap_cid, avrcp_context_t * context){ 64 btstack_linked_list_iterator_t it; 65 btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &context->connections); 66 while (btstack_linked_list_iterator_has_next(&it)){ 67 avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it); 68 if (connection->l2cap_browsing_cid != browsing_l2cap_cid) continue; 69 return connection; 70 } 71 return NULL; 72 } 73 74 static avrcp_browsing_connection_t * get_avrcp_browsing_connection_for_l2cap_cid(uint16_t l2cap_cid, avrcp_context_t * context){ 75 btstack_linked_list_iterator_t it; 76 btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &context->connections); 77 while (btstack_linked_list_iterator_has_next(&it)){ 78 avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it); 79 if (connection->l2cap_browsing_cid != l2cap_cid) continue; 80 return connection->browsing_connection; 81 } 82 return NULL; 83 } 84 85 static void avrcp_emit_browsing_connection_established(btstack_packet_handler_t callback, uint16_t browsing_cid, bd_addr_t addr, uint8_t status){ 86 if (!callback) return; 87 uint8_t event[12]; 88 int pos = 0; 89 event[pos++] = HCI_EVENT_AVRCP_META; 90 event[pos++] = sizeof(event) - 2; 91 event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_ESTABLISHED; 92 event[pos++] = status; 93 reverse_bd_addr(addr,&event[pos]); 94 pos += 6; 95 little_endian_store_16(event, pos, browsing_cid); 96 pos += 2; 97 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 98 } 99 100 static void avrcp_emit_browsing_connection_closed(btstack_packet_handler_t callback, uint16_t browsing_cid){ 101 if (!callback) return; 102 uint8_t event[5]; 103 int pos = 0; 104 event[pos++] = HCI_EVENT_AVRCP_META; 105 event[pos++] = sizeof(event) - 2; 106 event[pos++] = AVRCP_SUBEVENT_BROWSING_CONNECTION_RELEASED; 107 little_endian_store_16(event, pos, browsing_cid); 108 pos += 2; 109 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 110 } 111 112 static avrcp_browsing_connection_t * avrcp_browsing_create_connection(avrcp_connection_t * avrcp_connection){ 113 avrcp_browsing_connection_t * connection = btstack_memory_avrcp_browsing_connection_get(); 114 memset(connection, 0, sizeof(avrcp_browsing_connection_t)); 115 connection->state = AVCTP_CONNECTION_IDLE; 116 connection->transaction_label = 0xFF; 117 avrcp_connection->avrcp_browsing_cid = avrcp_get_next_cid(); 118 avrcp_connection->browsing_connection = connection; 119 return connection; 120 } 121 122 static uint8_t avrcp_browsing_connect(bd_addr_t remote_addr, avrcp_context_t * context, uint8_t * ertm_buffer, uint32_t size, l2cap_ertm_config_t * ertm_config, uint16_t * browsing_cid){ 123 avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_bd_addr(remote_addr, context); 124 if (!avrcp_connection){ 125 log_error("avrcp: there is no previously established AVRCP controller connection."); 126 return ERROR_CODE_COMMAND_DISALLOWED; 127 } 128 avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection; 129 if (connection){ 130 return ERROR_CODE_SUCCESS; 131 } 132 133 connection = avrcp_browsing_create_connection(avrcp_connection); 134 if (!connection){ 135 printf("avrcp: could not allocate connection struct."); 136 return BTSTACK_MEMORY_ALLOC_FAILED; 137 } 138 139 if (!browsing_cid) return L2CAP_LOCAL_CID_DOES_NOT_EXIST; 140 141 *browsing_cid = avrcp_connection->avrcp_browsing_cid; 142 connection->ertm_buffer = ertm_buffer; 143 connection->ertm_buffer_size = size; 144 avrcp_connection->browsing_connection = connection; 145 146 memcpy(&connection->ertm_config, ertm_config, sizeof(l2cap_ertm_config_t)); 147 148 return l2cap_create_ertm_channel(avrcp_browsing_controller_packet_handler, remote_addr, avrcp_connection->browsing_l2cap_psm, 149 &connection->ertm_config, connection->ertm_buffer, connection->ertm_buffer_size, NULL); 150 151 } 152 153 void avrcp_browser_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, avrcp_context_t * context){ 154 UNUSED(channel); 155 UNUSED(size); 156 bd_addr_t event_addr; 157 uint16_t local_cid; 158 uint8_t status; 159 avrcp_browsing_connection_t * connection = NULL; 160 avrcp_connection_t * avrcp_connection = NULL; 161 162 if (packet_type != HCI_EVENT_PACKET) return; 163 164 switch (hci_event_packet_get_type(packet)) { 165 case HCI_EVENT_DISCONNECTION_COMPLETE: 166 avrcp_emit_browsing_connection_closed(context->avrcp_callback, 0); 167 break; 168 case L2CAP_EVENT_INCOMING_CONNECTION: 169 l2cap_event_incoming_connection_get_address(packet, event_addr); 170 local_cid = l2cap_event_incoming_connection_get_local_cid(packet); 171 avrcp_connection = get_avrcp_connection_for_bd_addr(event_addr, context); 172 if (!avrcp_connection) { 173 log_error("No previously created AVRCP controller connections"); 174 l2cap_decline_connection(local_cid); 175 break; 176 } 177 connection = avrcp_browsing_create_connection(avrcp_connection); 178 avrcp_connection->browsing_connection = connection; 179 avrcp_connection->l2cap_browsing_cid = local_cid; 180 connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED; 181 log_info("L2CAP_EVENT_INCOMING_CONNECTION browsing_cid 0x%02x, l2cap_signaling_cid 0x%02x", avrcp_connection->avrcp_browsing_cid, avrcp_connection->l2cap_browsing_cid); 182 // l2cap_accept_connection(local_cid); 183 printf("L2CAP Accepting incoming connection request in ERTM\n"); 184 l2cap_accept_ertm_connection(local_cid, &connection->ertm_config, connection->ertm_buffer, connection->ertm_buffer_size); 185 break; 186 187 case L2CAP_EVENT_CHANNEL_OPENED: 188 l2cap_event_channel_opened_get_address(packet, event_addr); 189 status = l2cap_event_channel_opened_get_status(packet); 190 local_cid = l2cap_event_channel_opened_get_local_cid(packet); 191 192 avrcp_connection = get_avrcp_connection_for_bd_addr(event_addr, context); 193 if (!avrcp_connection){ 194 log_error("Failed to find AVRCP connection for bd_addr %s", bd_addr_to_str(event_addr)); 195 avrcp_emit_browsing_connection_established(context->avrcp_callback, local_cid, event_addr, L2CAP_LOCAL_CID_DOES_NOT_EXIST); 196 l2cap_disconnect(local_cid, 0); // reason isn't used 197 break; 198 } 199 200 connection = avrcp_connection->browsing_connection; 201 if (!connection){ 202 log_error("Failed to alloc AVRCP connection structure"); 203 avrcp_emit_browsing_connection_established(context->avrcp_callback, local_cid, event_addr, BTSTACK_MEMORY_ALLOC_FAILED); 204 l2cap_disconnect(local_cid, 0); // reason isn't used 205 break; 206 } 207 208 if (status != ERROR_CODE_SUCCESS){ 209 log_info("L2CAP connection to connection %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status); 210 avrcp_emit_browsing_connection_established(context->avrcp_callback, avrcp_connection->avrcp_browsing_cid, event_addr, status); 211 btstack_memory_avrcp_browsing_connection_free(connection); 212 avrcp_connection->browsing_connection = NULL; 213 break; 214 } 215 avrcp_connection->l2cap_browsing_cid = local_cid; 216 217 log_info("L2CAP_EVENT_CHANNEL_OPENED browsing cid 0x%02x, l2cap cid 0x%02x", avrcp_connection->avrcp_browsing_cid, avrcp_connection->l2cap_browsing_cid); 218 connection->state = AVCTP_CONNECTION_OPENED; 219 avrcp_emit_browsing_connection_established(context->avrcp_callback, avrcp_connection->avrcp_browsing_cid, event_addr, ERROR_CODE_SUCCESS); 220 break; 221 222 case L2CAP_EVENT_CHANNEL_CLOSED: 223 // data: event (8), len(8), channel (16) 224 local_cid = l2cap_event_channel_closed_get_local_cid(packet); 225 avrcp_connection = get_avrcp_connection_for_browsing_l2cap_cid(local_cid, context); 226 227 if (avrcp_connection && avrcp_connection->browsing_connection){ 228 avrcp_emit_browsing_connection_closed(context->avrcp_callback, avrcp_connection->avrcp_browsing_cid); 229 // free connection 230 btstack_memory_avrcp_browsing_connection_free(avrcp_connection->browsing_connection); 231 avrcp_connection->browsing_connection = NULL; 232 break; 233 } 234 break; 235 default: 236 break; 237 } 238 } 239 240 // static void avrcp_handle_l2cap_data_packet_for_browsing_connection(avrcp_browsing_connection_t * connection, uint8_t *packet, uint16_t size){ 241 242 // } 243 244 // static void avrcp_browsing_controller_handle_can_send_now(avrcp_browsing_connection_t * connection){ 245 // int i; 246 // switch (connection->state){ 247 // case AVCTP_CONNECTION_OPENED: 248 // return; 249 // default: 250 // return; 251 // } 252 // } 253 254 static void avrcp_browsing_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 255 avrcp_browsing_connection_t * connection; 256 257 switch (packet_type) { 258 case L2CAP_DATA_PACKET: 259 connection = get_avrcp_browsing_connection_for_l2cap_cid(channel, &avrcp_controller_context); 260 if (!connection) break; 261 // avrcp_handle_l2cap_data_packet_for_browsing_connection(connection, packet, size); 262 break; 263 case HCI_EVENT_PACKET: 264 switch (hci_event_packet_get_type(packet)){ 265 case L2CAP_EVENT_CAN_SEND_NOW: 266 connection = get_avrcp_browsing_connection_for_l2cap_cid(channel, &avrcp_controller_context); 267 if (!connection) break; 268 // avrcp_browsing_controller_handle_can_send_now(connection); 269 break; 270 default: 271 avrcp_browser_packet_handler(packet_type, channel, packet, size, &avrcp_controller_context); 272 break; 273 } 274 default: 275 break; 276 } 277 } 278 279 void avrcp_browsing_controller_init(void){ 280 avrcp_controller_context.browsing_packet_handler = avrcp_browsing_controller_packet_handler; 281 l2cap_register_service(&avrcp_browsing_controller_packet_handler, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, LEVEL_0); 282 } 283 284 uint8_t avrcp_browsing_controller_connect(bd_addr_t bd_addr, uint8_t * ertm_buffer, uint32_t size, l2cap_ertm_config_t * ertm_config, uint16_t * avrcp_browsing_cid){ 285 return avrcp_browsing_connect(bd_addr, &avrcp_controller_context, ertm_buffer, size, ertm_config, avrcp_browsing_cid); 286 } 287 288 uint8_t avrcp_browsing_controller_disconnect(uint16_t avrcp_browsing_cid){ 289 avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid(avrcp_browsing_cid, &avrcp_controller_context); 290 if (!avrcp_connection){ 291 log_error("avrcp_browsing_controller_disconnect: could not find a connection."); 292 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 293 } 294 if (avrcp_connection->browsing_connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 295 296 l2cap_disconnect(avrcp_connection->l2cap_browsing_cid, 0); 297 return ERROR_CODE_SUCCESS; 298 } 299