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******************************************************************************/ 38typedef 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 60btif_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******************************************************************************/ 86void 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******************************************************************************/ 107btif_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******************************************************************************/ 131bt_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******************************************************************************/ 163bt_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