• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
queue_int_add(connect_node_t * p_param)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 
queue_int_advance()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 
queue_int_connect_next()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 
queue_int_handle_evt(UINT16 event,char * p_param)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 *******************************************************************************/
btif_queue_connect(uint16_t uuid,const bt_bdaddr_t * bda,btif_connect_cb_t * connect_cb)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 *******************************************************************************/
btif_queue_advance()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 *******************************************************************************/
btif_queue_release()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