| /* |
| * SwitchChannel.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 SwitchChannel.c |
| * \brief SwitchChannel module interface |
| * |
| * \see SwitchChannelApi.h |
| */ |
| |
| /****************************************************************************************************/ |
| /* */ |
| /* MODULE: SwitchChannel.c */ |
| /* PURPOSE: SwitchChannel module interface. */ |
| /* This module perform SwitchChannel (Dynamic Frequency Selection) */ |
| /* according to AP command. The object responsibles for switching channel after*/ |
| /* the requires time and quieting the channel for the required duration */ |
| /* time. */ |
| /****************************************************************************************************/ |
| |
| #define __FILE_ID__ FILE_ID_7 |
| #include "tidef.h" |
| #include "report.h" |
| #include "osApi.h" |
| #include "paramOut.h" |
| #include "SwitchChannelApi.h" |
| #include "DataCtrl_Api.h" |
| #include "regulatoryDomainApi.h" |
| #include "apConn.h" |
| #include "siteMgrApi.h" |
| #include "PowerMgr_API.h" |
| #include "healthMonitor.h" |
| #include "TWDriver.h" |
| #include "DrvMainModules.h" |
| |
| /* allocation vector */ |
| #define SC_INIT_BIT (1) |
| #define SC_SM_INIT_BIT (2) |
| |
| #define SC_SWITCH_CHANNEL_CMD_LEN 3 |
| #define SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS 0 |
| #define SC_SWITCH_CHANNEL_MODE_TX_SUS 1 |
| |
| |
| #define SC_CHANNEL_INVALID TI_FALSE |
| #define SC_CHANNEL_VALID TI_TRUE |
| |
| /* Enumerations */ |
| |
| /** state machine states */ |
| typedef enum |
| { |
| SC_STATE_IDLE = 0, |
| SC_STATE_WAIT_4_CMD = 1, |
| SC_STATE_WAIT_4_SCR = 2, |
| SC_STATE_SC_IN_PROG = 3, |
| SC_STATE_LAST = 4 |
| } switchChannel_smStates; |
| |
| /** State machine events */ |
| typedef enum |
| { |
| SC_EVENT_START = 0, |
| SC_EVENT_STOP = 1, |
| SC_EVENT_SC_CMD = 2, |
| SC_EVENT_SCR_RUN = 3, |
| SC_EVENT_SCR_FAIL = 4, |
| SC_EVENT_SC_CMPLT = 5, |
| SC_EVENT_FW_RESET = 6, |
| SC_EVENT_LAST = 7 |
| } switchChannel_smEvents; |
| |
| |
| #define SC_NUM_STATES SC_STATE_LAST |
| #define SC_NUM_EVENTS SC_EVENT_LAST |
| |
| |
| /* Structures */ |
| typedef struct |
| { |
| |
| /* SwitchChannel parameters that can be configured externally */ |
| TI_BOOL dot11SpectrumManagementRequired; |
| |
| /* Internal SwitchChannel parameters */ |
| TI_UINT8 currentState; |
| dot11_CHANNEL_SWITCH_t curChannelSwitchCmdParams; |
| TI_UINT32 SCRRequestTimestamp; |
| TI_UINT8 currentChannel; |
| TI_BOOL switchChannelStarted; |
| |
| #ifdef TI_DBG |
| /* switchChannelCmd for debug */ |
| dot11_CHANNEL_SWITCH_t debugChannelSwitchCmdParams; |
| TI_UINT8 ignoreCancelSwitchChannelCmd; |
| #endif |
| |
| /* SwitchChannel SM */ |
| fsm_stateMachine_t *pSwitchChannelSm; |
| |
| /* SwitchChannel handles to other objects */ |
| TI_HANDLE hTWD; |
| TI_HANDLE hSiteMgr; |
| TI_HANDLE hSCR; |
| TI_HANDLE hRegulatoryDomain; |
| TI_HANDLE hPowerMngr; |
| TI_HANDLE hApConn; |
| TI_HANDLE hReport; |
| TI_HANDLE hOs; |
| |
| } switchChannel_t; |
| |
| |
| |
| |
| /* External data definitions */ |
| |
| /* Local functions definitions */ |
| |
| /* Global variables */ |
| |
| |
| /********************************************************************************/ |
| /* Internal functions prototypes. */ |
| /********************************************************************************/ |
| |
| |
| /* SM functions */ |
| static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData); |
| static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData); |
| static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData); |
| static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData); |
| static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData); |
| static TI_STATUS switchChannel_smNop(void *pData); |
| static TI_STATUS switchChannel_smUnexpected(void *pData); |
| static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData); |
| static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData); |
| static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData); |
| static TI_STATUS switchChannel_smStart(void *pData); |
| |
| |
| /* other functions */ |
| static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec); |
| static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data); |
| static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel); |
| void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel); |
| void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus, |
| EScrResourceId eResource, EScePendReason pendReason ); |
| #ifdef TI_DBG |
| static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel); |
| #endif |
| |
| |
| /********************************************************************************/ |
| /* Interface functions Implementation. */ |
| /********************************************************************************/ |
| |
| |
| /************************************************************************ |
| * switchChannel_create * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * This procedure is called by the config manager when the driver is created. |
| * It creates the SwitchChannel object. |
| * |
| * \b ARGS: |
| * |
| * I - hOs - OS context \n |
| * |
| * \b RETURNS: |
| * |
| * Handle to the SwitchChannel object. |
| * |
| * \sa |
| */ |
| TI_HANDLE switchChannel_create(TI_HANDLE hOs) |
| { |
| switchChannel_t *pSwitchChannel = NULL; |
| TI_UINT32 initVec = 0; |
| TI_STATUS status; |
| |
| /* allocating the SwitchChannel object */ |
| pSwitchChannel = os_memoryAlloc(hOs,sizeof(switchChannel_t)); |
| |
| if (pSwitchChannel == NULL) |
| return NULL; |
| |
| initVec |= (1 << SC_INIT_BIT); |
| |
| os_memoryZero(hOs, pSwitchChannel, sizeof(switchChannel_t)); |
| |
| pSwitchChannel->hOs = hOs; |
| |
| status = fsm_Create(hOs, &pSwitchChannel->pSwitchChannelSm, SC_NUM_STATES, SC_NUM_EVENTS); |
| if (status != TI_OK) |
| { |
| release_module(pSwitchChannel, initVec); |
| WLAN_OS_REPORT(("FATAL ERROR: switchChannel_create(): Error Creating pSwitchChannelSm - Aborting\n")); |
| return NULL; |
| } |
| initVec |= (1 << SC_SM_INIT_BIT); |
| |
| return(pSwitchChannel); |
| } |
| |
| /************************************************************************ |
| * switchChannel_init * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * This procedure is called by the DrvMain when the driver is initialized. |
| * It initializes the SwitchChannel object's variables and handlers and creates the SwitchChannel SM. |
| * |
| * \b ARGS: |
| * |
| * I - pStadHandles - The driver modules handles \n |
| * |
| * \b RETURNS: |
| * |
| * void |
| * |
| * \sa |
| */ |
| void switchChannel_init (TStadHandlesList *pStadHandles) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)(pStadHandles->hSwitchChannel); |
| |
| /** Roaming State Machine matrix */ |
| fsm_actionCell_t switchChannel_SM[SC_NUM_STATES][SC_NUM_EVENTS] = |
| { |
| /* next state and actions for IDLE state */ |
| { {SC_STATE_WAIT_4_CMD, switchChannel_smStart}, /* START */ |
| {SC_STATE_IDLE, switchChannel_smNop}, /* STOP */ |
| {SC_STATE_IDLE, switchChannel_smNop}, /* SC_CMD */ |
| {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SCR_RUN */ |
| {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SCR_FAIL */ |
| {SC_STATE_IDLE, switchChannel_smUnexpected}, /* SC_CMPLT */ |
| {SC_STATE_IDLE, switchChannel_smUnexpected} /* FW_RESET */ |
| }, |
| |
| /* next state and actions for WAIT_4_CMD state */ |
| { {SC_STATE_WAIT_4_CMD, switchChannel_smNop}, /* START */ |
| {SC_STATE_IDLE, switchChannel_smStopWhileWait4Cmd}, /* STOP */ |
| {SC_STATE_WAIT_4_SCR, switchChannel_smReqSCR_UpdateCmd}, /* SC_CMD */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_RUN */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_FAIL */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SC_CMPLT */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected} /* FW_RESET */ |
| |
| }, |
| |
| /* next state and actions for WAIT_4_SCR state */ |
| { {SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected}, /* START */ |
| {SC_STATE_IDLE, switchChannel_smStopWhileWait4Scr}, /* STOP */ |
| {SC_STATE_WAIT_4_SCR, switchChannel_smNop}, /* SC_CMD */ |
| {SC_STATE_SC_IN_PROG, switchChannel_smStartSwitchChannelCmd}, /* SCR_RUN */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smScrFailWhileWait4Scr}, /* SCR_FAIL */ |
| {SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected} , /* SC_CMPLT */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected} /* FW_RESET */ |
| |
| }, |
| |
| /* next state and actions for switchChannel_IN_PROG state */ |
| { {SC_STATE_SC_IN_PROG, switchChannel_smUnexpected}, /* START */ |
| {SC_STATE_IDLE, switchChannel_smStopWhileSwitchChannelInProg}, /* STOP */ |
| {SC_STATE_SC_IN_PROG, switchChannel_smNop}, /* SC_CMD */ |
| {SC_STATE_SC_IN_PROG, switchChannel_smUnexpected}, /* SCR_RUN */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}, /* SCR_FAIL */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smSwitchChannelCmplt}, /* SC_CMPLT */ |
| {SC_STATE_WAIT_4_CMD, switchChannel_smFwResetWhileSCInProg} /* FW_RESET */ |
| } |
| }; |
| |
| fsm_Config(pSwitchChannel->pSwitchChannelSm, |
| &switchChannel_SM[0][0], |
| SC_NUM_STATES, |
| SC_NUM_EVENTS, |
| switchChannel_smEvent, pSwitchChannel->hOs); |
| |
| /* init handlers */ |
| pSwitchChannel->hTWD = pStadHandles->hTWD; |
| pSwitchChannel->hSiteMgr = pStadHandles->hSiteMgr; |
| pSwitchChannel->hSCR = pStadHandles->hSCR; |
| pSwitchChannel->hRegulatoryDomain = pStadHandles->hRegulatoryDomain; |
| pSwitchChannel->hApConn = pStadHandles->hAPConnection; |
| pSwitchChannel->hReport = pStadHandles->hReport; |
| pSwitchChannel->hOs = pStadHandles->hOs; |
| } |
| |
| |
| TI_STATUS switchChannel_SetDefaults (TI_HANDLE hSwitchChannel, SwitchChannelInitParams_t *SwitchChannelInitParams) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; |
| |
| /* init variables */ |
| pSwitchChannel->dot11SpectrumManagementRequired = SwitchChannelInitParams->dot11SpectrumManagementRequired; |
| pSwitchChannel->currentState = SC_STATE_IDLE; |
| pSwitchChannel->currentChannel = 0; |
| pSwitchChannel->switchChannelStarted = TI_FALSE; |
| |
| /* register to SCR */ |
| scr_registerClientCB(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, |
| switchChannel_scrStatusCB, pSwitchChannel); |
| |
| /* register to Switch Channel Complete event in HAL */ |
| TWD_RegisterEvent (pSwitchChannel->hTWD, |
| TWD_OWN_EVENT_SWITCH_CHANNEL_CMPLT, |
| (void *)switchChannel_SwitchChannelCmdCompleteReturn, |
| pSwitchChannel); |
| |
| TWD_EnableEvent (pSwitchChannel->hTWD, TWD_OWN_EVENT_SWITCH_CHANNEL_CMPLT); |
| #ifdef TI_DBG |
| /* for debug */ |
| pSwitchChannel->debugChannelSwitchCmdParams.hdr[0] = CHANNEL_SWITCH_ANNOUNCEMENT_IE_ID; |
| pSwitchChannel->debugChannelSwitchCmdParams.hdr[1] = SC_SWITCH_CHANNEL_CMD_LEN; |
| pSwitchChannel->ignoreCancelSwitchChannelCmd = 0; |
| #endif |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INIT, ".....SwitchChannel configured successfully\n"); |
| |
| return TI_OK; |
| } |
| |
| |
| /************************************************************************ |
| * switchChannel_stop * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * This procedure is called by the SME when the state is changed from CONNECTED. |
| * It generates a STOP event to the SwitchChannel SM. |
| * |
| * \b ARGS: |
| * |
| * I - hSwitchChannel - SwitchChannel context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK on success, TI_NOK otherwise |
| * |
| * \sa |
| */ |
| TI_STATUS switchChannel_stop(TI_HANDLE hSwitchChannel) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; |
| |
| pSwitchChannel->switchChannelStarted = TI_FALSE; |
| return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel)); |
| |
| } |
| |
| /************************************************************************ |
| * switchChannel_start * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * This procedure is called by the SME when the state is changed to CONNECTED. |
| * It generates a START event to the SwitchChannel SM. |
| * |
| * \b ARGS: |
| * |
| * I - hSwitchChannel - SwitchChannel context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK on success, TI_NOK otherwise |
| * |
| * \sa |
| */ |
| TI_STATUS switchChannel_start(TI_HANDLE hSwitchChannel) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; |
| pSwitchChannel->switchChannelStarted = TI_TRUE; |
| |
| return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel)); |
| |
| } |
| |
| |
| /************************************************************************ |
| * switchChannel_unload * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * This procedure is called by the config manager when the driver is unloaded. |
| * It frees any memory allocated and timers. |
| * |
| * \b ARGS: |
| * |
| * I - hSwitchChannel - SwitchChannel context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK on success, TI_NOK otherwise |
| * |
| * \sa |
| */ |
| TI_STATUS switchChannel_unload(TI_HANDLE hSwitchChannel) |
| { |
| TI_UINT32 initVec; |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; |
| |
| if (pSwitchChannel == NULL) |
| return TI_OK; |
| |
| initVec = 0xff; |
| release_module(pSwitchChannel, initVec); |
| |
| return TI_OK; |
| } |
| |
| |
| /************************************************************************ |
| * switchChannel_recvCmd * |
| ************************************************************************/ |
| /*DESCRIPTION: This function is called by MLME Parser upon receiving of |
| Beacon, Probe Response or Action with Switch Channel command, |
| or beacon/ |
| performs the following: |
| - Initializes the switching channel procedure. |
| - Setting timer to the actual switching time(if needed) |
| |
| INPUT: hSwitchChannel - SwitchChannel handle. |
| switchMode - indicates whether to stop transmission |
| until the scheduled channel switch. |
| newChannelNum - indicates the number of the new channel. |
| durationTime - indicates the time (expressed in ms) until |
| the scheduled channel switch should accure. |
| |
| OUTPUT: None |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| |
| void switchChannel_recvCmd(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_UINT8 channel) |
| { |
| |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; |
| paramInfo_t param; |
| |
| if (pSwitchChannel==NULL) |
| { |
| return; |
| } |
| |
| param.paramType = REGULATORY_DOMAIN_DFS_CHANNELS_RANGE; |
| regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain, ¶m); |
| |
| if (!pSwitchChannel->dot11SpectrumManagementRequired || |
| (channel < param.content.DFS_ChannelRange.minDFS_channelNum) || |
| (channel > param.content.DFS_ChannelRange.maxDFS_channelNum)) |
| { /* Do not parse Switch Channel IE, when SpectrumManagement is disabled, |
| or the channel is non-DFS channel */ |
| return; |
| } |
| #ifdef TI_DBG |
| /* for debug purposes only */ |
| if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0) |
| { |
| return; |
| } |
| #endif |
| |
| if (channelSwitch == NULL) |
| { /* No SC IE, update regDomain */ |
| param.paramType = REGULATORY_DOMAIN_UPDATE_CHANNEL_VALIDITY; |
| param.content.channel = channel; |
| regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); |
| } |
| else |
| { /* SC IE exists */ |
| TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n", channelSwitch->channelNumber, channelSwitch->channelSwitchMode, channelSwitch->channelSwitchCount); |
| |
| /* Checking channel number validity */ |
| param.content.channel = channelSwitch->channelNumber; |
| param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; |
| regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m); |
| if ( ( !param.content.bIsChannelSupprted ) || |
| (channelSwitch->channelSwitchCount == 0) || |
| (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)) |
| { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid, |
| or the TBTT count is 0 */ |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "report Roaming trigger\n"); |
| if (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS) |
| { |
| param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY; |
| param.content.channelValidity.channelNum = channel; |
| param.content.channelValidity.channelValidity = TI_FALSE; |
| regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); |
| } |
| |
| if (TI_TRUE == pSwitchChannel->switchChannelStarted) |
| { |
| apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL); |
| } |
| |
| } |
| else |
| { /* Invoke Switch Channel command */ |
| /* update the new SCC params */ |
| pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; |
| switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel); |
| } |
| |
| } |
| |
| } |
| |
| |
| /************************************************************************ |
| * switchChannel_powerSaveStatusReturn * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * This procedure is called when power save status is returned |
| * |
| * \b ARGS: |
| * |
| * I/O - hSwitchChannel - SwitchChannel context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK on success, TI_NOK otherwise. |
| * |
| * \sa |
| */ |
| void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_SwitchChannelCmdCompleteReturn \n"); |
| |
| switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMPLT, pSwitchChannel); |
| |
| } |
| |
| /************************************************************************ |
| * switchChannel_enableDisableSpectrumMngmt * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * This procedure enables or disables the spectrum management |
| * |
| * \b ARGS: |
| * |
| * I - hSwitchChannel - SwitchChannel context \n |
| * I - enableDisable - TI_TRUE - Enable, TI_FALSE - Disable |
| * |
| * \b RETURNS: |
| * |
| * TI_OK on success, TI_NOK otherwise. |
| * |
| * \sa |
| */ |
| void switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel, TI_BOOL enableDisable) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| |
| |
| if (hSwitchChannel == NULL) |
| { |
| return; |
| } |
| TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_enableDisableSpectrumMngmt, enableDisable=%d \n", enableDisable); |
| |
| pSwitchChannel->dot11SpectrumManagementRequired = enableDisable; |
| |
| if (enableDisable) |
| { /* Enable SC, if it was started invoke start event. |
| otherwise, wait for a start event */ |
| if (pSwitchChannel->switchChannelStarted) |
| { |
| switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel); |
| } |
| } |
| else |
| { /* Disable SC */ |
| switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel); |
| } |
| |
| } |
| |
| |
| |
| /************************************************************************ |
| * SwitchChannel internal functions * |
| ************************************************************************/ |
| |
| /************************************************************************ |
| * switchChannel_smEvent * |
| ************************************************************************/ |
| /** |
| * |
| * \b Description: |
| * |
| * SwitchChannel state machine transition function |
| * |
| * \b ARGS: |
| * |
| * I/O - currentState - current state in the state machine\n |
| * I - event - specific event for the state machine\n |
| * I - pData - Data for state machine action function\n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK on success, TI_NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data) |
| { |
| TI_STATUS status; |
| TI_UINT8 nextState; |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)data; |
| |
| |
| status = fsm_GetNextState(pSwitchChannel->pSwitchChannelSm, *currState, event, &nextState); |
| if (status != TI_OK) |
| { |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent, fsm_GetNextState error\n"); |
| return(TI_NOK); |
| } |
| |
| TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState); |
| |
| status = fsm_Event(pSwitchChannel->pSwitchChannelSm, currState, event, (void *)pSwitchChannel); |
| |
| if (status != TI_OK) |
| { |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent fsm_Event error\n"); |
| TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState); |
| } |
| return status; |
| |
| } |
| |
| |
| /************************************************************************ |
| * switchChannel_smStart * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when the station becomes connected. |
| * update the current channel. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smStart(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; |
| paramInfo_t param; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| /* get the current channel number */ |
| param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; |
| siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m); |
| pSwitchChannel->currentChannel = param.content.siteMgrCurrentChannel; |
| |
| TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStart, channelNo=%d\n", pSwitchChannel->currentChannel); |
| return TI_OK; |
| |
| } |
| |
| /************************************************************************ |
| * switchChannel_smReqSCR_UpdateCmd * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * Update the Switch Channel command parameters. |
| * Request SCR and wait for SCR return. |
| * if tx status suspend |
| * update regulatory Domain |
| * update tx |
| * start periodic timer |
| |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; |
| EScrClientRequestStatus scrStatus; |
| EScePendReason scrPendReason; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smReqSCR_UpdateCmd, channelNo=%d, TBTT = %d, Mode = %d\n", pSwitchChannel->curChannelSwitchCmdParams.channelNumber, pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount, pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode); |
| |
| |
| /* Save the TS when requesting SCR */ |
| pSwitchChannel->SCRRequestTimestamp = os_timeStampMs(pSwitchChannel->hOs); |
| |
| scrStatus = scr_clientRequest(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, |
| SCR_RESOURCE_SERVING_CHANNEL, &scrPendReason); |
| if ((scrStatus != SCR_CRS_RUN) && (scrStatus != SCR_CRS_PEND)) |
| { |
| TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smReqSCR_UpdateCmd():Abort the switch channel, request Roaming, scrStatus=%d\n", scrStatus); |
| return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel)); |
| |
| } |
| if (scrStatus == SCR_CRS_RUN) |
| { |
| switchChannel_scrStatusCB(pSwitchChannel, scrStatus, SCR_RESOURCE_SERVING_CHANNEL, scrPendReason); |
| } |
| else if ((scrPendReason==SCR_PR_OTHER_CLIENT_RUNNING) || |
| (scrPendReason==SCR_PR_DIFFERENT_GROUP_RUNNING) ) |
| { /* No use to wait for the SCR, invoke FAIL */ |
| return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel)); |
| } |
| /* wait for the SCR callback function to be called */ |
| return TI_OK; |
| |
| } |
| |
| |
| /************************************************************************ |
| * switchChannel_scrStatusCB * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called by the SCR when: |
| * the resource is reserved for the SwitchChannel - SCR_CRS_RUN |
| * recovery occurred - SCR_CRS_ABORT |
| * other = ERROR |
| * |
| * \b ARGS: |
| * |
| * I - hSwitchChannel - pointer to the SwitchChannel SM context \n |
| * I - requestStatus - the SCR request status \n |
| * I - eResource - the resource for which the CB is issued \n |
| * I - pendReason - The SCR pend status in case of pend reply \n |
| * |
| * \b RETURNS: |
| * |
| * None. |
| * |
| * |
| *************************************************************************/ |
| void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus, |
| EScrResourceId eResource, EScePendReason pendReason ) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| switchChannel_smEvents scEvent; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| |
| switch (requestStatus) |
| { |
| case SCR_CRS_RUN: |
| scEvent = SC_EVENT_SCR_RUN; |
| break; |
| case SCR_CRS_FW_RESET: |
| scEvent = SC_EVENT_FW_RESET; |
| break; |
| case SCR_CRS_PEND: |
| scEvent = SC_EVENT_SCR_FAIL; |
| break; |
| case SCR_CRS_ABORT: |
| default: |
| TRACE2(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_scrStatusCB scrStatus = %d, pendReason=%d\n", requestStatus, pendReason); |
| scEvent = SC_EVENT_SCR_FAIL; |
| break; |
| } |
| |
| switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, scEvent, pSwitchChannel); |
| |
| } |
| |
| |
| |
| /************************************************************************ |
| * switchChannel_smStartSwitchChannelCmd * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called once SwitchChannel command was received and the SCR |
| * request returned with reason RUN. |
| * In this case perform the following: |
| * Set CMD to FW |
| |
| |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; |
| TSwitchChannelParams pSwitchChannelCmd; |
| TI_UINT32 switchChannelTimeDuration; |
| paramInfo_t param; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM; |
| siteMgr_getParam(pSwitchChannel->hSiteMgr, ¶m); |
| |
| switchChannelTimeDuration = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount * param.content.beaconInterval * 1024 / 1000; |
| if ( (switchChannelTimeDuration!=0) && |
| ((os_timeStampMs(pSwitchChannel->hOs) - pSwitchChannel->SCRRequestTimestamp) >= switchChannelTimeDuration )) |
| { /* There's no time to perfrom the SCC, set the Count to 1 */ |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 1; |
| } |
| |
| apConn_indicateSwitchChannelInProgress(pSwitchChannel->hApConn); |
| |
| pSwitchChannelCmd.channelNumber = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; |
| pSwitchChannelCmd.switchTime = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount; |
| pSwitchChannelCmd.txFlag = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode; |
| pSwitchChannelCmd.flush = 0; |
| TWD_CmdSwitchChannel (pSwitchChannel->hTWD, &pSwitchChannelCmd); |
| |
| TRACE4(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "TWD_CmdSwitchChannel:Set the cmd in HAL. Params:\n channelNumber=%d, switchTime=%d, txFlag=%d, flush=%d \n", pSwitchChannelCmd.channelNumber, pSwitchChannelCmd.switchTime, pSwitchChannelCmd.txFlag, pSwitchChannelCmd.flush); |
| |
| return TI_OK; |
| |
| } |
| |
| /************************************************************************ |
| * switchChannel_smFwResetWhileSCInProg * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when Switch Channel command is cancelled. |
| * In this case update TX nad regulatory Domain adn HAL. |
| * Release the SCR and exit PS. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; |
| paramInfo_t param; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smFwResetWhileSCInProg \n"); |
| |
| /* Update new current channel */ |
| param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; |
| param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; |
| siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m); |
| |
| apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); |
| |
| switchChannel_zeroDatabase(pSwitchChannel); |
| |
| /* release the SCR */ |
| scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); |
| |
| return TI_OK; |
| |
| } |
| |
| |
| /************************************************************************ |
| * switchChannel_smSwitchChannelCmplt * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when SwitchChannel command completed in FW. |
| * In this case release SCR and update current channel. |
| * If TX was sus, it will be enabled only after first Beacon is recieved. |
| * Exit PS. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)pData; |
| paramInfo_t param; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| /* Update new current channel */ |
| param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; |
| param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber; |
| siteMgr_setParam(pSwitchChannel->hSiteMgr, ¶m); |
| |
| TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smSwitchChannelCmplt, new channelNum = %d\n", pSwitchChannel->currentChannel); |
| |
| apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); |
| switchChannel_zeroDatabase(pSwitchChannel); |
| |
| /* release the SCR */ |
| scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); |
| |
| return TI_OK; |
| |
| } |
| |
| |
| |
| /************************************************************************ |
| * switchChannel_smScrFailWhileWait4Scr * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when recovery occurred, while waiting for SCR due |
| * to previous switch channel command. |
| * Exit PS |
| * Release SCR. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smScrFailWhileWait4Scr\n"); |
| |
| switchChannel_zeroDatabase(pSwitchChannel); |
| |
| /* release the SCR is not required !!! */ |
| scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * switchChannel_smStopWhileWait4Cmd * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when the station becomes Disconnected and the current |
| * state is Wait4Cmd. In this case perfrom: |
| * Stop the timer |
| * Enable TX if it was disabled |
| * Zero the current command parameters |
| * Stop the timer |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Cmd\n"); |
| |
| switchChannel_zeroDatabase(pSwitchChannel); |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * switchChannel_smStopWhileWait4Scr * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when the station becomes Disconnected and the current |
| * state is Wait4Scr. In this case perfrom: |
| * Stop the timer |
| * Enable TX if it was disabled |
| * Zero the current command parameters |
| * Complete SCR |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Scr\n"); |
| |
| |
| switchChannel_zeroDatabase(pSwitchChannel); |
| |
| /* release the SCR */ |
| scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); |
| |
| return TI_OK; |
| } |
| |
| /************************************************************************ |
| * switchChannel_smStopWhileSwitchChannelInProg * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when the station becomes Disconnected and the current |
| * state is SwitchChannelInProg. In this case perfrom: |
| * Stop the timer |
| * Enable TX if it was disabled |
| * Zero the current command parameters |
| * resume self test |
| * Complete SCR |
| * Exit PS |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| *************************************************************************/ |
| static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)pData; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileSwitchChannelInProg\n"); |
| |
| /* Exit PS */ |
| /*PowerMgr_exitFromDriverMode(pSwitchChannel->hPowerMngr, "SwitchChannel");*/ |
| |
| apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn); |
| |
| TWD_CmdSwitchChannelCancel (pSwitchChannel->hTWD, pSwitchChannel->currentChannel); |
| switchChannel_zeroDatabase(pSwitchChannel); |
| |
| /* release the SCR */ |
| scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL); |
| |
| return TI_OK; |
| } |
| |
| |
| |
| |
| /************************************************************************ |
| * switchChannel_zeroDatabase * |
| ************************************************************************/ |
| /** |
| * |
| * |
| * \b Description: |
| * |
| * This function is called when the SwitchChannel internal database should be zero. |
| * The following parameters are zerod: |
| * SwitchChannelChannelRange - the timestamps and validity state of channels |
| * curChannelSwitchCmdParams - the current switch channel command parameters |
| * |
| * \b ARGS: |
| * |
| * I - pSwitchChannel - pointer to the SwitchChannel SM context \n |
| * I - channelNum - channel number \n |
| * I - timestamp - required timestamp \n |
| * |
| * \b RETURNS: |
| * |
| * None. |
| * |
| * |
| *************************************************************************/ |
| static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel) |
| { |
| |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_zeroDatabase\n"); |
| |
| |
| pSwitchChannel->curChannelSwitchCmdParams.channelNumber = 0; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 0; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS; |
| pSwitchChannel->currentChannel = 0; |
| |
| } |
| |
| /*********************************************************************** |
| * release_module |
| ***********************************************************************/ |
| /* |
| DESCRIPTION: Called by the destroy function or by the create function (on failure) |
| Go over the vector, for each bit that is set, release the corresponding module. |
| |
| INPUT: pSwitchChannel - SwitchChannel pointer. |
| initVec - Vector that contains a bit set for each module thah had been initiualized |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec) |
| { |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| if (initVec & (1 << SC_SM_INIT_BIT)) |
| { |
| fsm_Unload(pSwitchChannel->hOs, pSwitchChannel->pSwitchChannelSm); |
| } |
| |
| if (initVec & (1 << SC_INIT_BIT)) |
| { |
| os_memoryFree(pSwitchChannel->hOs, pSwitchChannel, sizeof(switchChannel_t)); |
| } |
| |
| initVec = 0; |
| } |
| |
| |
| /** |
| * |
| * switchChannel_smNop - Do nothing |
| * |
| * \b Description: |
| * |
| * Do nothing in the SM. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| static TI_STATUS switchChannel_smNop(void *pData) |
| { |
| switchChannel_t *pSwitchChannel; |
| |
| pSwitchChannel = (switchChannel_t*)pData; |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, " switchChannel_smNop\n"); |
| |
| return TI_OK; |
| } |
| |
| /** |
| * |
| * switchChannel_smUnexpected - Unexpected event |
| * |
| * \b Description: |
| * |
| * Unexpected event in the SM. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the SwitchChannel SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| static TI_STATUS switchChannel_smUnexpected(void *pData) |
| { |
| switchChannel_t *pSwitchChannel; |
| |
| pSwitchChannel = (switchChannel_t*)pData; |
| if (pSwitchChannel == NULL) |
| { |
| return TI_NOK; |
| } |
| TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, " switchChannel_smUnexpected, state = %d\n", pSwitchChannel->currentState); |
| |
| return TI_NOK; |
| } |
| |
| /******************************************************************************* |
| *********** Debug functions *********** |
| *******************************************************************************/ |
| #ifdef TI_DBG |
| |
| /************************************************************************ |
| * switchChannel_recvCmd * |
| ************************************************************************/ |
| /*DESCRIPTION: This function is called by MLME Parser upon receiving of |
| Beacon, Probe Response or Action with Switch Channel command, |
| or beacon/ |
| performs the following: |
| - Initializes the switching channel procedure. |
| - Setting timer to the actual switching time(if needed) |
| |
| INPUT: hSwitchChannel - SwitchChannel handle. |
| switchMode - indicates whether to stop transmission |
| until the scheduled channel switch. |
| newChannelNum - indicates the number of the new channel. |
| durationTime - indicates the time (expressed in ms) until |
| the scheduled channel switch should accure. |
| |
| OUTPUT: None |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| |
| ************************************************************************/ |
| |
| static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel) |
| { |
| |
| switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; |
| paramInfo_t param; |
| |
| if (pSwitchChannel==NULL) |
| { |
| return; |
| } |
| |
| |
| /* The following is for debug purposes only |
| It will be operated when the Switch Channel cmd is opertated from debug CLI */ |
| if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0) |
| { |
| if (pSwitchChannel->ignoreCancelSwitchChannelCmd == 1) |
| { |
| /* update the new SCC params */ |
| pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; |
| |
| pSwitchChannel->ignoreCancelSwitchChannelCmd = 2; |
| } |
| else if (channelSwitch->channelSwitchCount>0) |
| { |
| channelSwitch->channelSwitchCount --; |
| } |
| else |
| { |
| pSwitchChannel->ignoreCancelSwitchChannelCmd = 0; |
| } |
| |
| |
| /* search in the buffer pointer to the beginning of the |
| Switch Cahnnel Announcement IE according to the IE ID */ |
| |
| /* SC IE exists on the serving channel */ |
| TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n", channelSwitch->channelNumber, channelSwitch->channelSwitchMode, channelSwitch->channelSwitchCount); |
| |
| /* Checking channel number validity */ |
| param.content.channel = channelSwitch->channelNumber; |
| param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; |
| regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m); |
| if (( !param.content.bIsChannelSupprted ) || |
| (channelSwitch->channelSwitchCount == 0) || |
| (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)) |
| { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid, |
| or the TBTT count is 0 */ |
| apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL); |
| } |
| else |
| { /* Invoke Switch Channel command */ |
| /* update the new SCC params */ |
| pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; |
| pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; |
| switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel); |
| } |
| } |
| |
| } |
| |
| void switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel, SC_switchChannelCmdParam_e switchChannelCmdParam, TI_UINT8 param) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| |
| switch (switchChannelCmdParam) |
| { |
| case SC_SWITCH_CHANNEL_NUM: |
| WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelNum=%d \n ", param)); |
| pSwitchChannel->debugChannelSwitchCmdParams.channelNumber = param; |
| break; |
| case SC_SWITCH_CHANNEL_TBTT: |
| WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchCount=%d \n ", param)); |
| pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount = param; |
| break; |
| case SC_SWITCH_CHANNEL_MODE: |
| WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchMode=%d \n ", param)); |
| pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode = param; |
| break; |
| default: |
| WLAN_OS_REPORT(("ERROR: SwitchChannelDebug_setSwitchChannelCmdParams, wrong switchChannelCmdParam=%d \n ", |
| switchChannelCmdParam)); |
| break; |
| } |
| |
| } |
| void switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| |
| WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n cmd params: channelNumber=%d, channelSwitchCount=%d, channelSwitchMode=%d \n", |
| BeaconPacket, |
| pSwitchChannel->debugChannelSwitchCmdParams.channelNumber, |
| pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount, |
| pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode)); |
| |
| |
| pSwitchChannel->ignoreCancelSwitchChannelCmd= 1; |
| switchChannel_recvCmd4Debug(hSwitchChannel, &pSwitchChannel->debugChannelSwitchCmdParams, BeaconPacket, pSwitchChannel->currentChannel); |
| } |
| |
| void switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket) |
| { |
| |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| |
| WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n",BeaconPacket)); |
| |
| pSwitchChannel->ignoreCancelSwitchChannelCmd= 0; |
| switchChannel_recvCmd4Debug(hSwitchChannel, NULL, BeaconPacket, pSwitchChannel->currentChannel); |
| } |
| |
| |
| void switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel) |
| { |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| |
| WLAN_OS_REPORT(("SwitchChannel debug params are: channelNumber=%d, channelSwitchCount=%d , channelSwitchMode=%d \n", |
| pSwitchChannel->debugChannelSwitchCmdParams.channelNumber, |
| pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount, |
| pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode)); |
| |
| WLAN_OS_REPORT(("SwitchChannel state=%d, currentChannel=%d \n", pSwitchChannel->currentState, pSwitchChannel->currentChannel)); |
| |
| |
| } |
| |
| void switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel, TI_UINT8 channelNum, TI_BOOL validity) |
| { |
| paramInfo_t param; |
| |
| switchChannel_t *pSwitchChannel = (switchChannel_t*)hSwitchChannel; |
| |
| if (pSwitchChannel == NULL) |
| { |
| return; |
| } |
| |
| param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY; |
| param.content.channelValidity.channelNum = channelNum; |
| param.content.channelValidity.channelValidity = validity; |
| regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); |
| |
| } |
| |
| #endif /* TI_DBG */ |
| |
| |
| |
| |
| |
| |