| /* |
| * connIbss.c |
| * |
| * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name Texas Instruments nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** \file connIbss.c |
| * \brief IBSS connection implementation |
| * |
| * \see connIbss.h |
| */ |
| |
| /***************************************************************************/ |
| /* */ |
| /* MODULE: connIbss.c */ |
| /* PURPOSE: IBSS connection implementation */ |
| /* */ |
| /***************************************************************************/ |
| |
| #define __FILE_ID__ FILE_ID_26 |
| #include "tidef.h" |
| #include "report.h" |
| #include "osApi.h" |
| #include "conn.h" |
| #include "connIbss.h" |
| #include "timer.h" |
| #include "fsm.h" |
| #include "siteMgrApi.h" |
| #include "sme.h" |
| #include "rsnApi.h" |
| #include "DataCtrl_Api.h" |
| #include "paramOut.h" |
| #include "connApi.h" |
| #include "EvHandler.h" |
| #include "currBss.h" |
| #include "TrafficMonitorAPI.h" |
| #include "healthMonitor.h" |
| #include "TWDriver.h" |
| |
| |
| /* Local functions prototypes */ |
| /* Local functions prototypes */ |
| static TI_STATUS waitDisconnToCmplt_to_idle (void *pData); |
| static TI_STATUS idle_to_selfWait(void *pData); |
| |
| static TI_STATUS idle_to_rsnWait(void *pData); |
| |
| static TI_STATUS selfWait_to_waitToDisconnCmplt(void *pData); |
| static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData); |
| static TI_STATUS connected_to_waitToDisconnCmplt(void *pData); |
| static TI_STATUS selfWait_to_rsnWait(void *pData); |
| static TI_STATUS rsnWait_to_connected(void *pData); |
| static TI_STATUS actionUnexpected(void *pData); |
| static TI_STATUS actionNop(void *pData); |
| static TI_STATUS selfw_merge_rsnw(void *pData); |
| static TI_STATUS rsnw_merge_rsnw(void *pData); |
| static TI_STATUS conn_merge_conn(void *pData); |
| |
| /********************************************/ |
| /* Functions Implementations */ |
| /********************************************/ |
| |
| /*********************************************************************** |
| * conn_ibssConfig |
| *********************************************************************** |
| DESCRIPTION: IBSS Connection configuration function, called by the conection set param function |
| in the selection phase. Configures the connection state machine to IBSS connection mode |
| |
| INPUT: hConn - Connection handle. |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| TI_STATUS conn_ibssConfig(conn_t *pConn) |
| { |
| |
| fsm_actionCell_t smMatrix[CONN_IBSS_NUM_STATES][CONN_IBSS_NUM_EVENTS] = |
| { |
| |
| /* next state and actions for IDLE state */ |
| { {STATE_CONN_IBSS_SELF_WAIT, idle_to_selfWait }, /* CONN_IBSS_CREATE */ |
| {STATE_CONN_IBSS_RSN_WAIT, idle_to_rsnWait }, /* CONN_IBSS_CONNECT */ |
| {STATE_CONN_IBSS_IDLE, actionNop }, /* CONN_IBSS_DISCONNECT */ |
| {STATE_CONN_IBSS_IDLE, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */ |
| {STATE_CONN_IBSS_IDLE, actionUnexpected }, /* CONN_IBSS_STA_JOINED */ |
| {STATE_CONN_IBSS_IDLE, actionUnexpected }, /* CONN_IBSS_MERGE */ |
| {STATE_CONN_IBSS_IDLE, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */ |
| }, |
| |
| /* next state and actions for SELF_WAIT state */ |
| { {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected }, /* CONN_IBSS_CREATE */ |
| {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected }, /* CONN_IBSS_CONNECT */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, selfWait_to_waitToDisconnCmplt }, /* CONN_IBSS_DISCONNECT */ |
| {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */ |
| {STATE_CONN_IBSS_RSN_WAIT, selfWait_to_rsnWait }, /* CONN_IBSS_STA_JOINED */ |
| {STATE_CONN_IBSS_RSN_WAIT, selfw_merge_rsnw }, /* CONN_IBSS_MERGE */ |
| {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */ |
| }, |
| |
| /* next state and actions for RSN_WAIT state */ |
| { {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected }, /* CONN_IBSS_CREATE */ |
| {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected }, /* CONN_IBSS_CONNECT */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, rsnWait_to_waitToDisconnCmplt }, /* CONN_IBSS_DISCONNECT */ |
| {STATE_CONN_IBSS_CONNECTED, rsnWait_to_connected }, /* CONN_IBSS_RSN_SUCC */ |
| {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected }, /* CONN_IBSS_STA_JOINED */ |
| {STATE_CONN_IBSS_RSN_WAIT, rsnw_merge_rsnw }, /* CONN_IBSS_MERGE */ |
| {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */ |
| }, |
| |
| /* next state and actions for CONNECTED state */ |
| { {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_CREATE */ |
| {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_CONNECT */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, connected_to_waitToDisconnCmplt }, /* CONN_IBSS_DISCONNECT */ |
| {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */ |
| {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_STA_JOINED */ |
| {STATE_CONN_IBSS_CONNECTED, conn_merge_conn }, /* CONN_IBSS_MERGE */ |
| {STATE_CONN_IBSS_CONNECTED, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */ |
| }, |
| |
| /* next state and actions for STATE_CONN_IBSS_WAIT_DISCONN_CMPLT state */ |
| { {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_CREATE */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_CONNECT */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_DISCONNECT */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_STA_JOINED */ |
| {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_MERGE */ |
| {STATE_CONN_IBSS_IDLE, waitDisconnToCmplt_to_idle } /* CONN_IBSS_DISCONN_COMPLETE */ |
| } |
| |
| }; |
| |
| return fsm_Config(pConn->ibss_pFsm, (fsm_Matrix_t)smMatrix, CONN_IBSS_NUM_STATES, CONN_IBSS_NUM_EVENTS, conn_ibssSMEvent, pConn->hOs); |
| } |
| |
| |
| /*********************************************************************** |
| * conn_ibssSMEvent |
| *********************************************************************** |
| DESCRIPTION: IBSS Connection SM event processing function, called by the connection API |
| Perform the following: |
| - Print the state movement as a result from the event |
| - Calls the generic state machine event processing function which preform the following: |
| - Calls the correspoding callback function |
| - Move to next state |
| |
| INPUT: currentState - Pointer to the connection current state. |
| event - Received event |
| pConn - Connection handle |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| TI_STATUS conn_ibssSMEvent(TI_UINT8 *currentState, TI_UINT8 event, TI_HANDLE hConn) |
| { |
| conn_t *pConn = (conn_t *)hConn; |
| TI_STATUS status; |
| TI_UINT8 nextState; |
| |
| status = fsm_GetNextState(pConn->ibss_pFsm, *currentState, event, &nextState); |
| if (status != TI_OK) |
| { |
| TRACE0(pConn->hReport, REPORT_SEVERITY_SM, "IBSS State machine error, failed getting next state\n"); |
| return(TI_NOK); |
| } |
| |
| TRACE3( pConn->hReport, REPORT_SEVERITY_INFORMATION, "conn_ibssSMEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currentState, event, nextState); |
| status = fsm_Event(pConn->ibss_pFsm, currentState, event, (void *)pConn); |
| |
| return status; |
| } |
| |
| |
| void connIbss_DisconnectComplete (conn_t *pConn, TI_UINT8 *data, TI_UINT8 dataLength) |
| { |
| /* send an DISCONNECT COMPLETE event to the SM */ |
| conn_ibssSMEvent(&pConn->state, CONN_IBSS_DISCONN_COMPLETE, (TI_HANDLE) pConn); |
| } |
| |
| /************************************************************************************************************/ |
| /* In the following section are listed the callback function used by the IBSS connection state machine */ |
| /************************************************************************************************************/ |
| |
| /*********************************************************************** |
| * selfWait_to_rsnWait |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS selfWait_to_rsnWait (void *pData) |
| { |
| conn_t *pConn = (conn_t *)pData; |
| paramInfo_t param; |
| |
| tmr_StopTimer (pConn->hConnTimer); |
| |
| param.paramType = RX_DATA_PORT_STATUS_PARAM; |
| param.content.rxDataPortStatus = OPEN_EAPOL; |
| rxData_setParam (pConn->hRxData, ¶m); |
| |
| /* Update TxMgmtQueue SM to enable EAPOL packets. */ |
| txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL); |
| |
| return rsn_start (pConn->hRsn); |
| } |
| |
| |
| /*********************************************************************** |
| * rsnWait_to_connected |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS rsnWait_to_connected(void *pData) |
| { |
| paramInfo_t param; |
| |
| conn_t *pConn=(conn_t *)pData; |
| |
| TrafficMonitor_Start( pConn->hTrafficMonitor ); |
| |
| healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_CONNECTED); |
| |
| siteMgr_start(pConn->hSiteMgr); |
| |
| param.paramType = RX_DATA_PORT_STATUS_PARAM; |
| param.content.rxDataPortStatus = OPEN; |
| rxData_setParam(((conn_t *)pData)->hRxData, ¶m); |
| |
| /* Update TxMgmtQueue SM to open Tx path to all packets. */ |
| txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_OPEN); |
| |
| /* Update current BSS connection type and mode */ |
| currBSS_updateConnectedState(pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT); |
| |
| sme_ReportConnStatus(((conn_t *)pData)->hSmeSm, STATUS_SUCCESSFUL, 0); |
| |
| return TI_OK; |
| } |
| |
| static TI_STATUS selfw_merge_rsnw(void *pData) |
| { |
| conn_t *pConn=(conn_t *)pData; |
| paramInfo_t param; |
| |
| os_printf("IBSS selfw_merge_rsnw!!!!!!!!!!\n"); |
| |
| tmr_StopTimer (pConn->hConnTimer); |
| siteMgr_join(pConn->hSiteMgr); |
| |
| param.paramType = RX_DATA_PORT_STATUS_PARAM; |
| param.content.rxDataPortStatus = OPEN_EAPOL; |
| rxData_setParam (pConn->hRxData, ¶m); |
| |
| /* Update TxMgmtQueue SM to enable EAPOL packets. */ |
| txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL); |
| |
| return rsn_start (pConn->hRsn); |
| |
| } |
| |
| |
| static TI_STATUS rsnw_merge_rsnw(void *pData) |
| { |
| conn_t *pConn=(conn_t *)pData; |
| |
| os_printf("IBSS rsnw_merge_rsnw!!!!!!!!!!\n"); |
| |
| siteMgr_join(pConn->hSiteMgr); |
| |
| return TI_OK; |
| } |
| |
| |
| static TI_STATUS conn_merge_conn(void *pData) |
| { |
| conn_t *pConn=(conn_t *)pData; |
| |
| os_printf("IBSS conn_merge_conn!!!!!!!!!!\n"); |
| |
| siteMgr_join(pConn->hSiteMgr); |
| |
| return TI_OK; |
| } |
| |
| static TI_STATUS waitDisconnToCmplt_to_idle (void *pData) |
| { |
| conn_t *pConn = (conn_t *)pData; |
| |
| /* Inform the SME about the connection lost */ |
| /* we use this status at SME, if != 0 means that assoc frame sent */ |
| sme_ReportConnStatus(pConn->hSmeSm, STATUS_UNSPECIFIED, 1); |
| return TI_OK; |
| } |
| |
| |
| |
| /*********************************************************************** |
| * actionUnexpected |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS actionUnexpected(void *pData) |
| { |
| #ifdef TI_DBG |
| conn_t *pConn = (conn_t *)pData; |
| |
| TRACE0(pConn->hReport, REPORT_SEVERITY_SM, "State machine error, unexpected Event\n\n"); |
| #endif /*TI_DBG*/ |
| |
| return TI_OK; |
| } |
| |
| /*********************************************************************** |
| * actionNop |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS actionNop(void *pData) |
| { |
| return TI_OK; |
| } |
| |
| |
| /*********************************************************************** |
| * selfWait_to_waitToDisconnCmplt |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS selfWait_to_waitToDisconnCmplt (void *pData) |
| { |
| conn_t *pConn = (conn_t *)pData; |
| paramInfo_t param; |
| |
| tmr_StopTimer (pConn->hConnTimer); |
| |
| siteMgr_removeSelfSite(pConn->hSiteMgr); |
| |
| /* Update current BSS connection type and mode */ |
| currBSS_updateConnectedState(pConn->hCurrBss, TI_FALSE, BSS_INDEPENDENT); |
| |
| /* stop beacon generation */ |
| param.paramType = RX_DATA_PORT_STATUS_PARAM; |
| param.content.rxDataPortStatus = CLOSE; |
| rxData_setParam(pConn->hRxData, ¶m); |
| |
| /* Update TxMgmtQueue SM to close Tx path. */ |
| txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_CLOSE); |
| |
| TWD_CmdFwDisconnect (pConn->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED); |
| |
| return TI_OK; |
| } |
| |
| |
| |
| /*********************************************************************** |
| * rsnWait_to_waitToDisconnCmplt |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData) |
| { |
| paramInfo_t param; |
| TI_STATUS tStatus; |
| |
| tStatus = rsn_stop(((conn_t *)pData)->hRsn, TI_FALSE); |
| |
| param.paramType = RX_DATA_PORT_STATUS_PARAM; |
| param.content.rxDataPortStatus = CLOSE; |
| rxData_setParam(((conn_t *)pData)->hRxData, ¶m); |
| |
| /* Update TxMgmtQueue SM to close Tx path. */ |
| txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_CLOSE); |
| |
| /* Update current BSS connection type and mode */ |
| currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_FALSE, BSS_INDEPENDENT); |
| |
| /* Stop beacon generation */ |
| TWD_CmdFwDisconnect (((conn_t *)pData)->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED); |
| |
| return tStatus; |
| } |
| |
| |
| /*********************************************************************** |
| * connected_to_waitToDisconnCmplt |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS connected_to_waitToDisconnCmplt(void *pData) |
| { |
| conn_t *pConn=(conn_t *)pData; |
| |
| TrafficMonitor_Stop(pConn->hTrafficMonitor); |
| |
| healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_DISCONNECTED); |
| |
| /* The logic of this action is identical to rsnWait_to_idle */ |
| return rsnWait_to_waitToDisconnCmplt(pConn); |
| } |
| |
| |
| |
| |
| |
| /*********************************************************************** |
| * idle_to_selfWait |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS idle_to_selfWait (void *pData) |
| { |
| conn_t *pConn = (conn_t *)pData; |
| TI_UINT16 randomTime; |
| |
| siteMgr_join (pConn->hSiteMgr); |
| |
| /* get a randomTime that is constructed of the lower 13 bits ot the system time to |
| get a MS random time of ~8000 ms */ |
| randomTime = os_timeStampMs (pConn->hOs) & 0x1FFF; |
| |
| /* Update current BSS connection type and mode */ |
| currBSS_updateConnectedState (pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT); |
| |
| tmr_StartTimer (pConn->hConnTimer, |
| conn_timeout, |
| (TI_HANDLE)pConn, |
| pConn->timeout + randomTime, |
| TI_FALSE); |
| |
| /* Notify that the driver is associated to the supplicant\IP stack. */ |
| EvHandlerSendEvent (pConn->hEvHandler, IPC_EVENT_ASSOCIATED, NULL, 0); |
| |
| return TI_OK; |
| } |
| |
| |
| |
| /*********************************************************************** |
| * idle_to_rsnWait |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static TI_STATUS idle_to_rsnWait(void *pData) |
| { |
| paramInfo_t param; |
| |
| siteMgr_join(((conn_t *)pData)->hSiteMgr); |
| |
| param.paramType = RX_DATA_PORT_STATUS_PARAM; |
| param.content.rxDataPortStatus = OPEN_EAPOL; |
| rxData_setParam(((conn_t *)pData)->hRxData, ¶m); |
| |
| /* Update TxMgmtQueue SM to enable EAPOL packets. */ |
| txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_EAPOL); |
| |
| /* |
| * Notify that the driver is associated to the supplicant\IP stack. |
| */ |
| EvHandlerSendEvent(((conn_t *)pData)->hEvHandler, IPC_EVENT_ASSOCIATED, NULL,0); |
| |
| /* Update current BSS connection type and mode */ |
| currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_TRUE, BSS_INDEPENDENT); |
| |
| return rsn_start(((conn_t *)pData)->hRsn); |
| } |
| |