blob: 0dbecd5c6425dac49b7b682718b7c3bfd29b4237 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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
Marie Janssen49120dc2015-07-07 16:47:20 -070027#define LOG_TAG "bt_btif_queue"
28
Marie Janssen49a86702015-07-08 11:48:57 -070029#include "btif_profile_queue.h"
30
Zach Johnson24870182014-12-03 15:18:49 -080031#include <assert.h>
Scott James Remnant933926c2015-04-02 15:22:14 -070032#include <string.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080033
The Android Open Source Project5738f832012-12-12 16:00:35 -080034#include "btif_common.h"
Pavlin Radoslavov258c2532015-09-27 20:59:05 -070035#include "bt_common.h"
Zach Johnson24870182014-12-03 15:18:49 -080036#include "osi/include/allocator.h"
Marie Janssendb554582015-06-26 14:53:46 -070037#include "osi/include/list.h"
Sharvil Nanavatieacc69d2014-10-27 16:56:42 -070038#include "stack_manager.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080039
40/*******************************************************************************
41** Local type definitions
42*******************************************************************************/
43
44typedef enum {
45 BTIF_QUEUE_CONNECT_EVT,
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070046 BTIF_QUEUE_ADVANCE_EVT,
The Android Open Source Project5738f832012-12-12 16:00:35 -080047} btif_queue_event_t;
48
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070049typedef struct {
The Android Open Source Project5738f832012-12-12 16:00:35 -080050 bt_bdaddr_t bda;
51 uint16_t uuid;
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070052 bool busy;
53 btif_connect_cb_t connect_cb;
54} connect_node_t;
The Android Open Source Project5738f832012-12-12 16:00:35 -080055
56/*******************************************************************************
57** Static variables
58*******************************************************************************/
59
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070060static list_t *connect_queue;
The Android Open Source Project5738f832012-12-12 16:00:35 -080061
Zach Johnson24870182014-12-03 15:18:49 -080062static const size_t MAX_REASONABLE_REQUESTS = 10;
63
The Android Open Source Project5738f832012-12-12 16:00:35 -080064/*******************************************************************************
65** Queue helper functions
66*******************************************************************************/
67
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070068static void queue_int_add(connect_node_t *p_param) {
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070069 if (!connect_queue) {
Zach Johnson24870182014-12-03 15:18:49 -080070 connect_queue = list_new(osi_free);
71 assert(connect_queue != NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -080072 }
73
Zach Johnson24870182014-12-03 15:18:49 -080074 // Sanity check to make sure we're not leaking connection requests
75 assert(list_length(connect_queue) < MAX_REASONABLE_REQUESTS);
76
Zach Johnson1ece3a32015-01-12 13:56:46 -080077 for (const list_node_t *node = list_begin(connect_queue); node != list_end(connect_queue); node = list_next(node)) {
78 if (((connect_node_t *)list_node(node))->uuid == p_param->uuid) {
Marie Janssendb554582015-06-26 14:53:46 -070079 LOG_INFO(LOG_TAG, "%s dropping duplicate connect request for uuid: %04x", __func__, p_param->uuid);
Zach Johnson1ece3a32015-01-12 13:56:46 -080080 return;
81 }
82 }
83
Jakub Pawlowski713993d2016-04-21 13:16:45 -070084 connect_node_t *p_node = (connect_node_t *)osi_malloc(sizeof(connect_node_t));
Zach Johnson1ece3a32015-01-12 13:56:46 -080085 memcpy(p_node, p_param, sizeof(connect_node_t));
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070086 list_append(connect_queue, p_node);
The Android Open Source Project5738f832012-12-12 16:00:35 -080087}
88
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070089static void queue_int_advance() {
90 if (connect_queue && !list_is_empty(connect_queue))
91 list_remove(connect_queue, list_front(connect_queue));
The Android Open Source Project5738f832012-12-12 16:00:35 -080092}
93
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070094static void queue_int_handle_evt(UINT16 event, char *p_param) {
95 switch(event) {
The Android Open Source Project5738f832012-12-12 16:00:35 -080096 case BTIF_QUEUE_CONNECT_EVT:
Sharvil Nanavatife10dd42014-04-25 23:16:01 -070097 queue_int_add((connect_node_t *)p_param);
The Android Open Source Project5738f832012-12-12 16:00:35 -080098 break;
99
100 case BTIF_QUEUE_ADVANCE_EVT:
101 queue_int_advance();
102 break;
103 }
104
Sharvil Nanavatieacc69d2014-10-27 16:56:42 -0700105 if (stack_manager_get_interface()->get_stack_is_running())
106 btif_queue_connect_next();
The Android Open Source Project5738f832012-12-12 16:00:35 -0800107}
108
109/*******************************************************************************
110**
111** Function btif_queue_connect
112**
113** Description Add a new connection to the queue and trigger the next
114** scheduled connection.
115**
116** Returns BT_STATUS_SUCCESS if successful
117**
118*******************************************************************************/
Sharvil Nanavatife10dd42014-04-25 23:16:01 -0700119bt_status_t btif_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, btif_connect_cb_t connect_cb) {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800120 connect_node_t node;
121 memset(&node, 0, sizeof(connect_node_t));
Sharvil Nanavatife10dd42014-04-25 23:16:01 -0700122 memcpy(&node.bda, bda, sizeof(bt_bdaddr_t));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800123 node.uuid = uuid;
Sharvil Nanavatife10dd42014-04-25 23:16:01 -0700124 node.connect_cb = connect_cb;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800125
126 return btif_transfer_context(queue_int_handle_evt, BTIF_QUEUE_CONNECT_EVT,
Sharvil Nanavatife10dd42014-04-25 23:16:01 -0700127 (char *)&node, sizeof(connect_node_t), NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800128}
129
130/*******************************************************************************
131**
132** Function btif_queue_advance
133**
134** Description Clear the queue's busy status and advance to the next
135** scheduled connection.
136**
137** Returns void
138**
139*******************************************************************************/
Sharvil Nanavatife10dd42014-04-25 23:16:01 -0700140void btif_queue_advance() {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800141 btif_transfer_context(queue_int_handle_evt, BTIF_QUEUE_ADVANCE_EVT,
142 NULL, 0, NULL);
143}
144
Sharvil Nanavatieacc69d2014-10-27 16:56:42 -0700145// This function dispatches the next pending connect request. It is called from
146// stack_manager when the stack comes up.
147bt_status_t btif_queue_connect_next(void) {
148 if (!connect_queue || list_is_empty(connect_queue))
149 return BT_STATUS_FAIL;
150
Jakub Pawlowski713993d2016-04-21 13:16:45 -0700151 connect_node_t *p_head = (connect_node_t *)list_front(connect_queue);
Sharvil Nanavatieacc69d2014-10-27 16:56:42 -0700152
153 // If the queue is currently busy, we return success anyway,
154 // since the connection has been queued...
155 if (p_head->busy)
156 return BT_STATUS_SUCCESS;
157
158 p_head->busy = true;
159 return p_head->connect_cb(&p_head->bda, p_head->uuid);
160}
161
The Android Open Source Project5738f832012-12-12 16:00:35 -0800162/*******************************************************************************
163**
164** Function btif_queue_release
165**
166** Description Free up all the queue nodes and set the queue head to NULL
167**
168** Returns void
169**
170*******************************************************************************/
Sharvil Nanavatife10dd42014-04-25 23:16:01 -0700171void btif_queue_release() {
172 list_free(connect_queue);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800173 connect_queue = NULL;
174}