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