/****************************************************************************** | |
* | |
* Copyright (C) 2009-2012 Broadcom Corporation | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may owfain a copy of the License at: | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* | |
******************************************************************************/ | |
/***************************************************************************** | |
* | |
* Filename: wlan_sm.c | |
* | |
* Description: Generic wlan state machine API | |
* | |
*****************************************************************************/ | |
#include "wlan_sm.h" | |
#include "wifi_util.h" | |
/***************************************************************************** | |
** Constants & Macros | |
******************************************************************************/ | |
/***************************************************************************** | |
** Local type definitions | |
******************************************************************************/ | |
typedef struct { | |
wlan_sm_state_t state; | |
wlan_sm_handler_t *p_handlers; | |
} wlan_sm_cb_t; | |
/***************************************************************************** | |
** Static variables | |
******************************************************************************/ | |
/***************************************************************************** | |
** Static functions | |
******************************************************************************/ | |
/***************************************************************************** | |
** Externs | |
******************************************************************************/ | |
/***************************************************************************** | |
** Functions | |
******************************************************************************/ | |
/***************************************************************************** | |
** | |
** Function wlan_sm_init | |
** | |
** Description Initializes the state machine with the state handlers | |
** The caller should ensure that the table and the corresponding | |
** states match. The location that 'p_handlers' points to shall | |
** be available until the wlan_sm_shutdown API is invoked. | |
** | |
** Returns Returns a pointer to the initialized state machine handle. | |
** | |
******************************************************************************/ | |
wlan_sm_handle_t wlan_sm_init(const wlan_sm_handler_t *p_handlers, wlan_sm_state_t initial_state) | |
{ | |
wlan_sm_cb_t *p_cb = NULL; | |
if (p_handlers == NULL) | |
{ | |
wf_log("p_handlers is NULL"); | |
return NULL; | |
} | |
p_cb = (wlan_sm_cb_t*) malloc(sizeof(wlan_sm_cb_t)); | |
if (p_cb == NULL)//wlocwork | |
{ | |
wf_log("p_cb is NULL"); | |
return NULL; | |
} | |
p_cb->state = initial_state; | |
p_cb->p_handlers = (wlan_sm_handler_t*)p_handlers; | |
/* Send wlan_SM_ENTER_EVT to the initial state */ | |
p_cb->p_handlers[initial_state](WLAN_SM_ENTER_EVT, NULL); | |
return (wlan_sm_handle_t)p_cb; | |
} | |
/***************************************************************************** | |
** | |
** Function wlan_sm_shutdown | |
** | |
** Description Tears down the state machine | |
** | |
** Returns None | |
** | |
******************************************************************************/ | |
void wlan_sm_shutdown(wlan_sm_handle_t handle) | |
{ | |
wlan_sm_cb_t *p_cb = (wlan_sm_cb_t*)handle; | |
if (p_cb == NULL) | |
{ | |
wf_log("Invalid handle"); | |
return; | |
} | |
free((void*)p_cb); | |
} | |
/***************************************************************************** | |
** | |
** Function wlan_sm_get_state | |
** | |
** Description Fetches the current state of the state machine | |
** | |
** Returns Current state | |
** | |
******************************************************************************/ | |
wlan_sm_state_t wlan_sm_get_state(wlan_sm_handle_t handle) | |
{ | |
wlan_sm_cb_t *p_cb = (wlan_sm_cb_t*)handle; | |
if (p_cb == NULL) | |
{ | |
wf_log("Invalid handle"); | |
return 0; | |
} | |
return p_cb->state; | |
} | |
/***************************************************************************** | |
** | |
** Function wlan_sm_dispatch | |
** | |
** Description Dispatches the 'event' along with 'data' to the current state handler | |
** | |
** Returns WF_STATUS_SUCCESS on success | |
** WF_STATUS_UNHANDLED if event was not processed | |
** WF_STATUS_FAIL otherwise | |
** | |
******************************************************************************/ | |
wf_status_t wlan_sm_dispatch(wlan_sm_handle_t handle, wlan_sm_event_t event, | |
void *data) | |
{ | |
wf_status_t status = WF_STATUS_SUCCESS; | |
wlan_sm_cb_t *p_cb = (wlan_sm_cb_t*)handle; | |
if (p_cb == NULL) | |
{ | |
wf_log("Invalid handle"); | |
return WF_STATUS_FAIL; | |
} | |
if (p_cb->p_handlers[p_cb->state](event, data) == FALSE) | |
return WF_STATUS_UNHANDLED; | |
return status; | |
} | |
/***************************************************************************** | |
** | |
** Function wlan_sm_change_state | |
** | |
** Description Make a transition to the new 'state'. The 'WLAN_SM_EXIT_EVT' | |
** shall be invoked before exiting the current state. The | |
** 'WLAN_SM_ENTER_EVT' shall be invoked before entering the new state | |
** | |
** Returns WF_STATUS_SUCCESS on success | |
** WF_STATUS_UNHANDLED if event was not processed | |
** WF_STATUS_FAIL otherwise | |
** | |
******************************************************************************/ | |
wf_status_t wlan_sm_change_state(wlan_sm_handle_t handle, wlan_sm_state_t state) | |
{ | |
wf_status_t status = WF_STATUS_SUCCESS; | |
wlan_sm_cb_t *p_cb = (wlan_sm_cb_t*)handle; | |
if (p_cb == NULL) | |
{ | |
wf_log("Invalid handle"); | |
return WF_STATUS_FAIL; | |
} | |
/* Send exit event to the current state */ | |
if (p_cb->p_handlers[p_cb->state](WLAN_SM_EXIT_EVT, NULL) == FALSE) | |
status = WF_STATUS_UNHANDLED; | |
/* Change to the new state */ | |
p_cb->state = state; | |
/* Send enter event to the new state */ | |
if (p_cb->p_handlers[p_cb->state](WLAN_SM_ENTER_EVT, NULL) == FALSE) | |
status = WF_STATUS_UNHANDLED; | |
return status; | |
} |