Home | History | Annotate | Download | only in Application
      1 /*
      2  * roamingMngr.c
      3  *
      4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  *  * Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *  * Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in
     15  *    the documentation and/or other materials provided with the
     16  *    distribution.
     17  *  * Neither the name Texas Instruments nor the names of its
     18  *    contributors may be used to endorse or promote products derived
     19  *    from this software without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 /** \file roamingMngr.c
     35  *  \brief Roaming Manager
     36  *
     37  *  \see roamingMngrApi.h
     38  */
     39 
     40 /****************************************************************************
     41  *                                                                          *
     42  *   MODULE:  Roaming Manager                                               *
     43  *   PURPOSE:                                                               *
     44  *   Roaming manager is responsible to receive Roaming triggers and try
     45  *      to select a better AP.
     46  *      The Roaming triggers are: Low RSSI, PER, consecutive No ACK on TX,
     47  *      beacon Missed or External request.
     48  *      In each Internal Roaming request, scan is performed and selection for
     49  *      better AP. Better AP is defined as a different AP with better RSSI,
     50  *      and similar SSID and security settings.
     51  *      If better AP is found, there is a check for fast-roaming via the
     52  *      Supplicant. Then connection to the new AP is invoked.
     53  *                                                                          *
     54  ****************************************************************************/
     55 
     56 #define __FILE_ID__  FILE_ID_8
     57 #include "osApi.h"
     58 
     59 #include "paramOut.h"
     60 #include "report.h"
     61 #include "fsm.h"
     62 #include "GenSM.h"
     63 #include "scanMngrApi.h"
     64 #include "roamingMngrApi.h"
     65 #include "apConnApi.h"
     66 #include "roamingMngrTypes.h"
     67 #include "bssTypes.h"
     68 #include "DrvMainModules.h"
     69 #include "TWDriver.h"
     70 #include "siteMgrApi.h"
     71 #include "roamingMngr_manualSM.h"
     72 #include "roamingMngr_autoSM.h"
     73 #include "currBss.h"
     74 #include "currBssApi.h"
     75 #include "EvHandler.h"
     76 
     77 /*-----------*/
     78 /* Constants */
     79 /*-----------*/
     80 
     81 /* Init bits */
     82 #define ROAMING_MNGR_CONTEXT_INIT_BIT       1
     83 #define ROAMING_MNGR_SM_INIT_BIT            2
     84 
     85 #define DEFAULT_AP_QUALITY                  (-70)
     86 #define DEFAULT_LOW_PASS_FILTER             (30)
     87 #define DEFAULT_DATA_RETRY_THRESHOLD        (20)
     88 #define DEFAULT_LOW_QUALITY_SCAN_COND       (-60)
     89 #define DEFAULT_NORMAL_QUALITY_SCAN_COND    (-50)
     90 #define DEFAULT_LOW_RSSI                    (-70)
     91 #define DEFAULT_LOW_SNR                     (0)
     92 #define DEFAULT_TBTT_4_BSS_LOSS             (10)
     93 #define DEFAULT_LOW_TX_RATE                 (2)
     94 
     95 
     96 /*--------------*/
     97 /* Enumerations */
     98 /*--------------*/
     99 
    100 /*----------*/
    101 /* Typedefs */
    102 /*----------*/
    103 
    104 /*------------*/
    105 /* Structures */
    106 /*------------*/
    107 
    108 
    109 /************** callback funtions called by AP Connection **************/
    110 /* called when a trigger for Roaming occurs */
    111 TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData, TI_UINT16 reasonCode);
    112 /* called when CONN status event occurs */
    113 TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData);
    114 /* called when Neighbor APs is updated */
    115 TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData);
    116 
    117 /* internal functions */
    118 static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, TI_UINT32 initVec);
    119 
    120 #ifdef TI_DBG
    121 /* debug function */
    122 static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr);
    123 static void roamingMngr_resetStatistics(TI_HANDLE hRoamingMngr);
    124 #endif
    125 
    126 /**
    127 *
    128 * roamingMngr_releaseModule
    129 *
    130 * \b Description:
    131 *
    132 * Called by the un load function
    133 * Go over the vector, for each bit that is set, release the corresponding module.
    134 *
    135 * \b ARGS:
    136 *
    137 *  I   - pRoamingMngr - Roaming Manager context  \n
    138 *  I   - initVec - indicates which modules should be released
    139 *
    140 * \b RETURNS:
    141 *
    142 *  TI_OK if successful, TI_NOK otherwise.
    143 *
    144 * \sa roamingMngr_create
    145 */
    146 static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, TI_UINT32 initVec)
    147 {
    148 
    149     if (pRoamingMngr==NULL)
    150     {
    151         return;
    152     }
    153     if (initVec & (1 << ROAMING_MNGR_SM_INIT_BIT))
    154     {
    155         genSM_Unload(pRoamingMngr->hRoamingSm);
    156     }
    157 
    158     if (initVec & (1 << ROAMING_MNGR_CONTEXT_INIT_BIT))
    159     {
    160         os_memoryFree(pRoamingMngr->hOs, pRoamingMngr, sizeof(roamingMngr_t));
    161     }
    162 
    163     initVec = 0;
    164 }
    165 
    166 /**
    167 *
    168 * roamingMngr_triggerRoamingCb
    169 *
    170 * \b Description:
    171 *
    172 * This procedure is called when Roaming should be triggered
    173  * due to one of apConn_roamingTrigger_e Roaming Reasons.
    174  * Save the trigger and process it only if there's no other Roaming trigger
    175  * in process.
    176 *
    177 * \b ARGS:
    178 *
    179 *  I   - hRoamingMngr - roamingMngr SM context  \n
    180 *  I   - pData - pointer to roaming trigger
    181 *
    182 * \b RETURNS:
    183 *
    184 *  TI_OK if successful, TI_NOK otherwise.
    185 *
    186 *
    187 */
    188 TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData, TI_UINT16 reasonCode)
    189 {
    190     roamingMngr_t       *pRoamingMngr;
    191     apConn_roamingTrigger_e     roamingTrigger;
    192     TI_UINT32                   curTimestamp;
    193     TI_UINT16                   disConnReasonCode;
    194 
    195 
    196     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    197     if ((pRoamingMngr == NULL) || (pData == NULL))
    198     {
    199         return TI_NOK;
    200     }
    201 
    202     roamingTrigger = *(apConn_roamingTrigger_e *)pData;
    203 
    204     if ((ROAMING_OPERATIONAL_MODE_MANUAL == pRoamingMngr->RoamingOperationalMode) &&
    205         (roamingTrigger == ROAMING_TRIGGER_AP_DISCONNECT))
    206     {
    207         disConnReasonCode = reasonCode;
    208         EvHandlerSendEvent(pRoamingMngr->hEvHandler, IPC_EVENT_AP_DISCONNECT, (TI_UINT8*)&disConnReasonCode, sizeof(disConnReasonCode));
    209     }
    210 
    211 
    212     if (roamingTrigger >= ROAMING_TRIGGER_LAST)
    213     {
    214         TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_triggerRoamingCb, bad roaming trigger = %d\n", roamingTrigger);
    215         return TI_NOK;
    216     }
    217 #ifdef TI_DBG
    218     /* save parameters for debug*/
    219     pRoamingMngr->roamingTriggerEvents[pRoamingMngr->roamingTrigger]++;
    220 #endif
    221     if (roamingTrigger <= ROAMING_TRIGGER_BG_SCAN_GROUP)
    222     {
    223         TI_BOOL    lowQuality = TI_FALSE;
    224         if (roamingTrigger == ROAMING_TRIGGER_LOW_QUALITY_FOR_BG_SCAN)
    225         {
    226             lowQuality = TI_TRUE;
    227         }
    228         TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, lowQuality = %d \n", lowQuality);
    229         scanMngr_qualityChangeTrigger(pRoamingMngr->hScanMngr, lowQuality);
    230     }
    231     else
    232     {
    233         if (roamingTrigger > pRoamingMngr->roamingTrigger)
    234         {   /* Save the highest priority roaming trigger */
    235             pRoamingMngr->roamingTrigger = roamingTrigger;
    236             TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, higher trigger = %d \n", roamingTrigger);
    237 
    238         }
    239 
    240         curTimestamp = os_timeStampMs(pRoamingMngr->hOs);
    241 
    242         /* If "No BSS" trigger received, disable count of low pass filter timer */
    243         if (roamingTrigger > ROAMING_TRIGGER_LOW_QUALITY_GROUP)
    244         {
    245             pRoamingMngr->lowQualityTriggerTimestamp = 0;
    246         }
    247 
    248         /* Do not invoke a new Roaming Trigger when a previous one is in process */
    249         if (pRoamingMngr->maskRoamingEvents == TI_FALSE)
    250         {   /* No Roaming trigger is in process */
    251             /* If the trigger is low quality check the low pass filter */
    252             TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, trigger = %d \n", roamingTrigger);
    253             if (roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP)
    254             {
    255                 TI_UINT32 deltaTs = curTimestamp-pRoamingMngr->lowQualityTriggerTimestamp;
    256 
    257                 if ((pRoamingMngr->lowQualityTriggerTimestamp != 0) &&
    258                     (deltaTs < pRoamingMngr->lowPassFilterRoamingAttemptInMsec))
    259                 {  /* Ignore the low quality events. till the low pass time elapses */
    260                     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);
    261                     return TI_OK;
    262                 }
    263                 pRoamingMngr->lowQualityTriggerTimestamp = curTimestamp;
    264             }
    265 
    266             /* Mask all future roaming events */
    267             pRoamingMngr->maskRoamingEvents = TI_TRUE;
    268 
    269 #ifdef TI_DBG
    270             /* For debug */
    271             pRoamingMngr->roamingTriggerTimestamp = curTimestamp;
    272 #endif
    273             return (roamingMngr_smEvent(ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));
    274         }
    275         else if (roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
    276         {   /* If the trigger is from the Full Connect group, then stop the connection. */
    277             return (roamingMngr_smEvent(ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));
    278 
    279         }
    280     }
    281 
    282     return TI_OK;
    283 }
    284 
    285 /**
    286 *
    287 * roamingMngr_connStatusCb
    288 *
    289 * \b Description:
    290 *
    291 * This procedure is called when the connection status event
    292  * is triggered.
    293 *
    294 * \b ARGS:
    295 *
    296 *  I   - hRoamingMngr - roamingMngr SM context  \n
    297 *  I   - pData - pointer to the connection status.
    298 *
    299 * \b RETURNS:
    300 *
    301 *  TI_OK if successful, TI_NOK otherwise.
    302 *
    303 *
    304 */
    305 TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData)
    306 {
    307     roamingMngr_t               *pRoamingMngr;
    308     apConn_connStatus_e         connStatus;
    309     roamingMngr_smEvents        roamingEvent;
    310 
    311     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    312     if ((pRoamingMngr == NULL) || (pData == NULL))
    313     {
    314         return TI_NOK;
    315     }
    316 
    317     connStatus = ((apConn_connStatus_t *)pData)->status;
    318     TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_connStatusCb, conn status = %d\n", connStatus);
    319 
    320     if (!pRoamingMngr->roamingMngrConfig.enableDisable)
    321     {
    322         TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connStatusCb, connStatus=%d was received while Roaming is disabled. Stop Roaming \n", 						   connStatus);
    323         return TI_NOK;
    324     }
    325 
    326     if (ROAMING_OPERATIONAL_MODE_AUTO == pRoamingMngr->RoamingOperationalMode)
    327     {
    328         switch (connStatus)
    329         {
    330         case CONN_STATUS_CONNECTED: roamingEvent = ROAMING_EVENT_START;
    331             /* Get station capabilities */
    332             apConn_getStaCapabilities(pRoamingMngr->hAPConnection, &pRoamingMngr->staCapabilities);
    333             break;
    334         case CONN_STATUS_NOT_CONNECTED: roamingEvent = ROAMING_EVENT_STOP;
    335             break;
    336         case CONN_STATUS_HANDOVER_SUCCESS: roamingEvent = ROAMING_EVENT_ROAM_SUCCESS;
    337 #ifdef TI_DBG
    338             /* For debug */
    339             pRoamingMngr->roamingSuccesfulHandoverNum++;
    340             pRoamingMngr->roamingHandoverCompletedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
    341             pRoamingMngr->roamingAverageSuccHandoverDuration += os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingHandoverStartedTimestamp;
    342             pRoamingMngr->roamingAverageRoamingDuration +=  os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingTriggerTimestamp;
    343             pRoamingMngr->roamingHandoverEvents[pRoamingMngr->roamingTrigger]++;
    344 #endif
    345             break;
    346         case CONN_STATUS_HANDOVER_FAILURE: roamingEvent = ROAMING_EVENT_REQ_HANDOVER;
    347 #ifdef TI_DBG
    348             /* For debug */
    349             pRoamingMngr->roamingFailedHandoverNum++;
    350 #endif
    351             break;
    352         default:
    353             TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connStatusCb, bad connStatus = %d\n", connStatus);
    354             return TI_NOK;
    355         }
    356     }
    357     else /* Roaming Manual operational mode*/
    358     {
    359          switch (connStatus)
    360          {
    361           case CONN_STATUS_CONNECTED:
    362         		roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_START;
    363                 apConn_getStaCapabilities(pRoamingMngr->hAPConnection,&pRoamingMngr->staCapabilities);
    364                 break;
    365           case CONN_STATUS_NOT_CONNECTED:
    366                 roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_STOP;
    367                 break;
    368           case CONN_STATUS_HANDOVER_SUCCESS:
    369                 roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_SUCCESS;
    370                 break;
    371           case CONN_STATUS_HANDOVER_FAILURE:
    372                 roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_FAIL;
    373                 break;
    374           default:
    375         	return TI_NOK;
    376         }
    377     }
    378 
    379     return (roamingMngr_smEvent(roamingEvent, pRoamingMngr));
    380 }
    381 
    382 /**
    383 *
    384 * roamingMngr_updateNeighborApListCb
    385 *
    386 * \b Description:
    387 *
    388 * This procedure is called when Neighbor AP list is received from the AP.
    389  * Save the list, and set them in Scan Manager object.
    390 *
    391 * \b ARGS:
    392 *
    393 *  I   - hRoamingMngr - roamingMngr SM context  \n
    394 *  I   - pData - pointer to the list of Neighbor APs.
    395 *
    396 * \b RETURNS:
    397 *
    398 *  TI_OK if successful, TI_NOK otherwise.
    399 *
    400 *
    401 */
    402 TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData)
    403 {
    404     roamingMngr_t           *pRoamingMngr;
    405     neighborAPList_t        *pNeighborAPList;
    406 
    407     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    408     if ((pRoamingMngr == NULL) || (pData == NULL))
    409     {
    410         return TI_NOK;
    411     }
    412 
    413     pNeighborAPList = (neighborAPList_t *)pData;
    414     if (pNeighborAPList->numOfEntries>0)
    415     {
    416         pRoamingMngr->neighborApsExist = TI_TRUE;
    417     }
    418     else
    419     {
    420         pRoamingMngr->neighborApsExist = TI_FALSE;
    421     }
    422 
    423     if (pRoamingMngr->roamingMngrConfig.enableDisable)
    424     {
    425         scanMngr_setNeighborAPs (pRoamingMngr->hScanMngr, pNeighborAPList);
    426     }
    427     TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_updateNeighborApListCb, numberOfAps = %d, enableDisable=%d\n", 							 pNeighborAPList->numOfEntries, pRoamingMngr->roamingMngrConfig.enableDisable);
    428 
    429     return TI_OK;
    430 }
    431 
    432 /**
    433 *
    434 * roamingMngr_smEvent
    435 *
    436 * \b Description:
    437 *
    438 * Roaming Manager state machine transition function
    439 *
    440 * \b ARGS:
    441 *
    442 *  I/O - currentState - current state in the state machine\n
    443 *  I   - event - specific event for the state machine\n
    444 *  I   - pData - Data for state machine action function\n
    445 *
    446 * \b RETURNS:
    447 *
    448 *  TI_OK on success, TI_NOK otherwise.
    449 *
    450 * \sa
    451 */
    452 TI_STATUS roamingMngr_smEvent(TI_UINT8 event, void* data)
    453 {
    454     roamingMngr_t   *pRoamingMngr = (roamingMngr_t*)data;
    455 
    456     TRACE3(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smEvent(). Mode(%d) ,currentState = %d, event=%d \n",
    457                     pRoamingMngr->RoamingOperationalMode,
    458                     *(pRoamingMngr->pCurrentState),
    459                     event);
    460 
    461     genSM_Event (pRoamingMngr->hRoamingSm, (TI_UINT32)event, data);
    462 
    463     TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smEvent(). new State : %d \n", *(pRoamingMngr->pCurrentState));
    464 
    465     return TI_OK;
    466 }
    467 
    468 
    469 
    470 #ifdef TI_DBG
    471 /**
    472 *
    473 * roamingMngr_debugTrace
    474 *
    475 * \b Description:
    476 *
    477 * This procedure is called for debug only, to trace the roaming triggers and events
    478 *
    479 * \b ARGS:
    480 *
    481 *  I   - hRoamingMngr - roamingMngr SM context  \n
    482 *
    483 * \b RETURNS:
    484 *
    485 *  TI_OK if successful, TI_NOK otherwise.
    486 *
    487 *
    488 */
    489 static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr)
    490 {
    491 
    492 
    493     roamingMngr_t       *pRoamingMngr;
    494     TI_UINT8               index;
    495 
    496     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    497     if (pRoamingMngr == NULL)
    498     {
    499         return;
    500     }
    501 
    502     WLAN_OS_REPORT(("******** ROAMING_TRIGGERS ********\n"));
    503     for (index=ROAMING_TRIGGER_LOW_TX_RATE; index<ROAMING_TRIGGER_LAST; index++)
    504     {
    505         switch (index)
    506         {
    507         case ROAMING_TRIGGER_LOW_TX_RATE:
    508             WLAN_OS_REPORT(("- Low TX rate = %d\n",     pRoamingMngr->roamingTriggerEvents[index]));
    509             break;
    510         case ROAMING_TRIGGER_LOW_SNR:
    511             WLAN_OS_REPORT(("- Low Snr = %d\n",         pRoamingMngr->roamingTriggerEvents[index]));
    512             break;
    513         case ROAMING_TRIGGER_LOW_QUALITY:
    514             WLAN_OS_REPORT(("- Low Quality = %d\n",     pRoamingMngr->roamingTriggerEvents[index]));
    515             break;
    516         case ROAMING_TRIGGER_MAX_TX_RETRIES:
    517             WLAN_OS_REPORT(("- MAX TX retries = %d\n",  pRoamingMngr->roamingTriggerEvents[index]));
    518             break;
    519         case ROAMING_TRIGGER_BSS_LOSS:
    520             WLAN_OS_REPORT(("- BSS Loss TX = %d\n",     pRoamingMngr->roamingTriggerEvents[index]));
    521             break;
    522         case ROAMING_TRIGGER_SWITCH_CHANNEL:
    523             WLAN_OS_REPORT(("- Switch Channel = %d\n",  pRoamingMngr->roamingTriggerEvents[index]));
    524             break;
    525         case ROAMING_TRIGGER_AP_DISCONNECT:
    526             WLAN_OS_REPORT(("- AP Disconnect = %d\n",   pRoamingMngr->roamingTriggerEvents[index]));
    527             break;
    528         case ROAMING_TRIGGER_SECURITY_ATTACK:
    529             WLAN_OS_REPORT(("- SEC attack = %d\n",      pRoamingMngr->roamingTriggerEvents[index]));
    530             break;
    531         default:
    532             break;
    533         }
    534     }
    535 
    536     WLAN_OS_REPORT(("******** Succ ROAMING_HANDOVERS ********\n"));
    537 
    538     for (index=ROAMING_TRIGGER_LOW_QUALITY; index<ROAMING_TRIGGER_LAST; index++)
    539     {
    540         switch (index)
    541         {
    542         case ROAMING_TRIGGER_LOW_TX_RATE:
    543             WLAN_OS_REPORT(("- Low TX rate = %d\n",     pRoamingMngr->roamingHandoverEvents[index]));
    544             break;
    545         case ROAMING_TRIGGER_LOW_SNR:
    546             WLAN_OS_REPORT(("- Low Snre = %d\n",        pRoamingMngr->roamingHandoverEvents[index]));
    547             break;
    548         case ROAMING_TRIGGER_LOW_QUALITY:
    549             WLAN_OS_REPORT(("- Low Quality = %d\n",     pRoamingMngr->roamingHandoverEvents[index]));
    550             break;
    551         case ROAMING_TRIGGER_MAX_TX_RETRIES:
    552             WLAN_OS_REPORT(("- MAX TX retries = %d\n",  pRoamingMngr->roamingHandoverEvents[index]));
    553             break;
    554         case ROAMING_TRIGGER_BSS_LOSS:
    555             WLAN_OS_REPORT(("- BSS Loss TX = %d\n",     pRoamingMngr->roamingHandoverEvents[index]));
    556             break;
    557         case ROAMING_TRIGGER_SWITCH_CHANNEL:
    558             WLAN_OS_REPORT(("- Switch Channel = %d\n",   pRoamingMngr->roamingHandoverEvents[index]));
    559             break;
    560         case ROAMING_TRIGGER_AP_DISCONNECT:
    561             WLAN_OS_REPORT(("- AP Disconnect = %d\n",   pRoamingMngr->roamingHandoverEvents[index]));
    562             break;
    563         case ROAMING_TRIGGER_SECURITY_ATTACK:
    564             WLAN_OS_REPORT(("- SEC attack = %d\n",      pRoamingMngr->roamingHandoverEvents[index]));
    565             break;
    566         default:
    567             break;
    568         }
    569     }
    570 
    571     WLAN_OS_REPORT(("******** ROAMING STATISTICS ********\n"));
    572     WLAN_OS_REPORT(("- Num of succesful handovers = %d\n", pRoamingMngr->roamingSuccesfulHandoverNum));
    573     WLAN_OS_REPORT(("- Num of failed handovers = %d\n", pRoamingMngr->roamingFailedHandoverNum));
    574     if (pRoamingMngr->roamingSuccesfulHandoverNum >0)
    575     {
    576         WLAN_OS_REPORT(("- Succesful average succesful handover duration = %d\n", pRoamingMngr->roamingAverageSuccHandoverDuration/pRoamingMngr->roamingSuccesfulHandoverNum));
    577         WLAN_OS_REPORT(("- Succesful average roaming duration = %d\n", pRoamingMngr->roamingAverageRoamingDuration/pRoamingMngr->roamingSuccesfulHandoverNum));
    578     }
    579 
    580 
    581 }
    582 
    583 
    584 /**
    585 *
    586 * roamingMngr_resetDebugTrace
    587 *
    588 * \b Description:
    589 *
    590 * This procedure is called for debug only, to reset Roaming debug trace
    591 *
    592 * \b ARGS:
    593 *
    594 *  I   - hRoamingMngr - roamingMngr SM context  \n
    595 *
    596 * \b RETURNS:
    597 *
    598 *  TI_OK if successful, TI_NOK otherwise.
    599 *
    600 *
    601 */
    602 static void roamingMngr_resetStatistics(TI_HANDLE hRoamingMngr)
    603 {
    604 
    605     roamingMngr_t       *pRoamingMngr;
    606     TI_UINT8               index;
    607 
    608     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    609     if (pRoamingMngr == NULL)
    610     {
    611         return;
    612     }
    613     WLAN_OS_REPORT(("Resetting all ROAMING_EVENTS \n"));
    614 
    615     pRoamingMngr->roamingSuccesfulHandoverNum = 0;
    616     pRoamingMngr->roamingHandoverStartedTimestamp = 0;
    617     pRoamingMngr->roamingHandoverCompletedTimestamp = 0;
    618     pRoamingMngr->roamingAverageSuccHandoverDuration = 0;
    619     pRoamingMngr->roamingAverageRoamingDuration = 0;
    620     pRoamingMngr->roamingFailedHandoverNum = 0;
    621 
    622     for (index=ROAMING_TRIGGER_LOW_QUALITY; index<ROAMING_TRIGGER_LAST; index++)
    623     {
    624         pRoamingMngr->roamingHandoverEvents[index] = 0;
    625         pRoamingMngr->roamingTriggerEvents[index] = 0;
    626     }
    627 }
    628 
    629 #endif /*TI_DBG*/
    630 
    631 
    632 
    633 /**********************************************************************
    634 **         External Function section                                 **
    635 ***********************************************************************/
    636 extern TI_STATUS apConn_reportRoamingEvent(TI_HANDLE hAPConnection,
    637 										   apConn_roamingTrigger_e roamingEventType,
    638 										   void *roamingEventData);
    639 
    640 
    641 
    642 /**********************************************************************
    643 **         API Function section                                      **
    644 ***********************************************************************/
    645 
    646 TI_HANDLE roamingMngr_create(TI_HANDLE hOs)
    647 {
    648     roamingMngr_t   *pRoamingMngr;
    649     TI_UINT32          initVec;
    650 
    651     initVec = 0;
    652 
    653     pRoamingMngr = os_memoryAlloc(hOs, sizeof(roamingMngr_t));
    654     if (pRoamingMngr == NULL)
    655         return NULL;
    656 
    657     initVec |= (1 << ROAMING_MNGR_CONTEXT_INIT_BIT);
    658     pRoamingMngr->hOs   = hOs;
    659 
    660     /* allocate the state machine object */
    661     pRoamingMngr->hRoamingSm = genSM_Create(hOs);
    662 
    663     if (pRoamingMngr->hRoamingSm == NULL)
    664     {
    665         roamingMngr_releaseModule(pRoamingMngr, initVec);
    666         WLAN_OS_REPORT(("FATAL ERROR: roamingMngr_create(): Error Creating pRoamingSm - Aborting\n"));
    667         return NULL;
    668     }
    669     initVec |= (1 << ROAMING_MNGR_SM_INIT_BIT);
    670 
    671 
    672     return pRoamingMngr;
    673 }
    674 
    675 TI_STATUS roamingMngr_unload(TI_HANDLE hRoamingMngr)
    676 {
    677     TI_UINT32          initVec;
    678 
    679     if (hRoamingMngr == NULL)
    680     {
    681         return TI_OK;
    682     }
    683 
    684     initVec = 0xFFFF;
    685     roamingMngr_releaseModule(hRoamingMngr, initVec);
    686 
    687     return TI_OK;
    688 }
    689 
    690 void roamingMngr_init (TStadHandlesList *pStadHandles)
    691 {
    692     roamingMngr_t    *pRoamingMngr = (roamingMngr_t*)(pStadHandles->hRoamingMngr);
    693 
    694     /* Update handlers */
    695     pRoamingMngr->hReport       = pStadHandles->hReport;
    696     pRoamingMngr->hScanMngr     = pStadHandles->hScanMngr;
    697     pRoamingMngr->hAPConnection = pStadHandles->hAPConnection;
    698     pRoamingMngr->hTWD          = pStadHandles->hTWD;
    699     pRoamingMngr->hEvHandler    = pStadHandles->hEvHandler;
    700     pRoamingMngr->hCurrBss      = pStadHandles->hCurrBss;
    701 
    702     genSM_Init(pRoamingMngr->hRoamingSm,pRoamingMngr->hReport);
    703 }
    704 
    705 
    706 TI_STATUS roamingMngr_setDefaults (TI_HANDLE hRoamingMngr, TRoamScanMngrInitParams *pInitParam)
    707 {
    708 
    709     roamingMngr_t  *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    710 	paramInfo_t     param;
    711 
    712 #ifdef TI_DBG
    713     TI_UINT8 index =0;
    714 #endif
    715      /* Init intrenal variables */
    716     //pRoamingMngr->currentState = ROAMING_STATE_IDLE;
    717     pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED;
    718     pRoamingMngr->roamingMngrConfig.apQualityThreshold = DEFAULT_AP_QUALITY;
    719     pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt = DEFAULT_LOW_PASS_FILTER;
    720     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
    721     pRoamingMngr->maskRoamingEvents= TI_TRUE;
    722     pRoamingMngr->scanType = ROAMING_NO_SCAN;
    723     pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
    724     pRoamingMngr->handoverWasPerformed = TI_FALSE;
    725     pRoamingMngr->lowQualityTriggerTimestamp = 0;
    726     pRoamingMngr->neighborApsExist = TI_FALSE;
    727     pRoamingMngr->pListOfAPs = NULL;
    728     pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
    729     pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
    730     pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
    731     pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;
    732     pRoamingMngr->RoamingOperationalMode =  pInitParam->RoamingOperationalMode;
    733     pRoamingMngr->bSendTspecInReassPkt = pInitParam->bSendTspecInReassPkt;
    734 
    735 	if (pInitParam->RoamingScanning_2_4G_enable)
    736     {
    737         param.content.roamingConfigBuffer.roamingMngrConfig.enableDisable =  ROAMING_ENABLED ;
    738         param.content.roamingConfigBuffer.roamingMngrConfig.lowPassFilterRoamingAttempt = 30;
    739         param.content.roamingConfigBuffer.roamingMngrConfig.apQualityThreshold = -70;
    740 
    741         param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.dataRetryThreshold = 20;
    742         param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss = 10;
    743         param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.txRateThreshold = 2;
    744         param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowRssiThreshold = -80;
    745         param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowSnrThreshold = 0;
    746         param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition = -80;
    747         param.content.roamingConfigBuffer.roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition = -70;
    748 
    749         param.paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION;
    750         param.paramLength = sizeof(roamingMngrConfigParams_t);
    751 
    752         roamingMngr_setParam(hRoamingMngr, &param);
    753 
    754     }
    755 
    756 
    757 
    758     /* config the FSM according to the operational mode*/
    759     if(ROAMING_OPERATIONAL_MODE_MANUAL==pRoamingMngr->RoamingOperationalMode)
    760     {
    761          genSM_SetDefaults(pRoamingMngr->hRoamingSm,
    762                            ROAMING_MANUAL_NUM_STATES,
    763                            ROAMING_MANUAL_NUM_EVENTS,
    764                            &roamingMngrManual_matrix[0][0],
    765                            ROAMING_MANUAL_STATE_IDLE,
    766                            "Roaming Manual SM",
    767                            ManualRoamStateDescription,
    768                            ManualRoamEventDescription,
    769                            __FILE_ID__);
    770 
    771          pRoamingMngr->RoamStateDescription = ManualRoamStateDescription;
    772          pRoamingMngr->RoamEventDescription = ManualRoamEventDescription;
    773     }
    774     else
    775     {
    776          genSM_SetDefaults(pRoamingMngr->hRoamingSm,
    777                            ROAMING_MNGR_NUM_STATES,
    778                            ROAMING_MNGR_NUM_EVENTS,
    779                            &roamingMngrAuto_matrix[0][0],
    780                            ROAMING_STATE_IDLE,
    781                            "Roaming Auto SM",
    782                            AutoRoamStateDescription,
    783                            AutoRoamEventDescription,
    784                            __FILE_ID__);
    785 
    786          pRoamingMngr->RoamStateDescription = AutoRoamStateDescription;
    787          pRoamingMngr->RoamEventDescription = AutoRoamEventDescription;
    788     }
    789 
    790     pRoamingMngr->pCurrentState = &((TGenSM*)pRoamingMngr->hRoamingSm)->uCurrentState;
    791 
    792 #ifdef TI_DBG
    793     /* debug counters */
    794     pRoamingMngr->roamingSuccesfulHandoverNum = 0;
    795     pRoamingMngr->roamingHandoverStartedTimestamp = 0;
    796     pRoamingMngr->roamingHandoverCompletedTimestamp = 0;
    797     pRoamingMngr->roamingAverageSuccHandoverDuration = 0;
    798     pRoamingMngr->roamingAverageRoamingDuration = 0;
    799     pRoamingMngr->roamingFailedHandoverNum = 0;
    800 
    801     for (index=ROAMING_TRIGGER_NONE; index<ROAMING_TRIGGER_LAST; index++)
    802     {
    803         pRoamingMngr->roamingTriggerEvents[index] = 0;
    804         pRoamingMngr->roamingHandoverEvents[index] = 0;
    805     }
    806 #endif
    807 
    808     return TI_OK;
    809 }
    810 
    811 TI_STATUS roamingMngr_setParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam)
    812 {
    813     roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    814     TI_STATUS      status       = TI_OK;
    815 
    816     if (pParam == NULL)
    817     {
    818         TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR , "roamingMngr_setParam(): pParam is NULL!\n");
    819         return TI_NOK;
    820     }
    821 
    822     TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION , "roamingMngr_setParam   %X \n", pParam->paramType);
    823 
    824     switch (pParam->paramType)
    825     {
    826 
    827     case ROAMING_MNGR_APPLICATION_CONFIGURATION:
    828         {
    829             roamingMngrConfigParams_t   *pRoamingMngrConfigParams;
    830 
    831             pRoamingMngrConfigParams = &pParam->content.roamingConfigBuffer;
    832 
    833             /* Configure the Roaming Parmeters */
    834             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);
    835 
    836             pRoamingMngr->roamingMngrConfig.apQualityThreshold = pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold;
    837             pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt;
    838             pRoamingMngr->lowPassFilterRoamingAttemptInMsec = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt * 1000;
    839 
    840             /* Configure the Roaming Trigger thresholds */
    841             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);
    842 
    843             os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngr->roamingMngrThresholdsConfig, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t));
    844 
    845             status = apConn_setRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig);
    846 
    847             if (pRoamingMngr->roamingMngrConfig.enableDisable &&
    848                 !pRoamingMngrConfigParams->roamingMngrConfig.enableDisable)
    849             {   /* disable Roaming Manager */
    850                 apConn_unregisterRoamMngrCallb(pRoamingMngr->hAPConnection);
    851                 pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED;
    852                 return (roamingMngr_smEvent(ROAMING_EVENT_STOP, pRoamingMngr));
    853             }
    854             else if (!pRoamingMngr->roamingMngrConfig.enableDisable &&
    855                 pRoamingMngrConfigParams->roamingMngrConfig.enableDisable)
    856             {   /* enable Roaming Manager */
    857                 /* Save the Roaming Configuration parameters */
    858                 pRoamingMngr->roamingMngrConfig.enableDisable = pRoamingMngrConfigParams->roamingMngrConfig.enableDisable;
    859                 /* register Roaming callback */
    860                 apConn_registerRoamMngrCallb(pRoamingMngr->hAPConnection,
    861                                              roamingMngr_triggerRoamingCb,
    862                                              roamingMngr_connStatusCb,
    863                                              roamingMngr_updateNeighborApListCb);
    864             }
    865         }
    866         break;
    867 
    868 
    869     /*********** For Debug Purposes ***********/
    870 
    871     case ROAMING_MNGR_TRIGGER_EVENT:
    872         /* Enable/disable Internal Roaming */
    873         TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam TRIGGER_EVENT=  %d \n", pParam->content.roamingTriggerType);
    874         apConn_reportRoamingEvent(pRoamingMngr->hAPConnection, (apConn_roamingTrigger_e)pParam->content.roamingTriggerType, NULL);
    875         break;
    876 
    877     case ROAMING_MNGR_CONN_STATUS:
    878         /* External request to connect to BBSID */
    879         TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam CONN_STATUS=  %d \n", pParam->content.roamingConnStatus);
    880         roamingMngr_connStatusCb(pRoamingMngr, &pParam->content.roamingConnStatus);
    881         break;
    882 
    883     default:
    884         TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_setParam bad param=  %X\n", pParam->paramType);
    885 
    886         break;
    887     }
    888 
    889 
    890     return status;
    891 }
    892 
    893 TI_STATUS roamingMngr_getParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam)
    894 {
    895     roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    896 
    897     if (pParam == NULL)
    898     {
    899         TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR , "roamingMngr_getParam(): pParam is NULL!\n");
    900         return TI_NOK;
    901     }
    902 
    903     TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_getParam   %X \n", pParam->paramType);
    904 
    905     switch (pParam->paramType)
    906     {
    907     case ROAMING_MNGR_APPLICATION_CONFIGURATION:
    908         {
    909             roamingMngrConfigParams_t   *pRoamingMngrConfigParams;
    910 
    911             pRoamingMngrConfigParams = &pParam->content.roamingConfigBuffer;
    912 
    913             if (pRoamingMngr->roamingMngrConfig.enableDisable == ROAMING_DISABLED)
    914             {
    915                 pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = TI_FALSE;
    916             }
    917             else
    918             {
    919                 pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = TI_TRUE;
    920             }
    921             pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold = pRoamingMngr->roamingMngrConfig.apQualityThreshold;
    922             pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt;
    923 
    924             apConn_getRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngr->roamingMngrThresholdsConfig);
    925             os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, &pRoamingMngr->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t));
    926             pParam->paramLength = sizeof(roamingMngrConfigParams_t);
    927         }
    928         break;
    929 
    930 #ifdef TI_DBG
    931     case ROAMING_MNGR_PRINT_STATISTICS:
    932         roamingMngr_printStatistics(pRoamingMngr);
    933         break;
    934 
    935     case ROAMING_MNGR_RESET_STATISTICS:
    936         roamingMngr_resetStatistics(pRoamingMngr);
    937         break;
    938 
    939     case ROAMING_MNGR_PRINT_CURRENT_STATUS:
    940         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",
    941                         *(pRoamingMngr->pCurrentState),
    942                         pRoamingMngr->roamingMngrConfig.enableDisable,
    943                         pRoamingMngr->maskRoamingEvents,
    944                         pRoamingMngr->roamingTrigger,
    945                         pRoamingMngr->scanType,
    946                         pRoamingMngr->handoverWasPerformed,
    947                         pRoamingMngr->candidateApIndex,
    948                         pRoamingMngr->lowQualityTriggerTimestamp));
    949         break;
    950     case ROAMING_MNGR_PRINT_CANDIDATE_TABLE:
    951         {
    952             TI_UINT32      index;
    953 
    954             if (pRoamingMngr->pListOfAPs==NULL)
    955             {
    956                 TRACE0( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr the candidate AP list is invalid \n");
    957                 break;
    958             }
    959             TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "The number of candidates is %d\n", pRoamingMngr->pListOfAPs->numOfEntries);
    960 
    961             TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr Neighbor AP list, num of candidates = %d\n", pRoamingMngr->listOfCandidateAps.numOfNeighborBSS);
    962 
    963             for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfNeighborBSS; index++)
    964             {
    965                 TI_UINT32  candidateIndex;
    966                 bssEntry_t  *pBssEntry;
    967 
    968                 candidateIndex = pRoamingMngr->listOfCandidateAps.neighborBSSList[index];
    969                 pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
    970                 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);
    971             }
    972             TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr Pre-Auth AP list, num of candidates = %d\n", pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS);
    973 
    974             for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS; index++)
    975             {
    976                 TI_UINT32  candidateIndex;
    977                 bssEntry_t  *pBssEntry;
    978 
    979                 candidateIndex = pRoamingMngr->listOfCandidateAps.preAuthBSSList[index];
    980                 pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
    981                 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);
    982             }
    983             TRACE1( pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "Roaming Mngr Regular AP list, num of candidates = %d\n", pRoamingMngr->listOfCandidateAps.numOfRegularBSS);
    984 
    985             for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfRegularBSS; index++)
    986             {
    987                 TI_UINT32  candidateIndex;
    988                 bssEntry_t  *pBssEntry;
    989 
    990                 candidateIndex = pRoamingMngr->listOfCandidateAps.regularBSSList[index];
    991                 pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
    992                 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);
    993             }
    994         }
    995         break;
    996 
    997 #endif /*TI_DBG*/
    998 
    999     default:
   1000         TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_getParam  bad paramType= %X \n", pParam->paramType);
   1001         return TI_NOK;
   1002     }
   1003 
   1004     return TI_OK;
   1005 }
   1006 
   1007 TI_STATUS roamingMngr_immediateScanComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus)
   1008 {
   1009     roamingMngr_t           *pRoamingMngr;
   1010     roamingMngr_smEvents    roamingEvent;
   1011 
   1012 
   1013     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1014     if (pRoamingMngr == NULL)
   1015     {
   1016         return TI_NOK;
   1017     }
   1018 
   1019     TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_immediateScanComplete, scanCmpltStatus = %d\n", 							 scanCmpltStatus);
   1020 
   1021     if (scanCmpltStatus == SCAN_MRS_SCAN_COMPLETE_OK)
   1022     {
   1023 		/* The scan completed TI_OK, get the updated list of APs */
   1024         pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
   1025         if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
   1026         {
   1027 			/* APs were found, start selection */
   1028             pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1029             roamingEvent = ROAMING_EVENT_SELECT;
   1030         }
   1031         else
   1032         {   /* There were no APs, if the scan was partial, retry full scan */
   1033             if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
   1034                 (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY))
   1035             {
   1036                 pRoamingMngr->scanType = ROAMING_FULL_SCAN;
   1037                 roamingEvent = ROAMING_EVENT_SCAN;
   1038             }
   1039             else
   1040             {
   1041 				/* No APs were found in FULL SCAN, report failure */
   1042                 roamingEvent = ROAMING_EVENT_SELECT;
   1043             }
   1044         }
   1045     }
   1046 	/* scanCmpltStatus != SCAN_MRS_SCAN_COMPLETE_OK */
   1047     else
   1048     {
   1049 		/* The scan failed, retry scanning according to the current scan type */
   1050         pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
   1051         if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
   1052         {
   1053 			/* APs were found, start selection */
   1054             pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1055             roamingEvent = ROAMING_EVENT_SELECT;
   1056         }
   1057         else
   1058         {
   1059 			/* The scan failed, and there were no APs found.
   1060 			Retry scanning according to the current scan type */
   1061 			switch (pRoamingMngr->scanType)
   1062 			{
   1063 			case ROAMING_PARTIAL_SCAN:
   1064 				roamingEvent = ROAMING_EVENT_SCAN;
   1065 				pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN_RETRY;
   1066 				break;
   1067 			case ROAMING_PARTIAL_SCAN_RETRY:
   1068 				roamingEvent = ROAMING_EVENT_SELECT;
   1069 				pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1070 				break;
   1071 			case ROAMING_FULL_SCAN:
   1072 				roamingEvent = ROAMING_EVENT_SCAN;
   1073 				pRoamingMngr->scanType = ROAMING_FULL_SCAN_RETRY;
   1074 				break;
   1075 			case ROAMING_FULL_SCAN_RETRY:
   1076 					roamingEvent = ROAMING_EVENT_SELECT;
   1077 				pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1078 				break;
   1079 			default:
   1080 				roamingEvent = ROAMING_EVENT_SELECT;
   1081 TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_immediateScanComplete, pRoamingMngr->scanType = %d\n", 								   pRoamingMngr->scanType);
   1082 				pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1083 				break;
   1084 			} /* switch (pRoamingMngr->scanType) */
   1085         }
   1086     }
   1087 
   1088     TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_immediateScanComplete, roamingEvent = %d, scanType=%d\n", 							roamingEvent, 							 pRoamingMngr->scanType);
   1089 
   1090     return (roamingMngr_smEvent(roamingEvent, pRoamingMngr));
   1091 
   1092 }
   1093 
   1094 TI_STATUS roamingMngr_updateNewBssList(TI_HANDLE hRoamingMngr, bssList_t *bssList)
   1095 {
   1096 
   1097     roamingMngr_t       *pRoamingMngr;
   1098 
   1099     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1100     if ((pRoamingMngr == NULL) || (bssList == NULL))
   1101     {
   1102         return TI_NOK;
   1103     }
   1104 
   1105     TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_updateNewBssList, number of APs = %d\n", bssList->numOfEntries);
   1106 
   1107     if (*(pRoamingMngr->pCurrentState) != ROAMING_STATE_WAIT_4_TRIGGER)
   1108     {
   1109         TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_WARNING, "roamingMngr_updateNewBssList, ignore APs when not in WAIT_4_TRIGGER state \n");
   1110         return TI_NOK;
   1111     }
   1112 
   1113 
   1114     if (pRoamingMngr->staCapabilities.authMode!=os802_11AuthModeWPA2)
   1115     {   /* No Pre-Auth is required */
   1116         TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_updateNewBssList, No Pre-Auth is required\n");
   1117         return TI_OK;
   1118     }
   1119     apConn_preAuthenticate(pRoamingMngr->hAPConnection, bssList);
   1120 
   1121     return TI_OK;
   1122 
   1123 }
   1124 
   1125 
   1126 void roamingMngr_smNop(void *pData)
   1127 {
   1128     roamingMngr_t       *pRoamingMngr;
   1129 
   1130     pRoamingMngr = (roamingMngr_t*)pData;
   1131     TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, " roamingMngr_smNop\n");
   1132 }
   1133 
   1134 
   1135 void roamingMngr_smUnexpected(void *pData)
   1136 {
   1137     roamingMngr_t       *pRoamingMngr;
   1138 
   1139     pRoamingMngr = (roamingMngr_t*)pData;
   1140     TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, " roamingMngr_smUnexpected, state = %d\n", *(pRoamingMngr->pCurrentState));
   1141 }
   1142 
   1143 
   1144 void roamingMngr_smStop(void *pData)
   1145 {
   1146     roamingMngr_t       *pRoamingMngr;
   1147 
   1148     pRoamingMngr = (roamingMngr_t*)pData;
   1149 
   1150     scanMngr_stopContScan(pRoamingMngr->hScanMngr);
   1151     /* clean intenal variables */
   1152     pRoamingMngr->maskRoamingEvents = TI_TRUE;
   1153     pRoamingMngr->neighborApsExist = TI_FALSE;
   1154     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   1155 }
   1156 /**
   1157 *
   1158 * roamingMngr_smStopWhileScanning -
   1159 *
   1160 * \b Description:
   1161 *
   1162 * Stop event means that the station is not in Connected State.
   1163  * Stop continuos and immediate scans and clean internal vars.
   1164 *
   1165 * \b ARGS:
   1166 *
   1167 *  I   - pData - pointer to the roamingMngr SM context  \n
   1168 *
   1169 * \b RETURNS:
   1170 *
   1171 *  TI_OK if successful, TI_NOK otherwise.
   1172 *
   1173 *
   1174 */
   1175 void roamingMngr_smStopWhileScanning(void *pData)
   1176 {
   1177     roamingMngr_t* pRoamingMngr;
   1178 
   1179     pRoamingMngr = (roamingMngr_t*)pData;
   1180 
   1181     TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, " roamingMngr_smStopWhileScanning\n");
   1182 
   1183     scanMngr_stopImmediateScan(pRoamingMngr->hScanMngr);
   1184     scanMngr_stopContScan(pRoamingMngr->hScanMngr);
   1185 
   1186     /* clean intenal variables */
   1187     pRoamingMngr->maskRoamingEvents = TI_TRUE;
   1188     pRoamingMngr->neighborApsExist = TI_FALSE;
   1189     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   1190 }
   1191 
   1192 
   1193 
   1194 
   1195 /**
   1196 *
   1197 * roamingMngr_setBssLossThreshold API
   1198 *
   1199 * Description:
   1200 *
   1201 * Set the BSS Loss threshold by EMP and register for the event.
   1202 *
   1203 * ARGS:
   1204 *
   1205 *  hRoamingMngr   - Roaming manager handle \n
   1206 *  uNumOfBeacons - number of consecutive beacons not received allowed before BssLoss event is issued
   1207 *  uClientID - the ID of the client that has registered for this event. will be sent along with the BssLoss event to EMP
   1208 * \b RETURNS:
   1209 *
   1210 *  TI_STATUS - registration status.
   1211  * TI_NOK - registration is not allowed
   1212 *
   1213 * \sa
   1214 */
   1215 TI_STATUS roamingMngr_setBssLossThreshold (TI_HANDLE hRoamingMngr, TI_UINT32 uNumOfBeacons, TI_UINT16 uClientID)
   1216 {
   1217     roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1218 
   1219     TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setBssLossThreshold! \n");
   1220 
   1221     if(ROAMING_OPERATIONAL_MODE_MANUAL == pRoamingMngr->RoamingOperationalMode)
   1222     {
   1223         return currBss_registerBssLossEvent(pRoamingMngr->hCurrBss, uNumOfBeacons, uClientID);
   1224     }
   1225     else
   1226     {
   1227         TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_setBssLossThreshold is available only in auto mode! \n");
   1228         WLAN_OS_REPORT(("\n roamingMngr_setBssLossThreshold is available only in auto mode! \n "));
   1229         return TI_NOK;
   1230     }
   1231 }
   1232 
   1233 
   1234 
   1235 /**
   1236 *
   1237 * roamingMngr_Connect API
   1238 *
   1239 * Description:
   1240 *
   1241 * send the Connect event to roaming state machine
   1242 *
   1243 * ARGS:
   1244 *
   1245 *  hRoamingMngr   - Roaming manager handle \n
   1246 *  pTargetAp - the target AP to connect with info.
   1247 * \b RETURNS:
   1248 *
   1249 *  TI_STATUS - roamingMngr_smEvent status.
   1250 */
   1251 
   1252 TI_STATUS roamingMngr_connect(TI_HANDLE hRoamingMngr, TargetAp_t* pTargetAp)
   1253 {
   1254     roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1255     bssList_t *bssList;
   1256     int i=0;
   1257 
   1258     TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_connect(),"
   1259                                                                "transitionMethod = %d,"
   1260                                                                "requestType = %d,"
   1261                                                                " \n", pTargetAp->transitionMethod,pTargetAp->connRequest.requestType) ;
   1262 
   1263 
   1264     TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connect(),"
   1265                                                          " AP to roam BSSID: "
   1266                                                          "%02x-%02x-%02x-%02x-%02x-%02x "
   1267                                                          "\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]);
   1268 
   1269 
   1270     /* Search for target AP in the scan manager results table, to get its beacon/ProbResponse buffer  */
   1271     bssList = scanMngr_getBSSList(((roamingMngr_t*)hRoamingMngr)->hScanMngr);
   1272     for (i=0; i< bssList->numOfEntries ; i++)
   1273     {
   1274         if (MAC_EQUAL(bssList->BSSList[i].BSSID, pTargetAp->newAP.BSSID))
   1275         {
   1276             pTargetAp->newAP.pBuffer = bssList->BSSList[i].pBuffer;
   1277             pTargetAp->newAP.bufferLength = bssList->BSSList[i].bufferLength;
   1278             os_memoryCopy(pRoamingMngr->hOs, &(pRoamingMngr->targetAP), (void*)pTargetAp, sizeof(TargetAp_t));
   1279             return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_CONNECT, hRoamingMngr);
   1280         }
   1281     }
   1282 
   1283     TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connect(),"
   1284                                                          "AP was not found in scan table!! BSSID: "
   1285                                                          "%02x-%02x-%02x-%02x-%02x-%02x "
   1286                                                          "\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]);
   1287     return TI_NOK;
   1288 }
   1289 
   1290 /**
   1291 *
   1292 * roamingMngr_startImmediateScan API
   1293 *
   1294 * Description:
   1295 *
   1296 * start the immediate scan with the channel list received by the application
   1297 *
   1298 * ARGS:
   1299 *
   1300 *  hRoamingMngr   - Roaming manager handle \n
   1301 *  pChannelList -  The channel list to be scanned
   1302 * \b RETURNS:
   1303 *
   1304 *  TI_STATUS - roamingMngr_smEvent status.
   1305 */
   1306 
   1307 TI_STATUS roamingMngr_startImmediateScan(TI_HANDLE hRoamingMngr, channelList_t* pChannelList)
   1308 {
   1309     roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1310 
   1311     TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_startImmediateScan().\n");
   1312 
   1313     /* Save the channelList for later usage in the scanMngr_startImmediateScan() */
   1314     scanMngr_setManualScanChannelList (pRoamingMngr-> hScanMngr, pChannelList);
   1315     return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_SCAN, hRoamingMngr);
   1316 }
   1317 
   1318 
   1319 
   1320 /**
   1321 *
   1322 * roamingMngr_stopImmediateScan API
   1323 *
   1324 * Description:
   1325 *
   1326 * stop the immediate scan, called by the application.
   1327 *
   1328 * ARGS:
   1329 *
   1330 *  hRoamingMngr   - Roaming manager handle \n
   1331 * \b RETURNS:
   1332 *
   1333 *  TI_STATUS - TI_OK.
   1334 */
   1335 TI_STATUS roamingMngr_stopImmediateScan(TI_HANDLE hRoamingMngr)
   1336 {
   1337     roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1338     scanMngr_stopImmediateScan(pRoamingMngr->hScanMngr);
   1339 
   1340     return TI_OK;
   1341 }
   1342 
   1343 
   1344 /**
   1345 *
   1346 * roamingMngr_stopImmediateScan API
   1347 *
   1348 * Description:
   1349 *
   1350 * called upon the immediate scan by application complete
   1351 *
   1352 * ARGS:
   1353 *
   1354 *  hRoamingMngr   - Roaming manager handle
   1355 *  scanCmpltStatus - scanCmpltStatus
   1356 *
   1357 * \b RETURNS:
   1358 *
   1359 *  TI_STATUS - State machine event status.
   1360 */
   1361 
   1362 TI_STATUS  roamingMngr_immediateScanByAppComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus)
   1363 {
   1364     return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_COMPLETE, hRoamingMngr);
   1365 }
   1366 
   1367