| /* |
| * roamingMngr.c |
| * |
| * Copyright(c) 1998 - 2009 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 roamingMngr.c |
| * \brief Roaming Manager |
| * |
| * \see roamingMngrApi.h |
| */ |
| |
| /**************************************************************************** |
| * * |
| * MODULE: Roaming Manager * |
| * PURPOSE: * |
| * Roaming manager is responsible to receive Roaming triggers and try |
| * to select a better AP. |
| * The Roaming triggers are: Low RSSI, PER, consecutive No ACK on TX, |
| * beacon Missed or External request. |
| * In each Internal Roaming request, scan is performed and selection for |
| * better AP. Better AP is defined as a different AP with better RSSI, |
| * and similar SSID and security settings. |
| * If better AP is found, there is a check for fast-roaming via the |
| * Supplicant. Then connection to the new AP is invoked. |
| * * |
| ****************************************************************************/ |
| |
| #define __FILE_ID__ FILE_ID_8 |
| #include "osApi.h" |
| |
| #include "paramOut.h" |
| #include "report.h" |
| #include "fsm.h" |
| #include "GenSM.h" |
| #include "scanMngrApi.h" |
| #include "roamingMngrApi.h" |
| #include "apConnApi.h" |
| #include "roamingMngrTypes.h" |
| #include "bssTypes.h" |
| #include "DrvMainModules.h" |
| #include "TWDriver.h" |
| #include "siteMgrApi.h" |
| #include "roamingMngr_manualSM.h" |
| #include "roamingMngr_autoSM.h" |
| #include "currBss.h" |
| #include "currBssApi.h" |
| #include "EvHandler.h" |
| |
| /*-----------*/ |
| /* Constants */ |
| /*-----------*/ |
| |
| /* Init bits */ |
| #define ROAMING_MNGR_CONTEXT_INIT_BIT 1 |
| #define ROAMING_MNGR_SM_INIT_BIT 2 |
| |
| #define DEFAULT_AP_QUALITY (-70) |
| #define DEFAULT_LOW_PASS_FILTER (30) |
| #define DEFAULT_DATA_RETRY_THRESHOLD (20) |
| #define DEFAULT_LOW_QUALITY_SCAN_COND (-60) |
| #define DEFAULT_NORMAL_QUALITY_SCAN_COND (-50) |
| #define DEFAULT_LOW_RSSI (-70) |
| #define DEFAULT_LOW_SNR (0) |
| #define DEFAULT_TBTT_4_BSS_LOSS (10) |
| #define DEFAULT_LOW_TX_RATE (2) |
| |
| |
| /*--------------*/ |
| /* Enumerations */ |
| /*--------------*/ |
| |
| /*----------*/ |
| /* Typedefs */ |
| /*----------*/ |
| |
| /*------------*/ |
| /* Structures */ |
| /*------------*/ |
| |
| |
| /************** callback funtions called by AP Connection **************/ |
| /* called when a trigger for Roaming occurs */ |
| TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData, TI_UINT16 reasonCode); |
| /* called when CONN status event occurs */ |
| TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData); |
| /* called when Neighbor APs is updated */ |
| TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData); |
| |
| /* internal functions */ |
| static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, TI_UINT32 initVec); |
| |
| #ifdef TI_DBG |
| /* debug function */ |
| static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr); |
| static void roamingMngr_resetStatistics(TI_HANDLE hRoamingMngr); |
| #endif |
| |
| /** |
| * |
| * roamingMngr_releaseModule |
| * |
| * \b Description: |
| * |
| * Called by the un load function |
| * Go over the vector, for each bit that is set, release the corresponding module. |
| * |
| * \b ARGS: |
| * |
| * I - pRoamingMngr - Roaming Manager context \n |
| * I - initVec - indicates which modules should be released |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * \sa roamingMngr_create |
| */ |
| static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, TI_UINT32 initVec) |
| { |
| |
| if (pRoamingMngr==NULL) |
| { |
| return; |
| } |
| if (initVec & (1 << ROAMING_MNGR_SM_INIT_BIT)) |
| { |
| genSM_Unload(pRoamingMngr->hRoamingSm); |
| } |
| |
| if (initVec & (1 << ROAMING_MNGR_CONTEXT_INIT_BIT)) |
| { |
| os_memoryFree(pRoamingMngr->hOs, pRoamingMngr, sizeof(roamingMngr_t)); |
| } |
| |
| initVec = 0; |
| } |
| |
| /** |
| * |
| * roamingMngr_triggerRoamingCb |
| * |
| * \b Description: |
| * |
| * This procedure is called when Roaming should be triggered |
| * due to one of apConn_roamingTrigger_e Roaming Reasons. |
| * Save the trigger and process it only if there's no other Roaming trigger |
| * in process. |
| * |
| * \b ARGS: |
| * |
| * I - hRoamingMngr - roamingMngr SM context \n |
| * I - pData - pointer to roaming trigger |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData, TI_UINT16 reasonCode) |
| { |
| roamingMngr_t *pRoamingMngr; |
| apConn_roamingTrigger_e roamingTrigger; |
| TI_UINT32 curTimestamp; |
| TI_UINT16 disConnReasonCode; |
| |
| |
| pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| if ((pRoamingMngr == NULL) || (pData == NULL)) |
| { |
| return TI_NOK; |
| } |
| |
| roamingTrigger = *(apConn_roamingTrigger_e *)pData; |
| |
| if ((ROAMING_OPERATIONAL_MODE_MANUAL == pRoamingMngr->RoamingOperationalMode) && |
| (roamingTrigger == ROAMING_TRIGGER_AP_DISCONNECT)) |
| { |
| disConnReasonCode = reasonCode; |
| EvHandlerSendEvent(pRoamingMngr->hEvHandler, IPC_EVENT_AP_DISCONNECT, (TI_UINT8*)&disConnReasonCode, sizeof(disConnReasonCode)); |
| } |
| |
| |
| if (roamingTrigger >= ROAMING_TRIGGER_LAST) |
| { |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_triggerRoamingCb, bad roaming trigger = %d\n", roamingTrigger); |
| return TI_NOK; |
| } |
| #ifdef TI_DBG |
| /* save parameters for debug*/ |
| pRoamingMngr->roamingTriggerEvents[pRoamingMngr->roamingTrigger]++; |
| #endif |
| if (roamingTrigger <= ROAMING_TRIGGER_BG_SCAN_GROUP) |
| { |
| TI_BOOL lowQuality = TI_FALSE; |
| if (roamingTrigger == ROAMING_TRIGGER_LOW_QUALITY_FOR_BG_SCAN) |
| { |
| lowQuality = TI_TRUE; |
| } |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, lowQuality = %d \n", lowQuality); |
| scanMngr_qualityChangeTrigger(pRoamingMngr->hScanMngr, lowQuality); |
| } |
| else |
| { |
| if (roamingTrigger > pRoamingMngr->roamingTrigger) |
| { /* Save the highest priority roaming trigger */ |
| pRoamingMngr->roamingTrigger = roamingTrigger; |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, higher trigger = %d \n", roamingTrigger); |
| |
| } |
| |
| curTimestamp = os_timeStampMs(pRoamingMngr->hOs); |
| |
| /* If "No BSS" trigger received, disable count of low pass filter timer */ |
| if (roamingTrigger > ROAMING_TRIGGER_LOW_QUALITY_GROUP) |
| { |
| pRoamingMngr->lowQualityTriggerTimestamp = 0; |
| } |
| |
| /* Do not invoke a new Roaming Trigger when a previous one is in process */ |
| if (pRoamingMngr->maskRoamingEvents == TI_FALSE) |
| { /* No Roaming trigger is in process */ |
| /* If the trigger is low quality check the low pass filter */ |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, trigger = %d \n", roamingTrigger); |
| if (roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP) |
| { |
| TI_UINT32 deltaTs = curTimestamp-pRoamingMngr->lowQualityTriggerTimestamp; |
| |
| if ((pRoamingMngr->lowQualityTriggerTimestamp != 0) && |
| (deltaTs < pRoamingMngr->lowPassFilterRoamingAttemptInMsec)) |
| { /* Ignore the low quality events. till the low pass time elapses */ |
| TRACE5(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, trigger = %d Ignored!!,deltaTs=%d, curTimestamp = %d, lowQualityTriggerTimestamp = %d, lowPassFilterRoamingAttempt=%d\n", roamingTrigger, deltaTs, curTimestamp, pRoamingMngr->lowQualityTriggerTimestamp, pRoamingMngr->lowPassFilterRoamingAttemptInMsec); |
| return TI_OK; |
| } |
| pRoamingMngr->lowQualityTriggerTimestamp = curTimestamp; |
| } |
| |
| /* Mask all future roaming events */ |
| pRoamingMngr->maskRoamingEvents = TI_TRUE; |
| |
| #ifdef TI_DBG |
| /* For debug */ |
| pRoamingMngr->roamingTriggerTimestamp = curTimestamp; |
| #endif |
| return (roamingMngr_smEvent(ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr)); |
| } |
| else if (roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP) |
| { /* If the trigger is from the Full Connect group, then stop the connection. */ |
| return (roamingMngr_smEvent(ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr)); |
| |
| } |
| } |
| |
| return TI_OK; |
| } |
| |
| /** |
| * |
| * roamingMngr_connStatusCb |
| * |
| * \b Description: |
| * |
| * This procedure is called when the connection status event |
| * is triggered. |
| * |
| * \b ARGS: |
| * |
| * I - hRoamingMngr - roamingMngr SM context \n |
| * I - pData - pointer to the connection status. |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData) |
| { |
| roamingMngr_t *pRoamingMngr; |
| apConn_connStatus_e connStatus; |
| roamingMngr_smEvents roamingEvent; |
| |
| pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| if ((pRoamingMngr == NULL) || (pData == NULL)) |
| { |
| return TI_NOK; |
| } |
| |
| connStatus = ((apConn_connStatus_t *)pData)->status; |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_connStatusCb, conn status = %d\n", connStatus); |
| |
| if (!pRoamingMngr->roamingMngrConfig.enableDisable) |
| { |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connStatusCb, connStatus=%d was received while Roaming is disabled. Stop Roaming \n", connStatus); |
| return TI_NOK; |
| } |
| |
| if (ROAMING_OPERATIONAL_MODE_AUTO == pRoamingMngr->RoamingOperationalMode) |
| { |
| switch (connStatus) |
| { |
| case CONN_STATUS_CONNECTED: roamingEvent = ROAMING_EVENT_START; |
| /* Get station capabilities */ |
| apConn_getStaCapabilities(pRoamingMngr->hAPConnection, &pRoamingMngr->staCapabilities); |
| break; |
| case CONN_STATUS_NOT_CONNECTED: roamingEvent = ROAMING_EVENT_STOP; |
| break; |
| case CONN_STATUS_HANDOVER_SUCCESS: roamingEvent = ROAMING_EVENT_ROAM_SUCCESS; |
| #ifdef TI_DBG |
| /* For debug */ |
| pRoamingMngr->roamingSuccesfulHandoverNum++; |
| pRoamingMngr->roamingHandoverCompletedTimestamp = os_timeStampMs(pRoamingMngr->hOs); |
| pRoamingMngr->roamingAverageSuccHandoverDuration += os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingHandoverStartedTimestamp; |
| pRoamingMngr->roamingAverageRoamingDuration += os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingTriggerTimestamp; |
| pRoamingMngr->roamingHandoverEvents[pRoamingMngr->roamingTrigger]++; |
| #endif |
| break; |
| case CONN_STATUS_HANDOVER_FAILURE: roamingEvent = ROAMING_EVENT_REQ_HANDOVER; |
| #ifdef TI_DBG |
| /* For debug */ |
| pRoamingMngr->roamingFailedHandoverNum++; |
| #endif |
| break; |
| default: |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connStatusCb, bad connStatus = %d\n", connStatus); |
| return TI_NOK; |
| } |
| } |
| else /* Roaming Manual operational mode*/ |
| { |
| switch (connStatus) |
| { |
| case CONN_STATUS_CONNECTED: |
| roamingEvent = ROAMING_MANUAL_EVENT_START; |
| apConn_getStaCapabilities(pRoamingMngr->hAPConnection,&pRoamingMngr->staCapabilities); |
| break; |
| case CONN_STATUS_NOT_CONNECTED: |
| roamingEvent = ROAMING_MANUAL_EVENT_STOP; |
| break; |
| case CONN_STATUS_HANDOVER_SUCCESS: |
| roamingEvent = ROAMING_MANUAL_EVENT_SUCCESS; |
| break; |
| case CONN_STATUS_HANDOVER_FAILURE: |
| roamingEvent = ROAMING_MANUAL_EVENT_FAIL; |
| break; |
| default: |
| return TI_NOK; |
| } |
| } |
| |
| return (roamingMngr_smEvent(roamingEvent, pRoamingMngr)); |
| } |
| |
| /** |
| * |
| * roamingMngr_updateNeighborApListCb |
| * |
| * \b Description: |
| * |
| * This procedure is called when Neighbor AP list is received from the AP. |
| * Save the list, and set them in Scan Manager object. |
| * |
| * \b ARGS: |
| * |
| * I - hRoamingMngr - roamingMngr SM context \n |
| * I - pData - pointer to the list of Neighbor APs. |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData) |
| { |
| roamingMngr_t *pRoamingMngr; |
| neighborAPList_t *pNeighborAPList; |
| |
| pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| if ((pRoamingMngr == NULL) || (pData == NULL)) |
| { |
| return TI_NOK; |
| } |
| |
| pNeighborAPList = (neighborAPList_t *)pData; |
| if (pNeighborAPList->numOfEntries>0) |
| { |
| pRoamingMngr->neighborApsExist = TI_TRUE; |
| } |
| else |
| { |
| pRoamingMngr->neighborApsExist = TI_FALSE; |
| } |
| |
| if (pRoamingMngr->roamingMngrConfig.enableDisable) |
| { |
| scanMngr_setNeighborAPs (pRoamingMngr->hScanMngr, pNeighborAPList); |
| } |
| TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_updateNeighborApListCb, numberOfAps = %d, enableDisable=%d\n", pNeighborAPList->numOfEntries, pRoamingMngr->roamingMngrConfig.enableDisable); |
| |
| return TI_OK; |
| } |
| |
| /** |
| * |
| * roamingMngr_smEvent |
| * |
| * \b Description: |
| * |
| * Roaming Manager 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 |
| */ |
| TI_STATUS roamingMngr_smEvent(TI_UINT8 event, void* data) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)data; |
| |
| TRACE3(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smEvent(). Mode(%d) ,currentState = %d, event=%d \n", |
| pRoamingMngr->RoamingOperationalMode, |
| *(pRoamingMngr->pCurrentState), |
| event); |
| |
| genSM_Event (pRoamingMngr->hRoamingSm, (TI_UINT32)event, data); |
| |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smEvent(). new State : %d \n", *(pRoamingMngr->pCurrentState)); |
| |
| return TI_OK; |
| } |
| |
| |
| |
| #ifdef TI_DBG |
| /** |
| * |
| * roamingMngr_debugTrace |
| * |
| * \b Description: |
| * |
| * This procedure is called for debug only, to trace the roaming triggers and events |
| * |
| * \b ARGS: |
| * |
| * I - hRoamingMngr - roamingMngr SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr) |
| { |
| |
| |
| roamingMngr_t *pRoamingMngr; |
| TI_UINT8 index; |
| |
| pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| if (pRoamingMngr == NULL) |
| { |
| return; |
| } |
| |
| WLAN_OS_REPORT(("******** ROAMING_TRIGGERS ********\n")); |
| for (index=ROAMING_TRIGGER_LOW_TX_RATE; index<ROAMING_TRIGGER_LAST; index++) |
| { |
| switch (index) |
| { |
| case ROAMING_TRIGGER_LOW_TX_RATE: |
| WLAN_OS_REPORT(("- Low TX rate = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| case ROAMING_TRIGGER_LOW_SNR: |
| WLAN_OS_REPORT(("- Low Snr = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| case ROAMING_TRIGGER_LOW_QUALITY: |
| WLAN_OS_REPORT(("- Low Quality = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| case ROAMING_TRIGGER_MAX_TX_RETRIES: |
| WLAN_OS_REPORT(("- MAX TX retries = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| case ROAMING_TRIGGER_BSS_LOSS: |
| WLAN_OS_REPORT(("- BSS Loss TX = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| case ROAMING_TRIGGER_SWITCH_CHANNEL: |
| WLAN_OS_REPORT(("- Switch Channel = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| case ROAMING_TRIGGER_AP_DISCONNECT: |
| WLAN_OS_REPORT(("- AP Disconnect = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| case ROAMING_TRIGGER_SECURITY_ATTACK: |
| WLAN_OS_REPORT(("- SEC attack = %d\n", pRoamingMngr->roamingTriggerEvents[index])); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| WLAN_OS_REPORT(("******** Succ ROAMING_HANDOVERS ********\n")); |
| |
| for (index=ROAMING_TRIGGER_LOW_QUALITY; index<ROAMING_TRIGGER_LAST; index++) |
| { |
| switch (index) |
| { |
| case ROAMING_TRIGGER_LOW_TX_RATE: |
| WLAN_OS_REPORT(("- Low TX rate = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| case ROAMING_TRIGGER_LOW_SNR: |
| WLAN_OS_REPORT(("- Low Snre = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| case ROAMING_TRIGGER_LOW_QUALITY: |
| WLAN_OS_REPORT(("- Low Quality = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| case ROAMING_TRIGGER_MAX_TX_RETRIES: |
| WLAN_OS_REPORT(("- MAX TX retries = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| case ROAMING_TRIGGER_BSS_LOSS: |
| WLAN_OS_REPORT(("- BSS Loss TX = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| case ROAMING_TRIGGER_SWITCH_CHANNEL: |
| WLAN_OS_REPORT(("- Switch Channel = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| case ROAMING_TRIGGER_AP_DISCONNECT: |
| WLAN_OS_REPORT(("- AP Disconnect = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| case ROAMING_TRIGGER_SECURITY_ATTACK: |
| WLAN_OS_REPORT(("- SEC attack = %d\n", pRoamingMngr->roamingHandoverEvents[index])); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| WLAN_OS_REPORT(("******** ROAMING STATISTICS ********\n")); |
| WLAN_OS_REPORT(("- Num of succesful handovers = %d\n", pRoamingMngr->roamingSuccesfulHandoverNum)); |
| WLAN_OS_REPORT(("- Num of failed handovers = %d\n", pRoamingMngr->roamingFailedHandoverNum)); |
| if (pRoamingMngr->roamingSuccesfulHandoverNum >0) |
| { |
| WLAN_OS_REPORT(("- Succesful average succesful handover duration = %d\n", pRoamingMngr->roamingAverageSuccHandoverDuration/pRoamingMngr->roamingSuccesfulHandoverNum)); |
| WLAN_OS_REPORT(("- Succesful average roaming duration = %d\n", pRoamingMngr->roamingAverageRoamingDuration/pRoamingMngr->roamingSuccesfulHandoverNum)); |
| } |
| |
| |
| } |
| |
| |
| /** |
| * |
| * roamingMngr_resetDebugTrace |
| * |
| * \b Description: |
| * |
| * This procedure is called for debug only, to reset Roaming debug trace |
| * |
| * \b ARGS: |
| * |
| * I - hRoamingMngr - roamingMngr SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| static void roamingMngr_resetStatistics(TI_HANDLE hRoamingMngr) |
| { |
| |
| roamingMngr_t *pRoamingMngr; |
| TI_UINT8 index; |
| |
| pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| if (pRoamingMngr == NULL) |
| { |
| return; |
| } |
| WLAN_OS_REPORT(("Resetting all ROAMING_EVENTS \n")); |
| |
| pRoamingMngr->roamingSuccesfulHandoverNum = 0; |
| pRoamingMngr->roamingHandoverStartedTimestamp = 0; |
| pRoamingMngr->roamingHandoverCompletedTimestamp = 0; |
| pRoamingMngr->roamingAverageSuccHandoverDuration = 0; |
| pRoamingMngr->roamingAverageRoamingDuration = 0; |
| pRoamingMngr->roamingFailedHandoverNum = 0; |
| |
| for (index=ROAMING_TRIGGER_LOW_QUALITY; index<ROAMING_TRIGGER_LAST; index++) |
| { |
| pRoamingMngr->roamingHandoverEvents[index] = 0; |
| pRoamingMngr->roamingTriggerEvents[index] = 0; |
| } |
| } |
| |
| #endif /*TI_DBG*/ |
| |
| |
| |
| /********************************************************************** |
| ** External Function section ** |
| ***********************************************************************/ |
| extern TI_STATUS apConn_reportRoamingEvent(TI_HANDLE hAPConnection, |
| apConn_roamingTrigger_e roamingEventType, |
| void *roamingEventData); |
| |
| |
| |
| /********************************************************************** |
| ** API Function section ** |
| ***********************************************************************/ |
| |
| TI_HANDLE roamingMngr_create(TI_HANDLE hOs) |
| { |
| // TI_STATUS status = TI_OK; |
| roamingMngr_t *pRoamingMngr; |
| TI_UINT32 initVec; |
| |
| initVec = 0; |
| |
| pRoamingMngr = os_memoryAlloc(hOs, sizeof(roamingMngr_t)); |
| if (pRoamingMngr == NULL) |
| return NULL; |
| |
| initVec |= (1 << ROAMING_MNGR_CONTEXT_INIT_BIT); |
| pRoamingMngr->hOs = hOs; |
| |
| /* allocate the state machine object */ |
| pRoamingMngr->hRoamingSm = genSM_Create(hOs); |
| |
| if (pRoamingMngr->hRoamingSm == NULL) |
| { |
| roamingMngr_releaseModule(pRoamingMngr, initVec); |
| WLAN_OS_REPORT(("FATAL ERROR: roamingMngr_create(): Error Creating pRoamingSm - Aborting\n")); |
| return NULL; |
| } |
| initVec |= (1 << ROAMING_MNGR_SM_INIT_BIT); |
| |
| |
| return pRoamingMngr; |
| } |
| |
| TI_STATUS roamingMngr_unload(TI_HANDLE hRoamingMngr) |
| { |
| TI_UINT32 initVec; |
| |
| if (hRoamingMngr == NULL) |
| { |
| return TI_OK; |
| } |
| |
| initVec = 0xFFFF; |
| roamingMngr_releaseModule(hRoamingMngr, initVec); |
| |
| return TI_OK; |
| } |
| |
| void roamingMngr_init (TStadHandlesList *pStadHandles) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)(pStadHandles->hRoamingMngr); |
| |
| /* Update handlers */ |
| pRoamingMngr->hReport = pStadHandles->hReport; |
| pRoamingMngr->hScanMngr = pStadHandles->hScanMngr; |
| pRoamingMngr->hAPConnection = pStadHandles->hAPConnection; |
| pRoamingMngr->hTWD = pStadHandles->hTWD; |
| pRoamingMngr->hEvHandler = pStadHandles->hEvHandler; |
| pRoamingMngr->hCurrBss = pStadHandles->hCurrBss; |
| |
| genSM_Init(pRoamingMngr->hRoamingSm,pRoamingMngr->hReport); |
| } |
| |
| |
| TI_STATUS roamingMngr_setDefaults (TI_HANDLE hRoamingMngr, TRoamScanMngrInitParams *pInitParam) |
| { |
| |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| paramInfo_t param; |
| |
| #ifdef TI_DBG |
| TI_UINT8 index =0; |
| #endif |
| /* Init intrenal variables */ |
| //pRoamingMngr->currentState = ROAMING_STATE_IDLE; |
| pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED; |
| pRoamingMngr->roamingMngrConfig.apQualityThreshold = DEFAULT_AP_QUALITY; |
| pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt = DEFAULT_LOW_PASS_FILTER; |
| pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE; |
| pRoamingMngr->maskRoamingEvents= TI_TRUE; |
| pRoamingMngr->scanType = ROAMING_NO_SCAN; |
| pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX; |
| pRoamingMngr->handoverWasPerformed = TI_FALSE; |
| pRoamingMngr->lowQualityTriggerTimestamp = 0; |
| pRoamingMngr->neighborApsExist = TI_FALSE; |
| pRoamingMngr->pListOfAPs = NULL; |
| pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX; |
| pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0; |
| pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0; |
| pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0; |
| pRoamingMngr->RoamingOperationalMode = pInitParam->RoamingOperationalMode; |
| |
| if (pInitParam->RoamingScanning_2_4G_enable) |
| { |
| param.content.roamingConfigBuffer.roamingMngrConfig.enableDisable = ROAMING_ENABLED ; |
| param.content.roamingConfigBuffer.roamingMngrConfig.lowPassFilterRoamingAttempt = 30; |
| param.content.roamingConfigBuffer.roamingMngrConfig.apQualityThreshold = -70; |
| |
| param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.dataRetryThreshold = 20; |
| param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss = 10; |
| param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.txRateThreshold = 2; |
| param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowRssiThreshold = -80; |
| param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowSnrThreshold = 0; |
| param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition = -80; |
| param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition = -70; |
| |
| param.paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION; |
| param.paramLength = sizeof(roamingMngrConfigParams_t); |
| |
| roamingMngr_setParam(hRoamingMngr, ¶m); |
| |
| } |
| |
| |
| |
| /* config the FSM according to the operational mode*/ |
| if(ROAMING_OPERATIONAL_MODE_MANUAL==pRoamingMngr->RoamingOperationalMode) |
| { |
| genSM_SetDefaults(pRoamingMngr->hRoamingSm, |
| ROAMING_MANUAL_NUM_STATES, |
| ROAMING_MANUAL_NUM_EVENTS, |
| &roamingMngrManual_matrix[0][0], |
| ROAMING_MANUAL_STATE_IDLE, |
| "Roaming Manual SM", |
| ManualRoamStateDescription, |
| ManualRoamEventDescription, |
| __FILE_ID__); |
| |
| pRoamingMngr->RoamStateDescription = ManualRoamStateDescription; |
| pRoamingMngr->RoamEventDescription = ManualRoamEventDescription; |
| } |
| else |
| { |
| genSM_SetDefaults(pRoamingMngr->hRoamingSm, |
| ROAMING_MNGR_NUM_STATES, |
| ROAMING_MNGR_NUM_EVENTS, |
| &roamingMngrAuto_matrix[0][0], |
| ROAMING_STATE_IDLE, |
| "Roaming Auto SM", |
| AutoRoamStateDescription, |
| AutoRoamEventDescription, |
| __FILE_ID__); |
| |
| pRoamingMngr->RoamStateDescription = AutoRoamStateDescription; |
| pRoamingMngr->RoamEventDescription = AutoRoamEventDescription; |
| } |
| |
| pRoamingMngr->pCurrentState = &((TGenSM*)pRoamingMngr->hRoamingSm)->uCurrentState; |
| |
| #ifdef TI_DBG |
| /* debug counters */ |
| pRoamingMngr->roamingSuccesfulHandoverNum = 0; |
| pRoamingMngr->roamingHandoverStartedTimestamp = 0; |
| pRoamingMngr->roamingHandoverCompletedTimestamp = 0; |
| pRoamingMngr->roamingAverageSuccHandoverDuration = 0; |
| pRoamingMngr->roamingAverageRoamingDuration = 0; |
| pRoamingMngr->roamingFailedHandoverNum = 0; |
| |
| for (index=ROAMING_TRIGGER_NONE; index<ROAMING_TRIGGER_LAST; index++) |
| { |
| pRoamingMngr->roamingTriggerEvents[index] = 0; |
| pRoamingMngr->roamingHandoverEvents[index] = 0; |
| } |
| #endif |
| |
| return TI_OK; |
| } |
| |
| TI_STATUS roamingMngr_setParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| TI_STATUS status = TI_OK; |
| |
| if (pParam == NULL) |
| { |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR , "roamingMngr_setParam(): pParam is NULL!\n"); |
| return TI_NOK; |
| } |
| |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION , "roamingMngr_setParam %X \n", pParam->paramType); |
| |
| switch (pParam->paramType) |
| { |
| |
| case ROAMING_MNGR_APPLICATION_CONFIGURATION: |
| { |
| roamingMngrConfigParams_t *pRoamingMngrConfigParams; |
| |
| pRoamingMngrConfigParams = &pParam->content.roamingConfigBuffer; |
| |
| /* Configure the Roaming Parmeters */ |
| TRACE3(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam Configuration: \n enableDisable= %d,\n lowPassFilterRoamingAttempt=%d,\n apQualityThreshold=%d\n", pRoamingMngrConfigParams->roamingMngrConfig.enableDisable, pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt, pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold); |
| |
| pRoamingMngr->roamingMngrConfig.apQualityThreshold = pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold; |
| pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt; |
| pRoamingMngr->lowPassFilterRoamingAttemptInMsec = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt * 1000; |
| |
| /* Configure the Roaming Trigger thresholds */ |
| TRACE7(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam Thresholds: \n dataRetryThreshold= %d,\n lowQualityForBackgroungScanCondition=%d,\n lowRssiThreshold=%d,\n lowSNRThreshold=%d,\n normalQualityForBackgroungScanCondition=%d,\n numExpectedTbttForBSSLoss=%d,\n txRateThreshold=%d \n \n", pRoamingMngrConfigParams->roamingMngrThresholdsConfig.dataRetryThreshold, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowRssiThreshold, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowSnrThreshold, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.txRateThreshold); |
| |
| os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngr->roamingMngrThresholdsConfig, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t)); |
| |
| status = apConn_setRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig); |
| |
| if (pRoamingMngr->roamingMngrConfig.enableDisable && |
| !pRoamingMngrConfigParams->roamingMngrConfig.enableDisable) |
| { /* disable Roaming Manager */ |
| apConn_unregisterRoamMngrCallb(pRoamingMngr->hAPConnection); |
| pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED; |
| return (roamingMngr_smEvent(ROAMING_EVENT_STOP, pRoamingMngr)); |
| } |
| else if (!pRoamingMngr->roamingMngrConfig.enableDisable && |
| pRoamingMngrConfigParams->roamingMngrConfig.enableDisable) |
| { /* enable Roaming Manager */ |
| /* Save the Roaming Configuration parameters */ |
| pRoamingMngr->roamingMngrConfig.enableDisable = pRoamingMngrConfigParams->roamingMngrConfig.enableDisable; |
| /* register Roaming callback */ |
| apConn_registerRoamMngrCallb(pRoamingMngr->hAPConnection, |
| roamingMngr_triggerRoamingCb, |
| roamingMngr_connStatusCb, |
| roamingMngr_updateNeighborApListCb); |
| } |
| } |
| break; |
| |
| |
| /*********** For Debug Purposes ***********/ |
| |
| case ROAMING_MNGR_TRIGGER_EVENT: |
| /* Enable/disable Internal Roaming */ |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam TRIGGER_EVENT= %d \n", pParam->content.roamingTriggerType); |
| apConn_reportRoamingEvent(pRoamingMngr->hAPConnection, (apConn_roamingTrigger_e)pParam->content.roamingTriggerType, NULL); |
| break; |
| |
| case ROAMING_MNGR_CONN_STATUS: |
| /* External request to connect to BBSID */ |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam CONN_STATUS= %d \n", pParam->content.roamingConnStatus); |
| roamingMngr_connStatusCb(pRoamingMngr, &pParam->content.roamingConnStatus); |
| break; |
| |
| default: |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_setParam bad param= %X\n", pParam->paramType); |
| |
| break; |
| } |
| |
| |
| return status; |
| } |
| |
| TI_STATUS roamingMngr_getParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| |
| if (pParam == NULL) |
| { |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR , "roamingMngr_getParam(): pParam is NULL!\n"); |
| return TI_NOK; |
| } |
| |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_getParam %X \n", pParam->paramType); |
| |
| switch (pParam->paramType) |
| { |
| case ROAMING_MNGR_APPLICATION_CONFIGURATION: |
| { |
| roamingMngrConfigParams_t *pRoamingMngrConfigParams; |
| |
| pRoamingMngrConfigParams = &pParam->content.roamingConfigBuffer; |
| |
| if (pRoamingMngr->roamingMngrConfig.enableDisable == ROAMING_DISABLED) |
| { |
| pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = TI_FALSE; |
| } |
| else |
| { |
| pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = TI_TRUE; |
| } |
| pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold = pRoamingMngr->roamingMngrConfig.apQualityThreshold; |
| pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt; |
| |
| apConn_getRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngr->roamingMngrThresholdsConfig); |
| os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, &pRoamingMngr->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t)); |
| pParam->paramLength = sizeof(roamingMngrConfigParams_t); |
| } |
| break; |
| |
| #ifdef TI_DBG |
| case ROAMING_MNGR_PRINT_STATISTICS: |
| roamingMngr_printStatistics(pRoamingMngr); |
| break; |
| |
| case ROAMING_MNGR_RESET_STATISTICS: |
| roamingMngr_resetStatistics(pRoamingMngr); |
| break; |
| |
| case ROAMING_MNGR_PRINT_CURRENT_STATUS: |
| WLAN_OS_REPORT(("Roaming Current State = %d, enableDisable=%d\n, maskRoamingEvents = %d, roamingTrigger=%d \n scanType=%d, handoverWasPerformed=%d \n, candidateApIndex=%d, lowQualityTriggerTimestamp=%d \n", |
| *(pRoamingMngr->pCurrentState), |
| pRoamingMngr->roamingMngrConfig.enableDisable, |
| pRoamingMngr->maskRoamingEvents, |
| pRoamingMngr->roamingTrigger, |
| pRoamingMngr->scanType, |
| pRoamingMngr->handoverWasPerformed, |
| pRoamingMngr->candidateApIndex, |
| pRoamingMngr->lowQualityTriggerTimestamp)); |
| break; |
| case ROAMING_MNGR_PRINT_CANDIDATE_TABLE: |
| { |
| TI_UINT32 index; |
| |
| if (pRoamingMngr->pListOfAPs==NULL) |
| { |
| TRACE0( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr the candidate AP list is invalid \n"); |
| break; |
| } |
| TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "The number of candidates is %d\n", pRoamingMngr->pListOfAPs->numOfEntries); |
| |
| TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr Neighbor AP list, num of candidates = %d\n", pRoamingMngr->listOfCandidateAps.numOfNeighborBSS); |
| |
| for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfNeighborBSS; index++) |
| { |
| TI_UINT32 candidateIndex; |
| bssEntry_t *pBssEntry; |
| |
| candidateIndex = pRoamingMngr->listOfCandidateAps.neighborBSSList[index]; |
| pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex]; |
| TRACE8( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n", candidateIndex, pBssEntry->BSSID[0], pBssEntry->BSSID[1], pBssEntry->BSSID[2], pBssEntry->BSSID[3], pBssEntry->BSSID[4], pBssEntry->BSSID[5], pBssEntry->RSSI); |
| } |
| TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr Pre-Auth AP list, num of candidates = %d\n", pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS); |
| |
| for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS; index++) |
| { |
| TI_UINT32 candidateIndex; |
| bssEntry_t *pBssEntry; |
| |
| candidateIndex = pRoamingMngr->listOfCandidateAps.preAuthBSSList[index]; |
| pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex]; |
| TRACE8( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n", candidateIndex, pBssEntry->BSSID[0], pBssEntry->BSSID[1], pBssEntry->BSSID[2], pBssEntry->BSSID[3], pBssEntry->BSSID[4], pBssEntry->BSSID[5], pBssEntry->RSSI); |
| } |
| TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr Regular AP list, num of candidates = %d\n", pRoamingMngr->listOfCandidateAps.numOfRegularBSS); |
| |
| for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfRegularBSS; index++) |
| { |
| TI_UINT32 candidateIndex; |
| bssEntry_t *pBssEntry; |
| |
| candidateIndex = pRoamingMngr->listOfCandidateAps.regularBSSList[index]; |
| pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex]; |
| TRACE8( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n", candidateIndex, pBssEntry->BSSID[0], pBssEntry->BSSID[1], pBssEntry->BSSID[2], pBssEntry->BSSID[3], pBssEntry->BSSID[4], pBssEntry->BSSID[5], pBssEntry->RSSI); |
| } |
| } |
| break; |
| |
| #endif /*TI_DBG*/ |
| |
| default: |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_getParam bad paramType= %X \n", pParam->paramType); |
| return TI_NOK; |
| } |
| |
| return TI_OK; |
| } |
| |
| TI_STATUS roamingMngr_immediateScanComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus) |
| { |
| roamingMngr_t *pRoamingMngr; |
| roamingMngr_smEvents roamingEvent; |
| |
| |
| pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| if (pRoamingMngr == NULL) |
| { |
| return TI_NOK; |
| } |
| |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_immediateScanComplete, scanCmpltStatus = %d\n", scanCmpltStatus); |
| |
| if (scanCmpltStatus == SCAN_MRS_SCAN_COMPLETE_OK) |
| { |
| /* The scan completed TI_OK, get the updated list of APs */ |
| pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr); |
| if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0)) |
| { |
| /* APs were found, start selection */ |
| pRoamingMngr->scanType = ROAMING_NO_SCAN; |
| roamingEvent = ROAMING_EVENT_SELECT; |
| } |
| else |
| { /* There were no APs, if the scan was partial, retry full scan */ |
| if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) || |
| (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY)) |
| { |
| pRoamingMngr->scanType = ROAMING_FULL_SCAN; |
| roamingEvent = ROAMING_EVENT_SCAN; |
| } |
| else |
| { |
| /* No APs were found in FULL SCAN, report failure */ |
| roamingEvent = ROAMING_EVENT_SELECT; |
| } |
| } |
| } |
| /* scanCmpltStatus != SCAN_MRS_SCAN_COMPLETE_OK */ |
| else |
| { |
| /* The scan failed, retry scanning according to the current scan type */ |
| pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr); |
| if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0)) |
| { |
| /* APs were found, start selection */ |
| pRoamingMngr->scanType = ROAMING_NO_SCAN; |
| roamingEvent = ROAMING_EVENT_SELECT; |
| } |
| else |
| { |
| /* The scan failed, and there were no APs found. |
| Retry scanning according to the current scan type */ |
| switch (pRoamingMngr->scanType) |
| { |
| case ROAMING_PARTIAL_SCAN: |
| roamingEvent = ROAMING_EVENT_SCAN; |
| pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN_RETRY; |
| break; |
| case ROAMING_PARTIAL_SCAN_RETRY: |
| roamingEvent = ROAMING_EVENT_SELECT; |
| pRoamingMngr->scanType = ROAMING_NO_SCAN; |
| break; |
| case ROAMING_FULL_SCAN: |
| roamingEvent = ROAMING_EVENT_SCAN; |
| pRoamingMngr->scanType = ROAMING_FULL_SCAN_RETRY; |
| break; |
| case ROAMING_FULL_SCAN_RETRY: |
| roamingEvent = ROAMING_EVENT_SELECT; |
| pRoamingMngr->scanType = ROAMING_NO_SCAN; |
| break; |
| default: |
| roamingEvent = ROAMING_EVENT_SELECT; |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_immediateScanComplete, pRoamingMngr->scanType = %d\n", pRoamingMngr->scanType); |
| pRoamingMngr->scanType = ROAMING_NO_SCAN; |
| break; |
| } /* switch (pRoamingMngr->scanType) */ |
| } |
| } |
| |
| TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_immediateScanComplete, roamingEvent = %d, scanType=%d\n", roamingEvent, pRoamingMngr->scanType); |
| |
| return (roamingMngr_smEvent(roamingEvent, pRoamingMngr)); |
| |
| } |
| |
| TI_STATUS roamingMngr_updateNewBssList(TI_HANDLE hRoamingMngr, bssList_t *bssList) |
| { |
| |
| roamingMngr_t *pRoamingMngr; |
| |
| pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| if ((pRoamingMngr == NULL) || (bssList == NULL)) |
| { |
| return TI_NOK; |
| } |
| |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_updateNewBssList, number of APs = %d\n", bssList->numOfEntries); |
| |
| if (*(pRoamingMngr->pCurrentState) != ROAMING_STATE_WAIT_4_TRIGGER) |
| { |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_WARNING, "roamingMngr_updateNewBssList, ignore APs when not in WAIT_4_TRIGGER state \n"); |
| return TI_NOK; |
| } |
| |
| |
| if (pRoamingMngr->staCapabilities.authMode!=os802_11AuthModeWPA2) |
| { /* No Pre-Auth is required */ |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_updateNewBssList, No Pre-Auth is required\n"); |
| return TI_OK; |
| } |
| apConn_preAuthenticate(pRoamingMngr->hAPConnection, bssList); |
| |
| return TI_OK; |
| |
| } |
| |
| |
| void roamingMngr_smNop(void *pData) |
| { |
| roamingMngr_t *pRoamingMngr; |
| |
| pRoamingMngr = (roamingMngr_t*)pData; |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, " roamingMngr_smNop\n"); |
| } |
| |
| |
| void roamingMngr_smUnexpected(void *pData) |
| { |
| roamingMngr_t *pRoamingMngr; |
| |
| pRoamingMngr = (roamingMngr_t*)pData; |
| TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, " roamingMngr_smUnexpected, state = %d\n", *(pRoamingMngr->pCurrentState)); |
| } |
| |
| |
| void roamingMngr_smStop(void *pData) |
| { |
| roamingMngr_t *pRoamingMngr; |
| |
| pRoamingMngr = (roamingMngr_t*)pData; |
| |
| scanMngr_stopContScan(pRoamingMngr->hScanMngr); |
| /* clean intenal variables */ |
| pRoamingMngr->maskRoamingEvents = TI_TRUE; |
| pRoamingMngr->neighborApsExist = TI_FALSE; |
| pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE; |
| } |
| /** |
| * |
| * roamingMngr_smStopWhileScanning - |
| * |
| * \b Description: |
| * |
| * Stop event means that the station is not in Connected State. |
| * Stop continuos and immediate scans and clean internal vars. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to the roamingMngr SM context \n |
| * |
| * \b RETURNS: |
| * |
| * TI_OK if successful, TI_NOK otherwise. |
| * |
| * |
| */ |
| void roamingMngr_smStopWhileScanning(void *pData) |
| { |
| roamingMngr_t* pRoamingMngr; |
| |
| pRoamingMngr = (roamingMngr_t*)pData; |
| |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, " roamingMngr_smStopWhileScanning\n"); |
| |
| scanMngr_stopImmediateScan(pRoamingMngr->hScanMngr); |
| scanMngr_stopContScan(pRoamingMngr->hScanMngr); |
| |
| /* clean intenal variables */ |
| pRoamingMngr->maskRoamingEvents = TI_TRUE; |
| pRoamingMngr->neighborApsExist = TI_FALSE; |
| pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE; |
| } |
| |
| |
| |
| |
| /** |
| * |
| * roamingMngr_setBssLossThreshold API |
| * |
| * Description: |
| * |
| * Set the BSS Loss threshold by EMP and register for the event. |
| * |
| * ARGS: |
| * |
| * hRoamingMngr - Roaming manager handle \n |
| * uNumOfBeacons - number of consecutive beacons not received allowed before BssLoss event is issued |
| * uClientID - the ID of the client that has registered for this event. will be sent along with the BssLoss event to EMP |
| * \b RETURNS: |
| * |
| * TI_STATUS - registration status. |
| * TI_NOK - registration is not allowed |
| * |
| * \sa |
| */ |
| TI_STATUS roamingMngr_setBssLossThreshold (TI_HANDLE hRoamingMngr, TI_UINT32 uNumOfBeacons, TI_UINT16 uClientID) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setBssLossThreshold! \n"); |
| |
| if(ROAMING_OPERATIONAL_MODE_MANUAL == pRoamingMngr->RoamingOperationalMode) |
| { |
| return currBss_registerBssLossEvent(pRoamingMngr->hCurrBss, uNumOfBeacons, uClientID); |
| } |
| else |
| { |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_setBssLossThreshold is available only in auto mode! \n"); |
| WLAN_OS_REPORT(("\n roamingMngr_setBssLossThreshold is available only in auto mode! \n ")); |
| return TI_NOK; |
| } |
| } |
| |
| |
| |
| /** |
| * |
| * roamingMngr_Connect API |
| * |
| * Description: |
| * |
| * send the Connect event to roaming state machine |
| * |
| * ARGS: |
| * |
| * hRoamingMngr - Roaming manager handle \n |
| * pTargetAp - the target AP to connect with info. |
| * \b RETURNS: |
| * |
| * TI_STATUS - roamingMngr_smEvent status. |
| */ |
| |
| TI_STATUS roamingMngr_connect(TI_HANDLE hRoamingMngr, TargetAp_t* pTargetAp) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| bssList_t *bssList; |
| int i=0; |
| |
| TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_connect()," |
| "transitionMethod = %d," |
| "requestType = %d," |
| " \n", pTargetAp->transitionMethod,pTargetAp->connRequest.requestType) ; |
| |
| |
| TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connect()," |
| " AP to roam BSSID: " |
| "%02x-%02x-%02x-%02x-%02x-%02x " |
| "\n", pTargetAp->newAP.BSSID[0],pTargetAp->newAP.BSSID[1],pTargetAp->newAP.BSSID[2],pTargetAp->newAP.BSSID[3],pTargetAp->newAP.BSSID[4],pTargetAp->newAP.BSSID[5]); |
| |
| |
| /* Search for target AP in the scan manager results table, to get its beacon/ProbResponse buffer */ |
| bssList = scanMngr_getBSSList(((roamingMngr_t*)hRoamingMngr)->hScanMngr); |
| for (i=0; i< bssList->numOfEntries ; i++) |
| { |
| if (MAC_EQUAL(bssList->BSSList[i].BSSID, pTargetAp->newAP.BSSID)) |
| { |
| pTargetAp->newAP.pBuffer = bssList->BSSList[i].pBuffer; |
| pTargetAp->newAP.bufferLength = bssList->BSSList[i].bufferLength; |
| os_memoryCopy(pRoamingMngr->hOs, &(pRoamingMngr->targetAP), (void*)pTargetAp, sizeof(TargetAp_t)); |
| return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_CONNECT, hRoamingMngr); |
| } |
| } |
| |
| TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connect()," |
| "AP was not found in scan table!! BSSID: " |
| "%02x-%02x-%02x-%02x-%02x-%02x " |
| "\n", pTargetAp->newAP.BSSID[0],pTargetAp->newAP.BSSID[1],pTargetAp->newAP.BSSID[2],pTargetAp->newAP.BSSID[3],pTargetAp->newAP.BSSID[4],pTargetAp->newAP.BSSID[5]); |
| return TI_NOK; |
| } |
| |
| /** |
| * |
| * roamingMngr_startImmediateScan API |
| * |
| * Description: |
| * |
| * start the immediate scan with the channel list received by the application |
| * |
| * ARGS: |
| * |
| * hRoamingMngr - Roaming manager handle \n |
| * pChannelList - The channel list to be scanned |
| * \b RETURNS: |
| * |
| * TI_STATUS - roamingMngr_smEvent status. |
| */ |
| |
| TI_STATUS roamingMngr_startImmediateScan(TI_HANDLE hRoamingMngr, channelList_t* pChannelList) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| |
| TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_startImmediateScan().\n"); |
| |
| /* Save the channelList for later usage in the scanMngr_startImmediateScan() */ |
| scanMngr_setManualScanChannelList (pRoamingMngr-> hScanMngr, pChannelList); |
| return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_SCAN, hRoamingMngr); |
| } |
| |
| |
| |
| /** |
| * |
| * roamingMngr_stopImmediateScan API |
| * |
| * Description: |
| * |
| * stop the immediate scan, called by the application. |
| * |
| * ARGS: |
| * |
| * hRoamingMngr - Roaming manager handle \n |
| * \b RETURNS: |
| * |
| * TI_STATUS - TI_OK. |
| */ |
| TI_STATUS roamingMngr_stopImmediateScan(TI_HANDLE hRoamingMngr) |
| { |
| roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr; |
| scanMngr_stopImmediateScan(pRoamingMngr->hScanMngr); |
| |
| return TI_OK; |
| } |
| |
| |
| /** |
| * |
| * roamingMngr_stopImmediateScan API |
| * |
| * Description: |
| * |
| * called upon the immediate scan by application complete |
| * |
| * ARGS: |
| * |
| * hRoamingMngr - Roaming manager handle |
| * scanCmpltStatus - scanCmpltStatus |
| * |
| * \b RETURNS: |
| * |
| * TI_STATUS - State machine event status. |
| */ |
| |
| TI_STATUS roamingMngr_immediateScanByAppComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus) |
| { |
| return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_COMPLETE, hRoamingMngr); |
| } |
| |