btif_profile_queue.c revision 5738f83aeb59361a0a2eda2460113f6dc9194271
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 38typedef enum { 39 BTIF_QUEUE_CONNECT_EVT, 40 BTIF_QUEUE_ADVANCE_EVT 41} btif_queue_event_t; 42 43typedef 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 57static connect_node_t *connect_queue; 58 59 60/******************************************************************************* 61** Queue helper functions 62*******************************************************************************/ 63 64static 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 83static 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 93static 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 109static 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*******************************************************************************/ 135bt_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*******************************************************************************/ 158void 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*******************************************************************************/ 174void 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