Home | History | Annotate | Download | only in src
      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