15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2009-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Filename:      btif_sm.c
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Description:   Generic BTIF state machine API
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *****************************************************************************/
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27f8027005333c88a2f097cfd70d15c3d54c7764aeChris Manton#define LOG_TAG "bt_btif"
28dae73b19ce2316b72f44116bc743eec3792de6b4Sharvil Nanavati
2949a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "btif_sm.h"
30dae73b19ce2316b72f44116bc743eec3792de6b4Sharvil Nanavati
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_common.h"
32a11035b5ecbc6cbd9da5bd707683504c47e2744ePavlin Radoslavov#include "bt_common.h"
3349a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "osi/include/allocator.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**  Local type definitions
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct {
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btif_sm_state_t         state;
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btif_sm_handler_t       *p_handlers;
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} btif_sm_cb_t;
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**  Functions
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function     btif_sm_init
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description  Initializes the state machine with the state handlers
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              The caller should ensure that the table and the corresponding
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              states match. The location that 'p_handlers' points to shall
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              be available until the btif_sm_shutdown API is invoked.
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns      Returns a pointer to the initialized state machine handle.
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbtif_sm_handle_t btif_sm_init(const btif_sm_handler_t *p_handlers, btif_sm_state_t initial_state)
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
625fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    if (p_handlers == NULL) {
63e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        BTIF_TRACE_ERROR("%s : p_handlers is NULL", __FUNCTION__);
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
675fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    btif_sm_cb_t *p_cb = (btif_sm_cb_t *)osi_malloc(sizeof(btif_sm_cb_t));
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cb->state = initial_state;
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cb->p_handlers = (btif_sm_handler_t*)p_handlers;
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send BTIF_SM_ENTER_EVT to the initial state */
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cb->p_handlers[initial_state](BTIF_SM_ENTER_EVT, NULL);
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (btif_sm_handle_t)p_cb;
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function     btif_sm_shutdown
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description  Tears down the state machine
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns      None
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btif_sm_shutdown(btif_sm_handle_t handle)
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cb == NULL)
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
92e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
95dae73b19ce2316b72f44116bc743eec3792de6b4Sharvil Nanavati    osi_free(p_cb);
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function     btif_sm_get_state
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description  Fetches the current state of the state machine
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns      Current state
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbtif_sm_state_t btif_sm_get_state(btif_sm_handle_t handle)
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cb == NULL)
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
113e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return 0;
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_cb->state;
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function     btif_sm_dispatch
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description  Dispatches the 'event' along with 'data' to the current state handler
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns      BT_STATUS_SUCCESS on success
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              BT_STATUS_UNHANDLED if event was not processed
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              BT_STATUS_FAIL otherwise
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbt_status_t btif_sm_dispatch(btif_sm_handle_t handle, btif_sm_event_t event,
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                void *data)
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    bt_status_t status = BT_STATUS_SUCCESS;
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cb == NULL)
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
140e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_FAIL;
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cb->p_handlers[p_cb->state](event, data) == FALSE)
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_UNHANDLED;
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*****************************************************************************
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function     btif_sm_change_state
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description  Make a transition to the new 'state'. The 'BTIF_SM_EXIT_EVT'
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              shall be invoked before exiting the current state. The
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              'BTIF_SM_ENTER_EVT' shall be invoked before entering the new state
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns      BT_STATUS_SUCCESS on success
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              BT_STATUS_UNHANDLED if event was not processed
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**              BT_STATUS_FAIL otherwise
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbt_status_t btif_sm_change_state(btif_sm_handle_t handle, btif_sm_state_t state)
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    bt_status_t status = BT_STATUS_SUCCESS;
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cb == NULL)
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
170e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_FAIL;
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send exit event to the current state */
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cb->p_handlers[p_cb->state](BTIF_SM_EXIT_EVT, NULL) == FALSE)
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        status = BT_STATUS_UNHANDLED;
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Change to the new state */
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_cb->state = state;
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send enter event to the new state */
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cb->p_handlers[p_cb->state](BTIF_SM_ENTER_EVT, NULL) == FALSE)
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        status = BT_STATUS_UNHANDLED;
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
187