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_sm.c
     22  *
     23  *  Description:   Generic BTIF state machine API
     24  *
     25  *****************************************************************************/
     26 
     27 #define LOG_TAG "bt_btif"
     28 
     29 #include "btif_sm.h"
     30 
     31 #include "btif_common.h"
     32 #include "bt_common.h"
     33 #include "osi/include/allocator.h"
     34 
     35 /*****************************************************************************
     36 **  Local type definitions
     37 ******************************************************************************/
     38 typedef struct {
     39     btif_sm_state_t         state;
     40     btif_sm_handler_t       *p_handlers;
     41 } btif_sm_cb_t;
     42 
     43 /*****************************************************************************
     44 **  Functions
     45 ******************************************************************************/
     46 
     47 /*****************************************************************************
     48 **
     49 ** Function     btif_sm_init
     50 **
     51 ** Description  Initializes the state machine with the state handlers
     52 **              The caller should ensure that the table and the corresponding
     53 **              states match. The location that 'p_handlers' points to shall
     54 **              be available until the btif_sm_shutdown API is invoked.
     55 **
     56 ** Returns      Returns a pointer to the initialized state machine handle.
     57 **
     58 ******************************************************************************/
     59 
     60 btif_sm_handle_t btif_sm_init(const btif_sm_handler_t *p_handlers, btif_sm_state_t initial_state)
     61 {
     62     if (p_handlers == NULL) {
     63         BTIF_TRACE_ERROR("%s : p_handlers is NULL", __FUNCTION__);
     64         return NULL;
     65     }
     66 
     67     btif_sm_cb_t *p_cb = (btif_sm_cb_t *)osi_malloc(sizeof(btif_sm_cb_t));
     68     p_cb->state = initial_state;
     69     p_cb->p_handlers = (btif_sm_handler_t*)p_handlers;
     70 
     71     /* Send BTIF_SM_ENTER_EVT to the initial state */
     72     p_cb->p_handlers[initial_state](BTIF_SM_ENTER_EVT, NULL);
     73 
     74     return (btif_sm_handle_t)p_cb;
     75 }
     76 
     77 /*****************************************************************************
     78 **
     79 ** Function     btif_sm_shutdown
     80 **
     81 ** Description  Tears down the state machine
     82 **
     83 ** Returns      None
     84 **
     85 ******************************************************************************/
     86 void btif_sm_shutdown(btif_sm_handle_t handle)
     87 {
     88     btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
     89 
     90     if (p_cb == NULL)
     91     {
     92         BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
     93         return;
     94     }
     95     osi_free(p_cb);
     96 }
     97 
     98 /*****************************************************************************
     99 **
    100 ** Function     btif_sm_get_state
    101 **
    102 ** Description  Fetches the current state of the state machine
    103 **
    104 ** Returns      Current state
    105 **
    106 ******************************************************************************/
    107 btif_sm_state_t btif_sm_get_state(btif_sm_handle_t handle)
    108 {
    109     btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
    110 
    111     if (p_cb == NULL)
    112     {
    113         BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
    114         return 0;
    115     }
    116 
    117     return p_cb->state;
    118 }
    119 
    120 /*****************************************************************************
    121 **
    122 ** Function     btif_sm_dispatch
    123 **
    124 ** Description  Dispatches the 'event' along with 'data' to the current state handler
    125 **
    126 ** Returns      BT_STATUS_SUCCESS on success
    127 **              BT_STATUS_UNHANDLED if event was not processed
    128 **              BT_STATUS_FAIL otherwise
    129 **
    130 ******************************************************************************/
    131 bt_status_t btif_sm_dispatch(btif_sm_handle_t handle, btif_sm_event_t event,
    132                                 void *data)
    133 {
    134     bt_status_t status = BT_STATUS_SUCCESS;
    135 
    136     btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
    137 
    138     if (p_cb == NULL)
    139     {
    140         BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
    141         return BT_STATUS_FAIL;
    142     }
    143 
    144     if (p_cb->p_handlers[p_cb->state](event, data) == FALSE)
    145         return BT_STATUS_UNHANDLED;
    146 
    147     return status;
    148 }
    149 
    150 /*****************************************************************************
    151 **
    152 ** Function     btif_sm_change_state
    153 **
    154 ** Description  Make a transition to the new 'state'. The 'BTIF_SM_EXIT_EVT'
    155 **              shall be invoked before exiting the current state. The
    156 **              'BTIF_SM_ENTER_EVT' shall be invoked before entering the new state
    157 **
    158 ** Returns      BT_STATUS_SUCCESS on success
    159 **              BT_STATUS_UNHANDLED if event was not processed
    160 **              BT_STATUS_FAIL otherwise
    161 **
    162 ******************************************************************************/
    163 bt_status_t btif_sm_change_state(btif_sm_handle_t handle, btif_sm_state_t state)
    164 {
    165     bt_status_t status = BT_STATUS_SUCCESS;
    166     btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
    167 
    168     if (p_cb == NULL)
    169     {
    170         BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
    171         return BT_STATUS_FAIL;
    172     }
    173 
    174     /* Send exit event to the current state */
    175     if (p_cb->p_handlers[p_cb->state](BTIF_SM_EXIT_EVT, NULL) == FALSE)
    176         status = BT_STATUS_UNHANDLED;
    177 
    178     /* Change to the new state */
    179     p_cb->state = state;
    180 
    181     /* Send enter event to the new state */
    182     if (p_cb->p_handlers[p_cb->state](BTIF_SM_ENTER_EVT, NULL) == FALSE)
    183         status = BT_STATUS_UNHANDLED;
    184 
    185     return status;
    186 }
    187