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 "bt_common.h"
     32 #include "btif_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,
     61                               btif_sm_state_t initial_state) {
     62   if (p_handlers == NULL) {
     63     BTIF_TRACE_ERROR("%s : p_handlers is NULL", __func__);
     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   btif_sm_cb_t* p_cb = (btif_sm_cb_t*)handle;
     88 
     89   if (p_cb == NULL) {
     90     BTIF_TRACE_ERROR("%s : Invalid handle", __func__);
     91     return;
     92   }
     93   osi_free(p_cb);
     94 }
     95 
     96 /*****************************************************************************
     97  *
     98  * Function     btif_sm_get_state
     99  *
    100  * Description  Fetches the current state of the state machine
    101  *
    102  * Returns      Current state
    103  *
    104  *****************************************************************************/
    105 btif_sm_state_t btif_sm_get_state(btif_sm_handle_t handle) {
    106   btif_sm_cb_t* p_cb = (btif_sm_cb_t*)handle;
    107 
    108   if (p_cb == NULL) {
    109     BTIF_TRACE_ERROR("%s : Invalid handle", __func__);
    110     return 0;
    111   }
    112 
    113   return p_cb->state;
    114 }
    115 
    116 /*****************************************************************************
    117  *
    118  * Function     btif_sm_dispatch
    119  *
    120  * Description  Dispatches the 'event' along with 'data' to the current state
    121  *              handler
    122  *
    123  * Returns      BT_STATUS_SUCCESS on success
    124  *              BT_STATUS_UNHANDLED if event was not processed
    125  *              BT_STATUS_FAIL otherwise
    126  *
    127  *****************************************************************************/
    128 bt_status_t btif_sm_dispatch(btif_sm_handle_t handle, btif_sm_event_t event,
    129                              void* data) {
    130   bt_status_t status = BT_STATUS_SUCCESS;
    131 
    132   btif_sm_cb_t* p_cb = (btif_sm_cb_t*)handle;
    133 
    134   if (p_cb == NULL) {
    135     BTIF_TRACE_ERROR("%s : Invalid handle", __func__);
    136     return BT_STATUS_FAIL;
    137   }
    138 
    139   if (p_cb->p_handlers[p_cb->state](event, data) == false)
    140     return BT_STATUS_UNHANDLED;
    141 
    142   return status;
    143 }
    144 
    145 /*****************************************************************************
    146  *
    147  * Function     btif_sm_change_state
    148  *
    149  * Description  Make a transition to the new 'state'. The 'BTIF_SM_EXIT_EVT'
    150  *              shall be invoked before exiting the current state. The
    151  *              'BTIF_SM_ENTER_EVT' shall be invoked before entering the new
    152  *              state
    153  *
    154  * Returns      BT_STATUS_SUCCESS on success
    155  *              BT_STATUS_UNHANDLED if event was not processed
    156  *              BT_STATUS_FAIL otherwise
    157  *
    158  *****************************************************************************/
    159 bt_status_t btif_sm_change_state(btif_sm_handle_t handle,
    160                                  btif_sm_state_t state) {
    161   bt_status_t status = BT_STATUS_SUCCESS;
    162   btif_sm_cb_t* p_cb = (btif_sm_cb_t*)handle;
    163 
    164   if (p_cb == NULL) {
    165     BTIF_TRACE_ERROR("%s : Invalid handle", __func__);
    166     return BT_STATUS_FAIL;
    167   }
    168 
    169   /* Send exit event to the current state */
    170   if (p_cb->p_handlers[p_cb->state](BTIF_SM_EXIT_EVT, NULL) == false)
    171     status = BT_STATUS_UNHANDLED;
    172 
    173   /* Change to the new state */
    174   p_cb->state = state;
    175 
    176   /* Send enter event to the new state */
    177   if (p_cb->p_handlers[p_cb->state](BTIF_SM_ENTER_EVT, NULL) == false)
    178     status = BT_STATUS_UNHANDLED;
    179 
    180   return status;
    181 }
    182