1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /******************************************************************************* 20 * 21 * Filename: btif_profile_queue.c 22 * 23 * Description: Bluetooth remote device connection queuing implementation. 24 * 25 ******************************************************************************/ 26 27 #include <hardware/bluetooth.h> 28 29 #define LOG_TAG "BTIF_QUEUE" 30 #include "btif_common.h" 31 #include "btif_profile_queue.h" 32 #include "gki.h" 33 34 /******************************************************************************* 35 ** Local type definitions 36 *******************************************************************************/ 37 38 typedef enum { 39 BTIF_QUEUE_CONNECT_EVT, 40 BTIF_QUEUE_ADVANCE_EVT 41 } btif_queue_event_t; 42 43 typedef struct connect_node_tag 44 { 45 bt_bdaddr_t bda; 46 uint16_t uuid; 47 uint16_t busy; 48 void *p_cb; 49 struct connect_node_tag *p_next; 50 } __attribute__((packed))connect_node_t; 51 52 53 /******************************************************************************* 54 ** Static variables 55 *******************************************************************************/ 56 57 static connect_node_t *connect_queue; 58 59 60 /******************************************************************************* 61 ** Queue helper functions 62 *******************************************************************************/ 63 64 static void queue_int_add(connect_node_t *p_param) 65 { 66 connect_node_t *p_list = connect_queue; 67 connect_node_t *p_node = GKI_getbuf(sizeof(connect_node_t)); 68 ASSERTC(p_node != NULL, "Failed to allocate new list node", 0); 69 70 memcpy(p_node, p_param, sizeof(connect_node_t)); 71 72 if (connect_queue == NULL) 73 { 74 connect_queue = p_node; 75 return; 76 } 77 78 while (p_list->p_next) 79 p_list = p_list->p_next; 80 p_list->p_next = p_node; 81 } 82 83 static void queue_int_advance() 84 { 85 connect_node_t *p_head = connect_queue; 86 if (connect_queue == NULL) 87 return; 88 89 connect_queue = connect_queue->p_next; 90 GKI_freebuf(p_head); 91 } 92 93 static bt_status_t queue_int_connect_next() 94 { 95 connect_node_t* p_head = connect_queue; 96 97 if (p_head == NULL) 98 return BT_STATUS_FAIL; 99 100 /* If the queue is currently busy, we return success anyway, 101 * since the connection has been queued... */ 102 if (p_head->busy != FALSE) 103 return BT_STATUS_SUCCESS; 104 105 p_head->busy = TRUE; 106 return (*(btif_connect_cb_t*)p_head->p_cb)(&p_head->bda); 107 } 108 109 static void queue_int_handle_evt(UINT16 event, char *p_param) 110 { 111 switch(event) 112 { 113 case BTIF_QUEUE_CONNECT_EVT: 114 queue_int_add((connect_node_t*)p_param); 115 break; 116 117 case BTIF_QUEUE_ADVANCE_EVT: 118 queue_int_advance(); 119 break; 120 } 121 122 queue_int_connect_next(); 123 } 124 125 /******************************************************************************* 126 ** 127 ** Function btif_queue_connect 128 ** 129 ** Description Add a new connection to the queue and trigger the next 130 ** scheduled connection. 131 ** 132 ** Returns BT_STATUS_SUCCESS if successful 133 ** 134 *******************************************************************************/ 135 bt_status_t btif_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, 136 btif_connect_cb_t *connect_cb) 137 { 138 connect_node_t node; 139 memset(&node, 0, sizeof(connect_node_t)); 140 memcpy(&(node.bda), bda, sizeof(bt_bdaddr_t)); 141 node.uuid = uuid; 142 node.p_cb = connect_cb; 143 144 return btif_transfer_context(queue_int_handle_evt, BTIF_QUEUE_CONNECT_EVT, 145 (char*)&node, sizeof(connect_node_t), NULL); 146 } 147 148 /******************************************************************************* 149 ** 150 ** Function btif_queue_advance 151 ** 152 ** Description Clear the queue's busy status and advance to the next 153 ** scheduled connection. 154 ** 155 ** Returns void 156 ** 157 *******************************************************************************/ 158 void btif_queue_advance() 159 { 160 btif_transfer_context(queue_int_handle_evt, BTIF_QUEUE_ADVANCE_EVT, 161 NULL, 0, NULL); 162 } 163 164 165 /******************************************************************************* 166 ** 167 ** Function btif_queue_release 168 ** 169 ** Description Free up all the queue nodes and set the queue head to NULL 170 ** 171 ** Returns void 172 ** 173 *******************************************************************************/ 174 void btif_queue_release() 175 { 176 connect_node_t *current = connect_queue; 177 178 while (current != NULL) 179 { 180 connect_node_t *next = current->p_next; 181 GKI_freebuf(current); 182 current = next; 183 } 184 185 connect_queue = NULL; 186 } 187 188