Home | History | Annotate | Download | only in Roaming
      1 /***************************************************************************
      2 **+-----------------------------------------------------------------------+**
      3 **|                                                                       |**
      4 **| Copyright(c) 1998 - 2008 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 ****************************************************************************/
     35 
     36 /****************************************************************************
     37  *                                                                          *
     38  *   MODULE:  Roaming Manager                                               *
     39  *   PURPOSE:                                                               *
     40  *   Roaming manager is responsible to receive Roaming triggers and try
     41  *      to select a better AP.
     42  *      The Roaming triggers are: Low RSSI, PER, consecutive No ACK on TX,
     43  *      beacon Missed or External request.
     44  *      In each Internal Roaming request, scan is performed and selection for
     45  *      better AP. Better AP is defined as a different AP with better RSSI,
     46  *      and similar SSID and security settings.
     47  *      If better AP is found, there is a check for fast-roaming via the
     48  *      Supplicant. Then connection to the new AP is invoked.
     49  *                                                                          *
     50  ****************************************************************************/
     51 
     52 #include "osApi.h"
     53 
     54 #include "paramOut.h"
     55 #include "report.h"
     56 #include "fsm.h"
     57 #include "utils.h"
     58 
     59 #include "scanMngrApi.h"
     60 #include "roamingMngrApi.h"
     61 #include "apConnApi.h"
     62 #include "roamingMngrTypes.h"
     63 #include "bssTypes.h"
     64 
     65 /* Constants */
     66 
     67 /* Init bits */
     68 #define ROAMING_MNGR_CONTEXT_INIT_BIT       1
     69 #define ROAMING_MNGR_SM_INIT_BIT            2
     70 
     71 #define DEFAULT_AP_QUALITY                  (-70)
     72 #define DEFAULT_LOW_PASS_FILTER             (30)
     73 #define DEFAULT_DATA_RETRY_THRESHOLD        (20)
     74 #define DEFAULT_LOW_QUALITY_SCAN_COND       (-60)
     75 #define DEFAULT_NORMAL_QUALITY_SCAN_COND    (-50)
     76 #define DEFAULT_LOW_RSSI                    (-70)
     77 #define DEFAULT_LOW_SNR                     (0)
     78 #define DEFAULT_TBTT_4_BSS_LOSS             (10)
     79 #define DEFAULT_LOW_TX_RATE                 (2)
     80 
     81 /* Enumerations */
     82 
     83 /** state machine states */
     84 typedef enum
     85 {
     86     ROAMING_STATE_IDLE                      = 0,
     87     ROAMING_STATE_WAIT_4_TRIGGER    = 1,
     88     ROAMING_STATE_WAIT_4_CMD        = 2,
     89     ROAMING_STATE_SCANNING          = 3,
     90     ROAMING_STATE_SELECTING         = 4,
     91     ROAMING_STATE_CONNECTING        = 5,
     92     ROAMING_STATE_LAST              = 6
     93 } roamingMngr_smStates;
     94 
     95 /** State machine events */
     96 typedef enum
     97 {
     98     ROAMING_EVENT_START             = 0, /* CONNECTED */
     99     ROAMING_EVENT_STOP              = 1, /* NOT CONNECTED */
    100     ROAMING_EVENT_ROAM_TRIGGER      = 2,
    101     ROAMING_EVENT_SCAN              = 3,
    102     ROAMING_EVENT_SELECT            = 4,
    103     ROAMING_EVENT_REQ_HANDOVER      = 5,
    104     ROAMING_EVENT_ROAM_SUCCESS      = 6,
    105     ROAMING_EVENT_FAILURE           = 7,
    106     ROAMING_EVENT_LAST              = 8
    107 } roamingMngr_smEvents;
    108 
    109 /* scan types */
    110 typedef enum
    111 {
    112     ROAMING_NO_SCAN,
    113     ROAMING_PARTIAL_SCAN,
    114     ROAMING_PARTIAL_SCAN_RETRY,
    115     ROAMING_FULL_SCAN,
    116     ROAMING_FULL_SCAN_RETRY
    117 } scan4RoamingType_e;
    118 
    119 /* Roaming Trigger groups, according to Roaming Triggers */
    120 typedef enum
    121 {
    122     ROAMING_TRIGGER_BG_SCAN_GROUP = ROAMING_TRIGGER_NORMAL_QUALITY_FOR_BG_SCAN,
    123     ROAMING_TRIGGER_LOW_QUALITY_GROUP = ROAMING_TRIGGER_MAX_TX_RETRIES,
    124     ROAMING_TRIGGER_FAST_CONNECT_GROUP = ROAMING_TRIGGER_SWITCH_CHANNEL,
    125     ROAMING_TRIGGER_FULL_CONNECT_GROUP = ROAMING_TRIGGER_SECURITY_ATTACK
    126 } roamingMngr_connectTypeGroup_e;
    127 
    128 
    129 #define ROAMING_MNGR_NUM_STATES     ROAMING_STATE_LAST
    130 #define ROAMING_MNGR_NUM_EVENTS     ROAMING_EVENT_LAST
    131 
    132 #define INVALID_CANDIDATE_INDEX     0xFF
    133 #define CURRENT_AP_INDEX            0xFE
    134 
    135 /* Typedefs */
    136 
    137 typedef struct _roamingMngr_t   roamingMngr_t;
    138 /* Structures */
    139 typedef struct
    140 {
    141     UINT8   preAuthBSSList[MAX_SIZE_OF_BSS_TRACK_LIST];
    142     UINT8   numOfPreAuthBSS;
    143     UINT8   neighborBSSList[MAX_SIZE_OF_BSS_TRACK_LIST];
    144     UINT8   numOfNeighborBSS;
    145     UINT8   regularBSSList[MAX_SIZE_OF_BSS_TRACK_LIST];
    146     UINT8   numOfRegularBSS;
    147 } listOfCandidateAps_t;
    148 
    149 #define MAX_ROAMING_TRIGGERS  ROAMING_TRIGGER_LAST
    150 
    151 struct _roamingMngr_t
    152 {
    153     /*** Roaming manager parameters that can be configured externally ***/
    154     roamingMngrConfig_t         roamingMngrConfig;
    155     roamingMngrThresholdsConfig_t   roamingMngrThresholdsConfig;
    156     UINT32                      lowPassFilterRoamingAttemptInMsec;
    157 
    158     /*** Internal roaming parameters ***/
    159     /* the roaming trigger type */
    160     apConn_roamingTrigger_e     roamingTrigger;
    161     /* Roaming SM current state */
    162     roamingMngr_smStates        currentState;
    163     /* Indicate if a trigger is already in process, and therefore the
    164         other triggers will be ignored */
    165     BOOL                        maskRoamingEvents;
    166     /* TS to filter Too many low Quality roaming triggers */
    167     UINT32                      lowQualityTriggerTimestamp;
    168     /* the scan type performed for Roaming */
    169     scan4RoamingType_e          scanType;
    170     /* list of BSS received from Scan Manager */
    171     bssList_t                   *pListOfAPs;
    172     /* Indicating if Neighbor APs exist */
    173     BOOL                        neighborApsExist;
    174     /* a list of the candiadte APs indexes in pListOfAPs according to
    175         neighbor APs, pre-auth APs and other APs */
    176     listOfCandidateAps_t        listOfCandidateAps;
    177     /* The current candidate AP's index to Roam to */
    178     UINT8                       candidateApIndex;
    179     /* Indicates whether at least one handover was performed */
    180     BOOL                        handoverWasPerformed;
    181     /* The station capabilities for the current Connection */
    182     apConn_staCapabilities_t    staCapabilities;
    183 
    184     /* Roaming manager SM */
    185     fsm_stateMachine_t          *pRoamingSm;
    186 
    187     /* Roaming manager handles to other objects */
    188     TI_HANDLE                   hReport;
    189     TI_HANDLE                   hOs;
    190     TI_HANDLE                   hScanMngr;
    191     TI_HANDLE                   hAPConnection;
    192 
    193 #ifdef TI_DBG
    194 
    195     /* Debug trace for Roaming statistics */
    196     UINT32                      roamingTriggerEvents[MAX_ROAMING_TRIGGERS];
    197     UINT32                      roamingHandoverEvents[MAX_ROAMING_TRIGGERS];
    198     UINT32                      roamingSuccesfulHandoverNum;
    199     UINT32                      roamingFailedHandoverNum;
    200     UINT32                      roamingTriggerTimestamp;
    201     UINT32                      roamingHandoverStartedTimestamp;
    202     UINT32                      roamingHandoverCompletedTimestamp;
    203     UINT32                      roamingAverageSuccHandoverDuration;
    204     UINT32                      roamingAverageRoamingDuration;
    205 #endif
    206 
    207 };
    208 
    209 /* External data definitions */
    210 
    211 /* Local functions definitions */
    212 
    213 /* Global variables */
    214 
    215 #ifdef REPORT_LOG
    216 
    217 static char *roamingMngr_stateDesc[ROAMING_MNGR_NUM_STATES] = {
    218         "STATE_IDLE",
    219         "STATE_WAIT_4_TRIGGER",
    220         "STATE_WAIT_4_CMD",
    221         "STATE_SCANNING",
    222         "STATE_SELECTING",
    223         "CONNECTING"
    224     };
    225 
    226 static char *roamingMngr_eventDesc[ROAMING_MNGR_NUM_EVENTS] = {
    227         "EVENT_START",
    228         "EVENT_STOP",
    229         "EVENT_ROAM_TRIGGER",
    230         "EVENT_SCAN",
    231         "EVENT_SELECT",
    232         "EVENT_REQ_HANDOVER",
    233         "EVENT_ROAM_SUCCESS",
    234         "EVENT_FAILURE"
    235     };
    236 
    237 #endif
    238 
    239 /* Function prototypes */
    240 /* SM functions */
    241 static TI_STATUS roamingMngr_smEvent(UINT8 *currState, UINT8 event, void* data);
    242 static TI_STATUS roamingMngr_smUnexpected(void *pData);
    243 static TI_STATUS roamingMngr_smNop(void *pData);
    244 static TI_STATUS roamingMngr_smStartIdle(void *pData);
    245 static TI_STATUS roamingMngr_smStop(void *pData);
    246 static TI_STATUS roamingMngr_smStopWhileScanning(void *pData);
    247 static TI_STATUS roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr);
    248 static TI_STATUS roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr);
    249 static TI_STATUS roamingMngr_smSelection(TI_HANDLE hRoamingMngr);
    250 static TI_STATUS roamingMngr_smHandover(TI_HANDLE hRoamingMngr);
    251 static TI_STATUS roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr);
    252 static TI_STATUS roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr);
    253 static TI_STATUS roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr);
    254 static TI_STATUS roamingMngr_smDisconnectWhileConnecting(TI_HANDLE hRoamingMngr);
    255 
    256 
    257 
    258 /************** callback funtions called by AP Connection **************/
    259 /* called when a trigger for Roaming occurs */
    260 TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData);
    261 /* called when CONN status event occurs */
    262 TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData);
    263 /* called when Neighbor APs is updated */
    264 TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData);
    265 
    266 /* internal functions */
    267 static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, UINT32 initVec);
    268 
    269 #ifdef TI_DBG
    270 /* debug function */
    271 static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr);
    272 static void roamingMngr_resetStatistics(TI_HANDLE hRoamingMngr);
    273 #endif
    274 
    275 
    276 /**
    277 *
    278 * roamingMngr_create
    279 *
    280 * \b Description:
    281 *
    282 * Create the Roaming Manager context.
    283 *
    284 * \b ARGS:
    285 *
    286 *  I   - hOs - OS handler  \n
    287 *
    288 * \b RETURNS:
    289 *
    290 *  OK on success, NOK on failure.
    291 *
    292 * \sa
    293 */
    294 TI_HANDLE roamingMngr_create(TI_HANDLE hOs)
    295 {
    296     TI_STATUS       status;
    297     roamingMngr_t   *pRoamingMngr;
    298     UINT32          initVec;
    299 
    300     initVec = 0;
    301 
    302     pRoamingMngr = os_memoryAlloc(hOs, sizeof(roamingMngr_t));
    303     if (pRoamingMngr == NULL)
    304         return NULL;
    305 
    306     initVec |= (1 << ROAMING_MNGR_CONTEXT_INIT_BIT);
    307     pRoamingMngr->hOs   = hOs;
    308 
    309     status = fsm_Create(hOs, &pRoamingMngr->pRoamingSm, ROAMING_MNGR_NUM_STATES, ROAMING_MNGR_NUM_EVENTS);
    310     if (status != OK)
    311     {
    312         roamingMngr_releaseModule(pRoamingMngr, initVec);
    313         WLAN_OS_REPORT(("FATAL ERROR: roamingMngr_create(): Error Creating pRoamingSm - Aborting\n"));
    314         return NULL;
    315     }
    316     initVec |= (1 << ROAMING_MNGR_SM_INIT_BIT);
    317 
    318 
    319     return pRoamingMngr;
    320 }
    321 
    322 /**
    323 *
    324 * roamingMngr_releaseModule
    325 *
    326 * \b Description:
    327 *
    328 * Called by the un load function
    329 * Go over the vector, for each bit that is set, release the corresponding module.
    330 *
    331 * \b ARGS:
    332 *
    333 *  I   - pRoamingMngr - Roaming Manager context  \n
    334 *  I   - initVec - indicates which modules should be released
    335 *
    336 * \b RETURNS:
    337 *
    338 *  OK if successful, NOK otherwise.
    339 *
    340 * \sa roamingMngr_create
    341 */
    342 static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, UINT32 initVec)
    343 {
    344 
    345     if (pRoamingMngr==NULL)
    346     {
    347         return;
    348     }
    349     if (initVec & (1 << ROAMING_MNGR_SM_INIT_BIT))
    350     {
    351         fsm_Unload(pRoamingMngr->hOs, pRoamingMngr->pRoamingSm);
    352     }
    353 
    354     if (initVec & (1 << ROAMING_MNGR_CONTEXT_INIT_BIT))
    355     {
    356         utils_nullMemoryFree(pRoamingMngr->hOs, pRoamingMngr, sizeof(roamingMngr_t));
    357     }
    358 
    359     initVec = 0;
    360 }
    361 
    362 
    363 /**
    364 *
    365 * roamingMngr_unload
    366 *
    367 * \b Description:
    368 *
    369 * Unload Roaming Manager module from memory
    370 *
    371 * \b ARGS:
    372 *
    373 *  I   - hAdmCtrl - Roaming Manager context  \n
    374 *
    375 * \b RETURNS:
    376 *
    377 *  OK if successful, NOK otherwise.
    378 *
    379 * \sa roamingMngr_create
    380 */
    381 TI_STATUS roamingMngr_unload(TI_HANDLE hRoamingMngr)
    382 {
    383     UINT32          initVec;
    384 
    385     if (hRoamingMngr == NULL)
    386     {
    387         return OK;
    388     }
    389 
    390     initVec = 0xFFFF;
    391     roamingMngr_releaseModule(hRoamingMngr, initVec);
    392 
    393     return OK;
    394 }
    395 
    396 /**
    397 *
    398 * roamingMngr_config
    399 *
    400 * \b Description:
    401 *
    402 * Configure the Roaming Manager module.
    403 *
    404 * \b ARGS:
    405 *
    406 *  I   - hRoamingMngr - Roaming Manager context  \n
    407 *  I   - hReport - Report context  \n
    408 *  I   - hOs - OS context  \n
    409 *  I   - hSiteMgr - Site Manager context  \n
    410 *  I   - hSmeSm - SME context  \n
    411 *  I   - hCtrlData - Control Data context  \n
    412 *  I   - hPowerMgr - Power Manager context  \n
    413 *  I   - pRoamingParams - init roaming parameters read from the registry  \n
    414 *
    415 * \b RETURNS:
    416 *
    417 *  OK on success, NOK on failure.
    418 *
    419 * \sa
    420 */
    421 
    422 TI_STATUS roamingMngr_init(TI_HANDLE hRoamingMngr,
    423                       TI_HANDLE hReport,
    424                       TI_HANDLE hScanMngr,
    425                       TI_HANDLE hAPConnection)
    426 {
    427     roamingMngr_t           *pRoamingMngr;
    428     TI_STATUS               status;
    429 #ifdef ENABLE_ROAMING_BY_DEFAULT
    430     roamingMngrConfigParams_t InitRoamingParams;
    431     paramInfo_t             param;
    432 #endif
    433 #ifdef TI_DBG
    434     UINT8                   index;
    435 #endif
    436 
    437     /** Station broadcast key State Machine matrix */
    438     fsm_actionCell_t    roamingMngr_matrix[ROAMING_MNGR_NUM_STATES][ROAMING_MNGR_NUM_EVENTS] =
    439     {
    440         /* next state and actions for IDLE state */
    441         {   {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smStartIdle},        /* START            */
    442             {ROAMING_STATE_IDLE, roamingMngr_smNop},                        /* STOP             */
    443             {ROAMING_STATE_IDLE, roamingMngr_smNop},                        /* ROAM_TRIGGER     */
    444             {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* SCAN             */
    445             {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* SELECT           */
    446             {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* REQ_HANDOVER     */
    447             {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* ROAM_SUCCESS     */
    448             {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}                  /* FAILURE          */
    449         },
    450 
    451         /* next state and actions for WAIT_4_TRIGGER state */
    452         {   {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* START            */
    453             {ROAMING_STATE_IDLE, roamingMngr_smStop},                   /* STOP             */
    454             {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smRoamTrigger},      /* ROAM_TRIGGER     */
    455             {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* SCAN             */
    456             {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* SELECT           */
    457             {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* REQ_HANDOVER     */
    458             {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* ROAM_SUCCESS     */
    459             {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}    /* FAILURE          */
    460         },
    461 
    462         /* next state and actions for WAIT_4_CMD state */
    463         {   {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* START            */
    464             {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* STOP             */
    465             {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* ROAM_TRIGGER     */
    466             {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan},                 /* SCAN             */
    467             {ROAMING_STATE_SELECTING, roamingMngr_smSelection},                 /* SELECT           */
    468             {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* REQ_HANDOVER     */
    469             {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* ROAM_SUCCESS     */
    470             {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}                /* FAILURE          */
    471         },
    472 
    473         /* next state and actions for SCANNING state */
    474         {   {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected},              /* START            */
    475             {ROAMING_STATE_IDLE, roamingMngr_smStopWhileScanning},           /* STOP             */
    476             {ROAMING_STATE_SCANNING, roamingMngr_smNop},                     /* ROAM_TRIGGER     */
    477             {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan},              /* SCAN             */
    478             {ROAMING_STATE_SELECTING, roamingMngr_smSelection},              /* SELECT           */
    479             {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected},              /* REQ_HANDOVER     */
    480             {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected},              /* ROAM_SUCCESS     */
    481             {ROAMING_STATE_IDLE, roamingMngr_smScanFailure}                  /* FAILURE          */
    482 
    483         },
    484 
    485         /* next state and actions for SELECTING state */
    486         {   {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* START            */
    487             {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* STOP             */
    488             {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* ROAM_TRIGGER     */
    489             {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* SCAN             */
    490             {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* SELECT           */
    491             {ROAMING_STATE_CONNECTING, roamingMngr_smHandover},              /* REQ_HANDOVER     */
    492             {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* ROAM_SUCCESS     */
    493             {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}              /* FAILURE          */
    494 
    495         },
    496 
    497         /* next state and actions for CONNECTING state */
    498         {   {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected},           /* START            */
    499             {ROAMING_STATE_IDLE, roamingMngr_smStop},                       /* STOP             */
    500             {ROAMING_STATE_IDLE, roamingMngr_smDisconnectWhileConnecting},      /* ROAM_TRIGGER     */
    501             {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected},           /* SCAN,            */
    502             {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected},           /* SELECT           */
    503             {ROAMING_STATE_CONNECTING, roamingMngr_smHandover},             /* REQ_HANDOVER     */
    504             {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smSuccHandover} ,    /* ROAM_SUCCESS     */
    505             {ROAMING_STATE_IDLE, roamingMngr_smFailHandover}                /* FAILURE          */
    506 
    507         }
    508 
    509 
    510 
    511     };
    512 
    513     if (hRoamingMngr == NULL)
    514     {
    515         return NOK;
    516     }
    517 
    518     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    519 
    520     /* Update handlers */
    521     pRoamingMngr->hReport   = hReport;
    522     pRoamingMngr->hScanMngr = hScanMngr;
    523     pRoamingMngr->hAPConnection = hAPConnection;
    524 
    525     /* Init intrenal variables */
    526     pRoamingMngr->currentState = ROAMING_STATE_IDLE;
    527     pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED;
    528     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
    529     pRoamingMngr->maskRoamingEvents= TRUE;
    530     pRoamingMngr->scanType = ROAMING_NO_SCAN;
    531     pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
    532     pRoamingMngr->handoverWasPerformed = FALSE;
    533     pRoamingMngr->lowQualityTriggerTimestamp = 0;
    534     pRoamingMngr->neighborApsExist = FALSE;
    535     pRoamingMngr->pListOfAPs = NULL;
    536     pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
    537     pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
    538     pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
    539     pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;
    540 
    541 #ifdef TI_DBG
    542     /* debug counters */
    543     pRoamingMngr->roamingSuccesfulHandoverNum = 0;
    544     pRoamingMngr->roamingHandoverStartedTimestamp = 0;
    545     pRoamingMngr->roamingHandoverCompletedTimestamp = 0;
    546     pRoamingMngr->roamingAverageSuccHandoverDuration = 0;
    547     pRoamingMngr->roamingAverageRoamingDuration = 0;
    548     pRoamingMngr->roamingFailedHandoverNum = 0;
    549 
    550     for (index=ROAMING_TRIGGER_NONE; index<ROAMING_TRIGGER_LAST; index++)
    551     {
    552         pRoamingMngr->roamingTriggerEvents[index] = 0;
    553         pRoamingMngr->roamingHandoverEvents[index] = 0;
    554     }
    555 #endif
    556 
    557     /* config the FSM */
    558     status = fsm_Config(pRoamingMngr->pRoamingSm,
    559                         &roamingMngr_matrix[0][0],
    560                         ROAMING_MNGR_NUM_STATES,
    561                         ROAMING_MNGR_NUM_EVENTS,
    562                         roamingMngr_smEvent, pRoamingMngr->hOs);
    563 #ifdef ENABLE_ROAMING_BY_DEFAULT
    564 	if (status != OK)
    565 	{
    566 		return status;
    567 	}
    568 
    569 	param.paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION;
    570 	param.content.applicationConfigBuffer.bufferSize = sizeof(roamingMngrConfigParams_t);
    571 	param.content.applicationConfigBuffer.buffer = (UINT8 *)&param;
    572 	InitRoamingParams.roamingMngrConfig.enableDisable =  ROAMING_ENABLED;
    573 
    574 	InitRoamingParams.roamingMngrConfig.lowPassFilterRoamingAttempt = 30;
    575 	InitRoamingParams.roamingMngrConfig.apQualityThreshold = -70;
    576 
    577 	InitRoamingParams.roamingMngrThresholdsConfig.dataRetryThreshold = 20;
    578 	InitRoamingParams.roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss = 10;
    579 	InitRoamingParams.roamingMngrThresholdsConfig.txRateThreshold = 2;
    580 	InitRoamingParams.roamingMngrThresholdsConfig.lowRssiThreshold = -80;
    581 	InitRoamingParams.roamingMngrThresholdsConfig.lowSnrThreshold = 0;
    582 	InitRoamingParams.roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition = -60;
    583 	InitRoamingParams.roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition = -50;
    584 	InitRoamingParams.roamingMngrThresholdsConfig.rssiFilterWeight = 10;
    585 	InitRoamingParams.roamingMngrThresholdsConfig.snrFilterWeight  = 10;
    586 
    587 	param.paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION;
    588 	param.content.applicationConfigBuffer.bufferSize = sizeof(roamingMngrConfigParams_t);
    589 	param.content.applicationConfigBuffer.buffer = (UINT8 *)&InitRoamingParams;
    590 
    591 	roamingMngr_setParam (hRoamingMngr,&param);
    592 #endif
    593     return status;
    594 }
    595 
    596 /* For debug */
    597 extern TI_STATUS apConn_reportRoamingEvent(TI_HANDLE hAPConnection,apConn_roamingTrigger_e roamingEventType,void *pRoamingEventData);
    598 
    599 /**
    600 *
    601 * roamingMngr_setParam - Set a specific parameter to the roamingMngr SM
    602 *
    603 * \b Description:
    604 *
    605 * Set a specific parameter to the roamingMngr SM.
    606 *
    607 * \b ARGS:
    608 *
    609 *  I   - hRoamingMngr - roamingMngr SM context  \n
    610 *  I/O - pParam - Parameter \n
    611 *
    612 * \b RETURNS:
    613 *
    614 *  OK if successful, NOK otherwise.
    615 *
    616 *
    617 */
    618 TI_STATUS roamingMngr_setParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam)
    619 {
    620     roamingMngr_t       *pRoamingMngr;
    621     TI_STATUS           status=OK;
    622 
    623     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    624 
    625     if ((hRoamingMngr == NULL) || (pParam == NULL))
    626     {
    627         return NOK;
    628     }
    629     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    630                           ("roamingMngr_setParam   %X \n",
    631                           pParam->paramType));
    632 
    633 
    634     switch (pParam->paramType)
    635     {
    636 
    637     case ROAMING_MNGR_APPLICATION_CONFIGURATION:
    638         {
    639             roamingMngrConfigParams_t   *pRoamingMngrConfigParams;
    640 
    641             if (pParam->content.applicationConfigBuffer.bufferSize < sizeof(roamingMngrConfigParams_t))
    642             {
    643                 WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    644                                       ("roamingMngr_setParam bad  size = %d \n",
    645                                       pParam->content.applicationConfigBuffer.bufferSize));
    646                 return NOK;
    647             }
    648 
    649             pRoamingMngrConfigParams = (roamingMngrConfigParams_t*)pParam->content.applicationConfigBuffer.buffer;
    650 
    651             /* Configure the Roaming Parmeters */
    652             WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,("roamingMngr_setParam Configuration: \n \
    653                                    enableDisable= %d,\n  lowPassFilterRoamingAttempt=%d,\n \
    654                                    apQualityThreshold=%d\n",
    655                                    pRoamingMngrConfigParams->roamingMngrConfig.enableDisable,
    656                                    pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt,
    657                                    pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold));
    658 
    659             pRoamingMngr->roamingMngrConfig.apQualityThreshold = pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold;
    660             pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt;
    661             pRoamingMngr->lowPassFilterRoamingAttemptInMsec = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt * 1000;
    662 
    663             /* Configure the Roaming Trigger thresholds */
    664             WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,("roamingMngr_setParam Thresholds: \n \
    665                                    dataRetryThreshold= %d,\n  lowQualityForBackgroungScanCondition=%d,\n \
    666                                    lowRssiThreshold=%d,\n lowSNRThreshold=%d,\n \
    667                                    normalQualityForBackgroungScanCondition=%d,\n \
    668                                    numExpectedTbttForBSSLoss=%d,\n txRateThreshold=%d \n \n",
    669                                    pRoamingMngrConfigParams->roamingMngrThresholdsConfig.dataRetryThreshold,
    670                                    pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition,
    671                                    pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowRssiThreshold,
    672                                    pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowSnrThreshold,                                  pRoamingMngrConfigParams->roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition,
    673                                    pRoamingMngrConfigParams->roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss,
    674                                    pRoamingMngrConfigParams->roamingMngrThresholdsConfig.txRateThreshold));
    675 
    676             os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngr->roamingMngrThresholdsConfig, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t));
    677 
    678             status = apConn_setRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig);
    679 
    680             if (pRoamingMngr->roamingMngrConfig.enableDisable &&
    681                 !pRoamingMngrConfigParams->roamingMngrConfig.enableDisable)
    682             {   /* disable Roaming Manager */
    683                 apConn_unregisterRoamMngrCallb(pRoamingMngr->hAPConnection);
    684                 pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED;
    685                 return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_STOP, pRoamingMngr));
    686             }
    687             else if (!pRoamingMngr->roamingMngrConfig.enableDisable &&
    688                 pRoamingMngrConfigParams->roamingMngrConfig.enableDisable)
    689             {   /* enable Roaming Manager */
    690                 /* Save the Roaming Configuration parameters */
    691                 pRoamingMngr->roamingMngrConfig.enableDisable = pRoamingMngrConfigParams->roamingMngrConfig.enableDisable;
    692                 /* register Roaming callback */
    693                 apConn_registerRoamMngrCallb(pRoamingMngr->hAPConnection,
    694                                              roamingMngr_triggerRoamingCb,
    695                                              roamingMngr_connStatusCb,
    696                                              roamingMngr_updateNeighborApListCb);
    697             }
    698         }
    699         break;
    700 
    701     /*********** For Debug Purposes ***********/
    702 
    703     case ROAMING_MNGR_TRIGGER_EVENT:
    704         /* Enable/disable Internal Roaming */
    705         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    706                               ("roamingMngr_setParam TRIGGER_EVENT=  %d \n",
    707                               pParam->content.roamingTriggerType));
    708 
    709 		if ((apConn_roamingTrigger_e)pParam->content.roamingTriggerType == ROAMING_TRIGGER_AP_DISCONNECT)
    710         {
    711 			/* DeAuth packet with status code of deauth/disassoc packet equal to  1 */
    712 			apConn_reportRoamingEventDisconnect(pRoamingMngr->hAPConnection ,1 ,TRUE);
    713         }
    714         else
    715         {
    716 			apConn_reportRoamingEvent(pRoamingMngr->hAPConnection, (apConn_roamingTrigger_e)pParam->content.roamingTriggerType, NULL);
    717         }
    718         break;
    719 
    720     case ROAMING_MNGR_CONN_STATUS:
    721         /* External request to connect to BBSID */
    722         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    723                               ("roamingMngr_setParam CONN_STATUS=  %d \n",
    724                                pParam->content.roamingConnStatus));
    725         roamingMngr_connStatusCb(pRoamingMngr, &pParam->content.roamingConnStatus);
    726         break;
    727 
    728     default:
    729         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    730                               ("roamingMngr_setParam bad param=  %X\n",
    731                               pParam->paramType));
    732 
    733         break;
    734     }
    735 
    736 
    737     return status;
    738 }
    739 
    740 /**
    741 *
    742 * roamingMngr_getParam - Get a specific parameter from the roamingMngr SM
    743 *
    744 * \b Description:
    745 *
    746 * Get a specific parameter from the roamingMngr SM.
    747 *
    748 * \b ARGS:
    749 *
    750 *  I   - hRoamingMngr - roamingMngr SM context  \n
    751 *  I/O - pParam - Parameter \n
    752 *
    753 * \b RETURNS:
    754 *
    755 *  OK if successful, NOK otherwise.
    756 *
    757 *
    758 */
    759 TI_STATUS roamingMngr_getParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam)
    760 {
    761     roamingMngr_t       *pRoamingMngr;
    762 
    763     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    764 
    765     if ((hRoamingMngr == NULL) || (pParam == NULL))
    766     {
    767         return NOK;
    768     }
    769 
    770     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    771                           ("roamingMngr_getParam   %X \n",
    772                           pParam->paramType));
    773 
    774     switch (pParam->paramType)
    775     {
    776     case ROAMING_MNGR_APPLICATION_CONFIGURATION:
    777         {
    778             roamingMngrConfigParams_t   *pRoamingMngrConfigParams;
    779 
    780             pRoamingMngrConfigParams = (roamingMngrConfigParams_t *)&pParam->content.roamingConfigBuffer;
    781 
    782             if (pRoamingMngr->roamingMngrConfig.enableDisable == ROAMING_DISABLED)
    783             {
    784                 pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = FALSE;
    785             }
    786             else
    787             {
    788                 pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = TRUE;
    789             }
    790             pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold = pRoamingMngr->roamingMngrConfig.apQualityThreshold;
    791             pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt;
    792 
    793             apConn_getRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngr->roamingMngrThresholdsConfig);
    794             os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, &pRoamingMngr->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t));
    795             pParam->paramLength = sizeof(roamingMngrConfigParams_t);
    796         }
    797         break;
    798 
    799     case ROAMING_MNGR_CONF_PARAM:
    800         WLAN_OS_REPORT(("Roaming is: %s \n", pRoamingMngr->roamingMngrConfig.enableDisable ? "Enabled" : "Disabled"));
    801         WLAN_OS_REPORT(("lowPassFilterRoamingAttempt = %d msec, apQualityThreshold = %d\n",
    802                pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt,
    803                pRoamingMngr->roamingMngrConfig.apQualityThreshold));
    804         break;
    805 #ifdef TI_DBG
    806     case ROAMING_MNGR_PRINT_STATISTICS:
    807         roamingMngr_printStatistics(pRoamingMngr);
    808         break;
    809 
    810     case ROAMING_MNGR_RESET_STATISTICS:
    811         roamingMngr_resetStatistics(pRoamingMngr);
    812         break;
    813 
    814     case ROAMING_MNGR_PRINT_CURRENT_STATUS:
    815         WLAN_OS_REPORT(("Roaming Current State = %s, enableDisable=%d\n, maskRoamingEvents = %d, roamingTrigger=%d \n scanType=%d, handoverWasPerformed=%d \n, candidateApIndex=%d, lowQualityTriggerTimestamp=%d \n",
    816                         roamingMngr_stateDesc[pRoamingMngr->currentState],
    817                         pRoamingMngr->roamingMngrConfig.enableDisable,
    818                         pRoamingMngr->maskRoamingEvents,
    819                         pRoamingMngr->roamingTrigger,
    820                         pRoamingMngr->scanType,
    821                         pRoamingMngr->handoverWasPerformed,
    822                         pRoamingMngr->candidateApIndex,
    823                         pRoamingMngr->lowQualityTriggerTimestamp));
    824         break;
    825     case ROAMING_MNGR_PRINT_CANDIDATE_TABLE:
    826         {
    827             UINT32      index;
    828 
    829             if (pRoamingMngr->pListOfAPs==NULL)
    830             {
    831                 WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    832                                          ("Roaming Mngr the candidate AP list is invalid \n") );
    833                 break;
    834             }
    835             WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    836                                      ("The number of candidates is %d\n",
    837                                       pRoamingMngr->pListOfAPs->numOfEntries) );
    838 
    839             WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    840                                      ("Roaming Mngr Neighbor AP list, num of candidates = %d\n",
    841                                       pRoamingMngr->listOfCandidateAps.numOfNeighborBSS) );
    842 
    843             for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfNeighborBSS; index++)
    844             {
    845                 UINT32  candidateIndex;
    846                 bssEntry_t  *pBssEntry;
    847 
    848                 candidateIndex = pRoamingMngr->listOfCandidateAps.neighborBSSList[index];
    849                 pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
    850                 WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    851                                          ("candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n",
    852                                           candidateIndex, pBssEntry->BSSID.addr[0],
    853                                           pBssEntry->BSSID.addr[1], pBssEntry->BSSID.addr[2],
    854                                           pBssEntry->BSSID.addr[3], pBssEntry->BSSID.addr[4],
    855                                           pBssEntry->BSSID.addr[5], pBssEntry->RSSI) );
    856             }
    857             WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    858                                      ("Roaming Mngr Pre-Auth AP list, num of candidates = %d\n",
    859                                       pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS) );
    860 
    861             for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS; index++)
    862             {
    863                 UINT32  candidateIndex;
    864                 bssEntry_t  *pBssEntry;
    865 
    866                 candidateIndex = pRoamingMngr->listOfCandidateAps.preAuthBSSList[index];
    867                 pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
    868                 WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    869                                          ("candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n",
    870                                           candidateIndex, pBssEntry->BSSID.addr[0],
    871                                           pBssEntry->BSSID.addr[1], pBssEntry->BSSID.addr[2],
    872                                           pBssEntry->BSSID.addr[3], pBssEntry->BSSID.addr[4],
    873                                           pBssEntry->BSSID.addr[5], pBssEntry->RSSI) );
    874             }
    875             WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    876                                      ("Roaming Mngr Regular AP list, num of candidates = %d\n",
    877                                       pRoamingMngr->listOfCandidateAps.numOfRegularBSS) );
    878 
    879             for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfRegularBSS; index++)
    880             {
    881                 UINT32  candidateIndex;
    882                 bssEntry_t  *pBssEntry;
    883 
    884                 candidateIndex = pRoamingMngr->listOfCandidateAps.regularBSSList[index];
    885                 pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
    886                 WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    887                                          ("candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n",
    888                                           candidateIndex, pBssEntry->BSSID.addr[0],
    889                                           pBssEntry->BSSID.addr[1], pBssEntry->BSSID.addr[2],
    890                                           pBssEntry->BSSID.addr[3], pBssEntry->BSSID.addr[4],
    891                                           pBssEntry->BSSID.addr[5], pBssEntry->RSSI) );
    892             }
    893         }
    894         break;
    895 
    896 #endif /*TI_DBG*/
    897 
    898     default:
    899         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    900                               ("roamingMngr_getParam  bad paramType= %X \n",
    901                               pParam->paramType));
    902         return NOK;
    903     }
    904 
    905     return OK;
    906 }
    907 
    908 
    909 /**
    910 *
    911 * roamingMngr_triggerRoamingCb
    912 *
    913 * \b Description:
    914 *
    915 * This procedure is called when Roaming should be triggered
    916  * due to one of apConn_roamingTrigger_e Roaming Reasons.
    917  * Save the trigger and process it only if there's no other Roaming trigger
    918  * in process.
    919 *
    920 * \b ARGS:
    921 *
    922 *  I   - hRoamingMngr - roamingMngr SM context  \n
    923 *  I   - pData - pointer to roaming trigger
    924 *
    925 * \b RETURNS:
    926 *
    927 *  OK if successful, NOK otherwise.
    928 *
    929 *
    930 */
    931 TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData)
    932 {
    933     roamingMngr_t       *pRoamingMngr;
    934     apConn_roamingTrigger_e     roamingTrigger;
    935     UINT32                      curTimestamp;
    936 
    937     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    938     if ((pRoamingMngr == NULL) || (pData == NULL))
    939     {
    940         return NOK;
    941     }
    942 
    943     roamingTrigger = *(apConn_roamingTrigger_e *)pData;
    944 
    945     if (roamingTrigger >= ROAMING_TRIGGER_LAST)
    946     {
    947         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    948                           ("roamingMngr_triggerRoamingCb, bad roaming trigger = %d\n", roamingTrigger));
    949         return NOK;
    950     }
    951 #ifdef TI_DBG
    952     /* save parameters for debug*/
    953     pRoamingMngr->roamingTriggerEvents[pRoamingMngr->roamingTrigger]++;
    954 #endif
    955     if (roamingTrigger <= ROAMING_TRIGGER_BG_SCAN_GROUP)
    956     {
    957         BOOL    lowQuality = FALSE;
    958         if (roamingTrigger == ROAMING_TRIGGER_LOW_QUALITY_FOR_BG_SCAN)
    959         {
    960             lowQuality = TRUE;
    961         }
    962         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    963                       ("roamingMngr_triggerRoamingCb, lowQuality = %d \n",
    964                        lowQuality));
    965         scanMngr_qualityChangeTrigger(pRoamingMngr->hScanMngr, lowQuality);
    966     }
    967     else
    968     {
    969         if (roamingTrigger > pRoamingMngr->roamingTrigger)
    970         {   /* Save the highest priority roaming trigger */
    971             pRoamingMngr->roamingTrigger = roamingTrigger;
    972             WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    973                           ("roamingMngr_triggerRoamingCb, higher trigger = %d \n",
    974                            roamingTrigger));
    975 
    976         }
    977 
    978         curTimestamp = os_timeStampMs(pRoamingMngr->hOs);
    979 
    980         /* If "No BSS" trigger received, disable count of low pass filter timer */
    981         if (roamingTrigger > ROAMING_TRIGGER_LOW_QUALITY_GROUP)
    982         {
    983             pRoamingMngr->lowQualityTriggerTimestamp = 0;
    984         }
    985 
    986         /* Do not invoke a new Roaming Trigger when a previous one is in process */
    987         if (pRoamingMngr->maskRoamingEvents == FALSE)
    988         {   /* No Roaming trigger is in process */
    989             /* If the trigger is low quality check the low pass filter */
    990             WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
    991                       ("roamingMngr_triggerRoamingCb, trigger = %d \n",
    992                        roamingTrigger));
    993             if (roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP)
    994             {
    995                 UINT32 deltaTs = curTimestamp-pRoamingMngr->lowQualityTriggerTimestamp;
    996 
    997                 if ((pRoamingMngr->lowQualityTriggerTimestamp != 0) &&
    998                     (deltaTs < pRoamingMngr->lowPassFilterRoamingAttemptInMsec))
    999                 {  /* Ignore the low quality events. till the low pass time elapses */
   1000                     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1001                                   ("roamingMngr_triggerRoamingCb, trigger = %d Ignored!!,deltaTs=%d, curTimestamp = %d, lowQualityTriggerTimestamp = %d, lowPassFilterRoamingAttempt=%d\n",
   1002                                    roamingTrigger, deltaTs, curTimestamp, pRoamingMngr->lowQualityTriggerTimestamp, pRoamingMngr->lowPassFilterRoamingAttemptInMsec));
   1003                     return OK;
   1004                 }
   1005                 pRoamingMngr->lowQualityTriggerTimestamp = curTimestamp;
   1006             }
   1007 
   1008             /* Mask all future roaming events */
   1009             pRoamingMngr->maskRoamingEvents = TRUE;
   1010 
   1011 #ifdef TI_DBG
   1012             /* For debug */
   1013             pRoamingMngr->roamingTriggerTimestamp = curTimestamp;
   1014 #endif
   1015             return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));
   1016         }
   1017         else if (roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
   1018         {   /* If the trigger is from the Full Connect group, then stop the connection. */
   1019             return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));
   1020 
   1021         }
   1022     }
   1023 
   1024     return OK;
   1025 }
   1026 
   1027 /**
   1028 *
   1029 * roamingMngr_connStatusCb
   1030 *
   1031 * \b Description:
   1032 *
   1033 * This procedure is called when the connection status event
   1034  * is triggered.
   1035 *
   1036 * \b ARGS:
   1037 *
   1038 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1039 *  I   - pData - pointer to the connection status.
   1040 *
   1041 * \b RETURNS:
   1042 *
   1043 *  OK if successful, NOK otherwise.
   1044 *
   1045 *
   1046 */
   1047 TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData)
   1048 {
   1049     roamingMngr_t               *pRoamingMngr;
   1050     apConn_connStatus_e         connStatus;
   1051     roamingMngr_smEvents        roamingEvent;
   1052 
   1053     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1054     if ((pRoamingMngr == NULL) || (pData == NULL))
   1055     {
   1056         return NOK;
   1057     }
   1058 
   1059     connStatus = ((apConn_connStatus_t *)pData)->status;
   1060     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1061                       ("roamingMngr_connStatusCb, conn status = %d\n", connStatus));
   1062 
   1063     if (!pRoamingMngr->roamingMngrConfig.enableDisable)
   1064     {
   1065         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1066                               ("roamingMngr_connStatusCb, connStatus=%d was received while Roaming is disabled. Stop Roaming \n",
   1067                                connStatus));
   1068         return NOK;
   1069     }
   1070 
   1071     switch (connStatus)
   1072     {
   1073     case CONN_STATUS_CONNECTED: roamingEvent = ROAMING_EVENT_START;
   1074         /* Get station capabilities */
   1075         apConn_getStaCapabilities(pRoamingMngr->hAPConnection, &pRoamingMngr->staCapabilities);
   1076         break;
   1077     case CONN_STATUS_NOT_CONNECTED: roamingEvent = ROAMING_EVENT_STOP;
   1078         break;
   1079     case CONN_STATUS_HANDOVER_SUCCESS: roamingEvent = ROAMING_EVENT_ROAM_SUCCESS;
   1080 #ifdef TI_DBG
   1081         /* For debug */
   1082         pRoamingMngr->roamingSuccesfulHandoverNum++;
   1083         pRoamingMngr->roamingHandoverCompletedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
   1084         pRoamingMngr->roamingAverageSuccHandoverDuration += os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingHandoverStartedTimestamp;
   1085         pRoamingMngr->roamingAverageRoamingDuration +=  os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingTriggerTimestamp;
   1086         pRoamingMngr->roamingHandoverEvents[pRoamingMngr->roamingTrigger]++;
   1087 #endif
   1088         break;
   1089     case CONN_STATUS_HANDOVER_FAILURE: roamingEvent = ROAMING_EVENT_REQ_HANDOVER;
   1090 #ifdef TI_DBG
   1091         /* For debug */
   1092         pRoamingMngr->roamingFailedHandoverNum++;
   1093 #endif
   1094         break;
   1095     default:
   1096         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1097                           ("roamingMngr_connStatusCb, bad connStatus = %d\n", connStatus));
   1098         return NOK;
   1099 /*        break; - unreachable */
   1100     }
   1101 
   1102     return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, roamingEvent, pRoamingMngr));
   1103 
   1104 
   1105 }
   1106 
   1107 
   1108 
   1109 
   1110 
   1111 /**
   1112 *
   1113 * roamingMngr_updateNeighborApListCb
   1114 *
   1115 * \b Description:
   1116 *
   1117 * This procedure is called when Neighbor AP list is received from the AP.
   1118  * Save the list, and set them in Scan Manager object.
   1119 *
   1120 * \b ARGS:
   1121 *
   1122 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1123 *  I   - pData - pointer to the list of Neighbor APs.
   1124 *
   1125 * \b RETURNS:
   1126 *
   1127 *  OK if successful, NOK otherwise.
   1128 *
   1129 *
   1130 */
   1131 TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData)
   1132 {
   1133     roamingMngr_t           *pRoamingMngr;
   1134     neighborAPList_t        *pNeighborAPList;
   1135 
   1136     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1137     if ((pRoamingMngr == NULL) || (pData == NULL))
   1138     {
   1139         return NOK;
   1140     }
   1141 
   1142     pNeighborAPList = (neighborAPList_t *)pData;
   1143     if (pNeighborAPList->numOfEntries>0)
   1144     {
   1145         pRoamingMngr->neighborApsExist = TRUE;
   1146     }
   1147     else
   1148     {
   1149         pRoamingMngr->neighborApsExist = FALSE;
   1150     }
   1151 
   1152     if (pRoamingMngr->roamingMngrConfig.enableDisable)
   1153     {
   1154         scanMngr_setNeighborAPs (pRoamingMngr->hScanMngr, pNeighborAPList);
   1155     }
   1156     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1157                       ("roamingMngr_updateNeighborApListCb, numberOfAps = %d, enableDisable=%d\n",
   1158                        pNeighborAPList->numOfEntries, pRoamingMngr->roamingMngrConfig.enableDisable));
   1159 
   1160     return OK;
   1161 }
   1162 
   1163 /**
   1164 *
   1165 * roamingMngr_immediateScanComplete
   1166 *
   1167 * \b Description:
   1168 *
   1169 * This procedure is called when Scan Manager completed Immediate Scan for Roaming
   1170  * It performs the following:
   1171  * - Partial or Full scan
   1172  * - Re-try Partial or Full scan if the previous scan failed
   1173  * - Full scan if the previous partial scan didn't get any APS
   1174  * - Fail event if all the Scans failed
   1175 *
   1176 * \b ARGS:
   1177 *
   1178 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1179 *  I   - scanCmpltStatus - the scan result, success or failure with different reasons
   1180 *
   1181 * \b RETURNS:
   1182 *
   1183 *  OK if successful, NOK otherwise.
   1184 *
   1185 *
   1186 */
   1187 TI_STATUS roamingMngr_immediateScanComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus)
   1188 {
   1189     roamingMngr_t           *pRoamingMngr;
   1190     roamingMngr_smEvents    roamingEvent;
   1191 
   1192 
   1193     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1194     if (pRoamingMngr == NULL)
   1195     {
   1196         return NOK;
   1197     }
   1198 
   1199     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1200                       ("roamingMngr_immediateScanComplete, scanCmpltStatus = %d\n", scanCmpltStatus));
   1201 
   1202     if (scanCmpltStatus == SCAN_MRS_SCAN_COMPLETE_OK)
   1203     {   /* The scan completed OK, get the updated list of APs */
   1204         pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
   1205         if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
   1206         {   /* APs were found, start selection */
   1207             pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1208             roamingEvent = ROAMING_EVENT_SELECT;
   1209         }
   1210         else
   1211         {   /* There were no APs, if the scan was partial, retry full scan */
   1212             if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
   1213                 (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY))
   1214             {
   1215                 pRoamingMngr->scanType = ROAMING_FULL_SCAN;
   1216                 roamingEvent = ROAMING_EVENT_SCAN;
   1217             }
   1218             else
   1219             {   /* No APs were found in FULL SCAN, report failure */
   1220                 roamingEvent = ROAMING_EVENT_SELECT;
   1221             }
   1222         }
   1223     }
   1224     else
   1225     {   /* The scan failed, retry scanning according to the current scan type */
   1226         pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
   1227         if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
   1228         {   /* APs were found, start selection */
   1229             pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1230             roamingEvent = ROAMING_EVENT_SELECT;
   1231         }
   1232         else
   1233         {   /* The scan failed, and there were no APs found.
   1234                 Retry scanning according to the current scan type */
   1235         switch (pRoamingMngr->scanType)
   1236         {
   1237         case ROAMING_PARTIAL_SCAN:
   1238             roamingEvent = ROAMING_EVENT_SCAN;
   1239             pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN_RETRY;
   1240             break;
   1241         case ROAMING_PARTIAL_SCAN_RETRY:
   1242             roamingEvent = ROAMING_EVENT_SELECT;
   1243             pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1244             break;
   1245         case ROAMING_FULL_SCAN:
   1246             roamingEvent = ROAMING_EVENT_SCAN;
   1247             pRoamingMngr->scanType = ROAMING_FULL_SCAN_RETRY;
   1248             break;
   1249         case ROAMING_FULL_SCAN_RETRY:
   1250                 roamingEvent = ROAMING_EVENT_SELECT;
   1251             pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1252             break;
   1253         default:
   1254             roamingEvent = ROAMING_EVENT_SELECT;
   1255             WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1256                               ("roamingMngr_immediateScanComplete, pRoamingMngr->scanType = %d\n", pRoamingMngr->scanType));
   1257             pRoamingMngr->scanType = ROAMING_NO_SCAN;
   1258             break;
   1259             }
   1260 
   1261         }
   1262     }
   1263 
   1264     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1265                       ("roamingMngr_immediateScanComplete, roamingEvent = %d, scanType=%d\n",
   1266                        roamingEvent, pRoamingMngr->scanType));
   1267 
   1268     return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, roamingEvent, pRoamingMngr));
   1269 
   1270 
   1271 }
   1272 
   1273 
   1274 /* called by the Scan Manager when new BSSID was found */
   1275 /**
   1276 *
   1277 * roamingMngr_updateNewBssList
   1278 *
   1279 * \b Description:
   1280 *
   1281 * This procedure is called when Scan Manager finds new BSSIDs.
   1282 * These BSSIDs are sent to RSn to invoke Pre-Auth if allowed.
   1283 *
   1284 * \b ARGS:
   1285 *
   1286 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1287 *  I   - bssList - list of BSSIDs
   1288 *
   1289 * \b RETURNS:
   1290 *
   1291 *  OK if successful, NOK otherwise.
   1292 *
   1293 *
   1294 */
   1295 TI_STATUS roamingMngr_updateNewBssList(TI_HANDLE hRoamingMngr, bssList_t *bssList)
   1296 {
   1297 
   1298     roamingMngr_t       *pRoamingMngr;
   1299 
   1300     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1301     if ((pRoamingMngr == NULL) || (bssList == NULL))
   1302     {
   1303         return NOK;
   1304     }
   1305 
   1306     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1307                       ("roamingMngr_updateNewBssList, number of APs = %d\n", bssList->numOfEntries));
   1308 
   1309     if (pRoamingMngr->currentState != ROAMING_STATE_WAIT_4_TRIGGER)
   1310     {
   1311         WLAN_REPORT_WARNING(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1312                           ("roamingMngr_updateNewBssList, ignore APs when not in WAIT_4_TRIGGER state \n"));
   1313         return NOK;
   1314     }
   1315 
   1316 
   1317     if (pRoamingMngr->staCapabilities.authMode!=os802_11AuthModeWPA2)
   1318     {   /* No Pre-Auth is required */
   1319         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1320                           ("roamingMngr_updateNewBssList, No Pre-Auth is required\n"));
   1321         return OK;
   1322     }
   1323     apConn_preAuthenticate(pRoamingMngr->hAPConnection, bssList, bssList->numOfEntries);
   1324 
   1325     return OK;
   1326 
   1327 }
   1328 
   1329 
   1330 /*****************************************************************************
   1331 **         Private Function section                                      **
   1332 *****************************************************************************/
   1333 
   1334 
   1335 
   1336 /**
   1337 *
   1338 * roamingMngr_smEvent
   1339 *
   1340 * \b Description:
   1341 *
   1342 * Roaming Manager state machine transition function
   1343 *
   1344 * \b ARGS:
   1345 *
   1346 *  I/O - currentState - current state in the state machine\n
   1347 *  I   - event - specific event for the state machine\n
   1348 *  I   - pData - Data for state machine action function\n
   1349 *
   1350 * \b RETURNS:
   1351 *
   1352 *  OK on success, NOK otherwise.
   1353 *
   1354 * \sa
   1355 */
   1356 static TI_STATUS roamingMngr_smEvent(UINT8 *currState, UINT8 event, void* data)
   1357 {
   1358     TI_STATUS       status;
   1359     UINT8           nextState;
   1360     roamingMngr_t   *pRoamingMngr = (roamingMngr_t*)data;
   1361 
   1362 
   1363     status = fsm_GetNextState(pRoamingMngr->pRoamingSm, *currState, event, &nextState);
   1364     if (status != OK)
   1365     {
   1366         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG, ("roamingMngr_smEvent, fsm_GetNextState error\n"));
   1367         return(NOK);
   1368     }
   1369 
   1370 #ifdef TI_DBG
   1371     WLAN_REPORT_SM(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1372                               ("<%s, %s> --> %s\n\n",
   1373                                roamingMngr_stateDesc[*currState],
   1374                                roamingMngr_eventDesc[event],
   1375                                roamingMngr_stateDesc[nextState]));
   1376 #endif
   1377 
   1378     status = fsm_Event(pRoamingMngr->pRoamingSm, currState, event, (void *)pRoamingMngr);
   1379 
   1380 #ifdef TI_DBG
   1381     if (status != OK)
   1382     {
   1383         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG, ("roamingMngr_smEvent fsm_Event error\n"));
   1384         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1385                                   ("<%s, %s> --> %s\n\n",
   1386                                    roamingMngr_stateDesc[*currState],
   1387                                    roamingMngr_eventDesc[event],
   1388                                    roamingMngr_stateDesc[nextState]));
   1389     }
   1390 #endif
   1391 
   1392     return status;
   1393 
   1394 }
   1395 
   1396 /**
   1397 *
   1398 * roamingMngr_smRoamTrigger
   1399 *
   1400 * \b Description:
   1401 *
   1402 * This procedure is called when an Roaming event occurs: BSS LOSS, LOW Quality etc.
   1403  * Performs the following:
   1404  * - If Roaming is disabled, ignore.
   1405  * - Indicate Driver that Roaming process is starting
   1406  * - Get the BSS list from the Scan Manager.
   1407  * - If the list is not empty, start SELECTION
   1408  * - If the list is empty, start SCANNING. The type of scan is decided
   1409  *      according to the Neigbor APs existence.
   1410 *
   1411 * \b ARGS:
   1412 *
   1413 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1414 *
   1415 * \b RETURNS:
   1416 *
   1417 *  OK if successful, NOK otherwise.
   1418 *
   1419 *
   1420 */
   1421 static TI_STATUS roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr)
   1422 {
   1423     roamingMngr_t           *pRoamingMngr;
   1424     roamingMngr_smEvents    roamingEvent;
   1425 
   1426     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1427     if (pRoamingMngr == NULL)
   1428     {
   1429         return NOK;
   1430     }
   1431     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1432                 ("roamingMngr_smRoamTrigger, enableDisable = %d\n",pRoamingMngr->roamingMngrConfig.enableDisable));
   1433 
   1434 
   1435     if (!pRoamingMngr->roamingMngrConfig.enableDisable)
   1436     {   /* Ignore any other Roaming event when Roaming is disabled */
   1437         WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1438                     ("roamingMngr_smRoamTrigger, when Roaming is disabled\n"));
   1439         return OK;
   1440     }
   1441     /* Indicate the driver that Roaming process is starting */
   1442     apConn_prepareToRoaming(pRoamingMngr->hAPConnection, pRoamingMngr->roamingTrigger);
   1443 
   1444     /* Get the current BSSIDs from ScanMngr */
   1445 #if 0
   1446     pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
   1447 #else
   1448     pRoamingMngr->pListOfAPs = NULL; /* force immediate scan */
   1449 #endif
   1450     if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
   1451     {   /* No need to SCAN, start SELECTING */
   1452         roamingEvent = ROAMING_EVENT_SELECT;
   1453     }
   1454     else
   1455     {   /* check if list of APs exists in order to verify which scan to start */
   1456         roamingEvent = ROAMING_EVENT_SCAN;
   1457         if (pRoamingMngr->neighborApsExist)
   1458         {   /* Scan only Neighbor APs */
   1459             pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN;
   1460         }
   1461         else
   1462         {   /* Scan all channels */
   1463             pRoamingMngr->scanType = ROAMING_FULL_SCAN;
   1464         }
   1465     }
   1466     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1467                 ("roamingMngr_smRoamTrigger, scanType = %d\n", pRoamingMngr->scanType));
   1468 
   1469     return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, roamingEvent, pRoamingMngr));
   1470 }
   1471 
   1472 /**
   1473 *
   1474 * roamingMngr_smInvokeScan
   1475 *
   1476 * \b Description:
   1477 *
   1478 * This procedure is called when scan should be performed in order
   1479  * to select an AP to roam to.
   1480  * This can be the first scan, a second scan after partail scan,
   1481  * or scan after previous scan was failed.
   1482  * In any case, the scan can either be:
   1483  *  partail, on list of channles or
   1484  *  full on all channels.
   1485 *
   1486 * \b ARGS:
   1487 *
   1488 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1489 *
   1490 * \b RETURNS:
   1491 *
   1492 *  OK if successful, NOK otherwise.
   1493 *
   1494 *
   1495 */
   1496 static TI_STATUS roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr)
   1497 {
   1498     roamingMngr_t       *pRoamingMngr;
   1499     scan_mngrResultStatus_e     scanResult;
   1500 
   1501     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1502     if (pRoamingMngr == NULL)
   1503     {
   1504         return NOK;
   1505     }
   1506 
   1507     scanMngrClearBSSListEntry(pRoamingMngr->hScanMngr);
   1508 
   1509     /* check which scan should be performed: Partial on list of channels, or full scan */
   1510     if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
   1511         (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY))
   1512     {
   1513         scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, TRUE);
   1514     }
   1515     else
   1516     {    /* Scan all channels */
   1517         scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, FALSE);
   1518     }
   1519 
   1520     if (scanResult != SCAN_MRS_SCAN_RUNNING)
   1521     {   /* the scan failed, immitate scan complete event */
   1522         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1523                     ("roamingMngr_smInvokeScan, scanResult = %d\n", scanResult));
   1524         roamingMngr_immediateScanComplete(pRoamingMngr, scanResult);
   1525     }
   1526     return OK;
   1527 
   1528 }
   1529 
   1530 /**
   1531 *
   1532 * roamingMngr_smSelection
   1533 *
   1534 * \b Description:
   1535 *
   1536 * This procedure is called when selection should be performed.
   1537 *   It perform the following:
   1538  * Prepare the candidate APs to roam according to:
   1539  *  - Priority APs
   1540  *  - Pre-Authenticated APs
   1541  * If the candidate AP list is empty, only the current AP can be re-selected
   1542  * Select one AP and trigger REQ_HANDOVER event.
   1543  *
   1544 * \b ARGS:
   1545 *
   1546 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1547 *
   1548 * \b RETURNS:
   1549 *
   1550 *  OK if successful, NOK otherwise.
   1551 *
   1552 *
   1553 */
   1554 static TI_STATUS roamingMngr_smSelection(TI_HANDLE hRoamingMngr)
   1555 {
   1556     roamingMngr_t               *pRoamingMngr;
   1557     UINT32                      index;
   1558 
   1559 
   1560     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1561     if (pRoamingMngr == NULL)
   1562     {
   1563         return NOK;
   1564     }
   1565 
   1566 
   1567     pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
   1568     pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
   1569     pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;
   1570 
   1571     pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
   1572 
   1573     if ((pRoamingMngr->pListOfAPs == NULL) ||
   1574         (pRoamingMngr->pListOfAPs->numOfEntries == 0))
   1575     {   /* Error, there cannot be selection  */
   1576         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1577                           ("roamingMngr_smSelection pListOfAPs is empty \n"));
   1578         return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr));
   1579     }
   1580 
   1581     /* Build the candidate AP list */
   1582     for (index=0; index<pRoamingMngr->pListOfAPs->numOfEntries; index++ )
   1583     {
   1584         if ( (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP) &&
   1585             (pRoamingMngr->pListOfAPs->BSSList[index].RSSI < pRoamingMngr->roamingMngrConfig.apQualityThreshold))
   1586         {   /* Do not insert APs with low quality to the selection table,
   1587                 if the Roaming Trigger was low Quality */
   1588             WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1589                               ("candidate AP %x-%x-%x-%x-%x-%x with RSSI too low =%d, Quality=%d  \n",
   1590                                pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[0],
   1591                                pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[1],
   1592                                pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[2],
   1593                                pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[3],
   1594                                pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[4],
   1595                                pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[5],
   1596                                pRoamingMngr->pListOfAPs->BSSList[index].RSSI,
   1597                                pRoamingMngr->roamingMngrConfig.apQualityThreshold));
   1598 
   1599             continue;
   1600         }
   1601 
   1602         if (apConn_isSiteBanned(pRoamingMngr->hAPConnection, &pRoamingMngr->pListOfAPs->BSSList[index].BSSID) == TRUE)
   1603         {
   1604             WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1605                     ("%s: Candidate AP %02X-%02X-%02X-%02X-%02X-%02X is banned!\n", __FUNCTION__,
   1606                             pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[0],
   1607                             pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[1],
   1608                             pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[2],
   1609                             pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[3],
   1610                             pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[4],
   1611                             pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[5]));
   1612             continue;
   1613         }
   1614 
   1615         if (pRoamingMngr->pListOfAPs->BSSList[index].bNeighborAP)
   1616         {   /* The AP is a neighbor AP, insert its index to the neighbor APs list */
   1617             pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS] = index;
   1618             pRoamingMngr->listOfCandidateAps.numOfNeighborBSS++;
   1619         }
   1620         else if (apConn_getPreAuthAPStatus(pRoamingMngr->hAPConnection,
   1621                         &pRoamingMngr->pListOfAPs->BSSList[index].BSSID))
   1622         {   /* This AP is a pre-auth AP */
   1623             pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS] = index;
   1624             pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS++;
   1625         }
   1626         else
   1627         {   /* This AP is not Neighbor nor Pre-Auth */
   1628             pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS] = index;
   1629             pRoamingMngr->listOfCandidateAps.numOfRegularBSS++;
   1630         }
   1631     }
   1632 
   1633 #ifdef TI_DBG
   1634     {   /* for debug */
   1635         paramInfo_t     param;
   1636 
   1637         param.paramType = ROAMING_MNGR_PRINT_CANDIDATE_TABLE;
   1638         roamingMngr_getParam(pRoamingMngr, &param);
   1639 
   1640     }
   1641 #endif
   1642     return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr));
   1643 
   1644 }
   1645 
   1646 
   1647 
   1648 /**
   1649 *
   1650 * roamingMngr_smHandover
   1651 *
   1652 * \b Description:
   1653 *
   1654 * This procedure is called when handover should be invoked.
   1655 *   Go over the candidate APs and start handover to each of them.
   1656  * If there's no candidate APs, disconnect.
   1657  * Handover to the current AP is allowed only if the trigger is
   1658  * low quality.
   1659  *
   1660 * \b ARGS:
   1661 *
   1662 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1663 *
   1664 * \b RETURNS:
   1665 *
   1666 *  OK if successful, NOK otherwise.
   1667 *
   1668 *
   1669 */
   1670 static TI_STATUS roamingMngr_smHandover(TI_HANDLE hRoamingMngr)
   1671 {
   1672     roamingMngr_t           *pRoamingMngr;
   1673     bssEntry_t              *pApToConnect;
   1674     apConn_connRequest_t    requestToApConn;
   1675 
   1676     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1677     if (pRoamingMngr == NULL)
   1678     {
   1679         return NOK;
   1680     }
   1681 
   1682 
   1683     if ((pRoamingMngr->handoverWasPerformed) && (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX))
   1684     {   /* Handover with the current AP already failed, Disconnect */
   1685         return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_FAILURE, pRoamingMngr));
   1686     }
   1687     if (pRoamingMngr->listOfCandidateAps.numOfNeighborBSS > 0)
   1688     {   /* Neighbor APs are the highest priority to Roam */
   1689         pRoamingMngr->candidateApIndex =
   1690             pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS-1];
   1691         pRoamingMngr->listOfCandidateAps.numOfNeighborBSS--;
   1692     }
   1693     else if (pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS > 0)
   1694     {   /* Pre-Auth APs are the second priority to Roam */
   1695         pRoamingMngr->candidateApIndex =
   1696             pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS-1];
   1697         pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS--;
   1698     }
   1699     else if (pRoamingMngr->listOfCandidateAps.numOfRegularBSS > 0)
   1700     {   /* Regular APs are APs that are not pre-authenticated and not Neighbor */
   1701         pRoamingMngr->candidateApIndex =
   1702             pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS-1];
   1703         pRoamingMngr->listOfCandidateAps.numOfRegularBSS--;
   1704     }
   1705     else
   1706     {   /* No Candidate APs */
   1707         pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
   1708     }
   1709 
   1710     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1711                       ("roamingMngr_smHandover, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex));
   1712 
   1713 
   1714     if (pRoamingMngr->candidateApIndex == INVALID_CANDIDATE_INDEX)
   1715     {   /* No cnadidate to Roam to, only the current AP is candidate */
   1716         if (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP)
   1717         {   /* If the trigger to Roam is low quality, and there are no candidate APs
   1718                 to roam to, retain connected to the current AP */
   1719             requestToApConn.requestType = (pRoamingMngr->handoverWasPerformed) ? AP_CONNECT_RECONNECT_CURR_AP : AP_CONNECT_RETAIN_CURR_AP;
   1720             pRoamingMngr->candidateApIndex = CURRENT_AP_INDEX;
   1721         }
   1722         else
   1723         {   /* Disconnect the BSS, there are no more APs to roam to */
   1724             return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_FAILURE, pRoamingMngr));
   1725         }
   1726     }
   1727     else
   1728     {   /* There is a valid candidate AP */
   1729         if (pRoamingMngr->roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
   1730         {   /* Full re-connection should be perfromed */
   1731             requestToApConn.requestType = AP_CONNECT_FULL_TO_AP;
   1732         }
   1733         else
   1734         {   /* Fast re-connection should be perfromed */
   1735             requestToApConn.requestType = AP_CONNECT_FAST_TO_AP;
   1736         }
   1737     }
   1738 #ifdef TI_DBG
   1739     /* For debug */
   1740     if (!pRoamingMngr->handoverWasPerformed)
   1741     {   /* Take the time before the first handover started */
   1742         pRoamingMngr->roamingHandoverStartedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
   1743     }
   1744 #endif
   1745 
   1746     if (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX)
   1747     {   /* get the current AP */
   1748         pApToConnect = apConn_getBSSParams(pRoamingMngr->hAPConnection);
   1749     }
   1750     else
   1751     {   /* get the candidate AP */
   1752         pRoamingMngr->handoverWasPerformed = TRUE;
   1753         pApToConnect = &pRoamingMngr->pListOfAPs->BSSList[pRoamingMngr->candidateApIndex];
   1754     }
   1755     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1756                       ("roamingMngr_smHandover, candidateApIndex=%d, requestType = %d, channel=%d \n",
   1757                        pRoamingMngr->candidateApIndex, requestToApConn.requestType, pApToConnect->channel));
   1758 
   1759     requestToApConn.dataBufLength = 0;
   1760     return (apConn_connectToAP(pRoamingMngr->hAPConnection, pApToConnect, &requestToApConn, TRUE));
   1761 }
   1762 
   1763 
   1764 
   1765 /**
   1766 *
   1767 * roamingMngr_smDisconnectWhileConnecting
   1768 *
   1769 * \b Description:
   1770 *
   1771 * This procedure is called when the Station is in the process of connection,
   1772  * and the AP disconnects the station.
   1773  *
   1774 * \b ARGS:
   1775 *
   1776 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1777 *
   1778 * \b RETURNS:
   1779 *
   1780 *  OK if successful, NOK otherwise.
   1781 *
   1782 *
   1783 */
   1784 static TI_STATUS roamingMngr_smDisconnectWhileConnecting(TI_HANDLE hRoamingMngr)
   1785 {
   1786     roamingMngr_t           *pRoamingMngr;
   1787 
   1788     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1789     if (pRoamingMngr == NULL)
   1790     {
   1791         return NOK;
   1792     }
   1793 
   1794     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1795                       ("roamingMngr_smDisconnectWhileConnecting, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex));
   1796 
   1797     if (pRoamingMngr->roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
   1798     {   /* If the trigger is from the Full Connect group, then stop the connection. */
   1799         /* clean intenal variables */
   1800         pRoamingMngr->maskRoamingEvents = TRUE;
   1801         pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   1802 
   1803         scanMngr_stopContScan(pRoamingMngr->hScanMngr);
   1804 #ifdef TI_DBG
   1805         pRoamingMngr->roamingFailedHandoverNum++;
   1806 #endif
   1807         return (apConn_disconnect(pRoamingMngr->hAPConnection));
   1808 
   1809     }
   1810 
   1811     return OK;
   1812 
   1813 }
   1814 
   1815 /**
   1816 *
   1817 * roamingMngr_smSuccHandover
   1818 *
   1819 * \b Description:
   1820 *
   1821 * This procedure is called when handover succeeded.
   1822  * Inform Scan Manager about the new AP.
   1823  * UnMask Roaming Triggers.
   1824  *
   1825 * \b ARGS:
   1826 *
   1827 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1828 *
   1829 * \b RETURNS:
   1830 *
   1831 *  OK if successful, NOK otherwise.
   1832 *
   1833 *
   1834 */
   1835 static TI_STATUS roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr)
   1836 {
   1837     roamingMngr_t           *pRoamingMngr;
   1838     bssEntry_t              *pNewConnectedAp;
   1839 
   1840     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1841     if (pRoamingMngr == NULL)
   1842     {
   1843         return NOK;
   1844     }
   1845 
   1846     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1847                       ("roamingMngr_smSuccHandover, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex));
   1848 
   1849     if (pRoamingMngr->handoverWasPerformed &&
   1850         (pRoamingMngr->pListOfAPs != NULL) &&
   1851         (pRoamingMngr->pListOfAPs->numOfEntries>0))
   1852     {
   1853         if (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX)
   1854         {   /* get the current AP */
   1855             pNewConnectedAp = apConn_getBSSParams(pRoamingMngr->hAPConnection);
   1856         }
   1857         else
   1858         {   /* get the candidate AP */
   1859             pNewConnectedAp = &pRoamingMngr->pListOfAPs->BSSList[pRoamingMngr->candidateApIndex];
   1860         }
   1861 
   1862         scanMngr_handoverDone(pRoamingMngr->hScanMngr,
   1863                           &pNewConnectedAp->BSSID,
   1864                           pNewConnectedAp->band);
   1865     }
   1866     pRoamingMngr->maskRoamingEvents = FALSE;
   1867     pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
   1868     pRoamingMngr->handoverWasPerformed = FALSE;
   1869     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   1870 
   1871     /* Start pre-authentication in order to set PMKID
   1872         for the current AP */
   1873     if (pRoamingMngr->staCapabilities.authMode==os802_11AuthModeWPA2)
   1874     {   /* No Pre-Auth is required */
   1875 		UINT8 dummy;
   1876 
   1877         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1878                           ("roamingMngr_smStartIdle, Pre-Auth to cur AP\n"));
   1879         apConn_preAuthenticate(pRoamingMngr->hAPConnection, (bssList_t *)&dummy, 0);
   1880     }
   1881 
   1882     return OK;
   1883 }
   1884 
   1885 
   1886 
   1887 
   1888 /**
   1889 *
   1890 * roamingMngr_smFailHandover
   1891 *
   1892 * \b Description:
   1893 *
   1894 * This procedure is called when handover failed and there are no more
   1895  * APs to roam to. Disconnect the BSS and retrun to IDLE state.
   1896 *
   1897 * \b ARGS:
   1898 *
   1899 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1900 *
   1901 * \b RETURNS:
   1902 *
   1903 *  OK if successful, NOK otherwise.
   1904 *
   1905 *
   1906 */
   1907 static TI_STATUS roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr)
   1908 {
   1909     roamingMngr_t           *pRoamingMngr;
   1910 
   1911     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1912     if (pRoamingMngr == NULL)
   1913     {
   1914         return NOK;
   1915     }
   1916 
   1917     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1918                       ("roamingMngr_smFailHandover \n"));
   1919 
   1920     /* clean intenal variables */
   1921     pRoamingMngr->maskRoamingEvents = TRUE;
   1922     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   1923 
   1924     scanMngr_stopContScan(pRoamingMngr->hScanMngr);
   1925 #ifdef TI_DBG
   1926     pRoamingMngr->roamingFailedHandoverNum++;
   1927 #endif
   1928     return (apConn_disconnect(pRoamingMngr->hAPConnection));
   1929 }
   1930 
   1931 
   1932 
   1933 
   1934 /**
   1935 *
   1936 * roamingMngr_smScanFailure
   1937 *
   1938 * \b Description:
   1939 *
   1940 * This procedure is called when all scan attempts failed.
   1941  * Send Disconnect event and return to IDLE state.
   1942  *
   1943 *
   1944 * \b ARGS:
   1945 *
   1946 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1947 *
   1948 * \b RETURNS:
   1949 *
   1950 *  OK if successful, NOK otherwise.
   1951 *
   1952 *
   1953 */
   1954 static TI_STATUS roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr)
   1955 {
   1956     roamingMngr_t           *pRoamingMngr;
   1957 
   1958     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   1959     if (pRoamingMngr == NULL)
   1960     {
   1961         return NOK;
   1962     }
   1963 
   1964     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   1965                       ("roamingMngr_smScanFailure \n"));
   1966 
   1967     /* clean intenal variables */
   1968     pRoamingMngr->maskRoamingEvents = TRUE;
   1969     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   1970 
   1971     scanMngr_stopContScan(pRoamingMngr->hScanMngr);
   1972 
   1973     return (apConn_disconnect(pRoamingMngr->hAPConnection));
   1974 }
   1975 
   1976 #if 0
   1977 /**
   1978 *
   1979 * roamingMngr_smCmdFailure
   1980 *
   1981 * \b Description:
   1982 *
   1983 * This procedure is called when all the driver failed to prepare to Roaming.
   1984  * Mask all future Roaming triggers.
   1985  *
   1986 *
   1987 * \b ARGS:
   1988 *
   1989 *  I   - hRoamingMngr - roamingMngr SM context  \n
   1990 *
   1991 * \b RETURNS:
   1992 *
   1993 *  OK if successful, NOK otherwise.
   1994 *
   1995 *
   1996 */
   1997 static TI_STATUS roamingMngr_smCmdFailure(TI_HANDLE hRoamingMngr)
   1998 {
   1999     roamingMngr_t           *pRoamingMngr;
   2000 
   2001     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   2002     if (pRoamingMngr == NULL)
   2003     {
   2004         return NOK;
   2005     }
   2006 
   2007     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   2008                       ("roamingMngr_smCmdFailure \n"));
   2009 
   2010     /* clean intenal variables */
   2011     pRoamingMngr->maskRoamingEvents = TRUE;
   2012     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   2013 
   2014     return OK;
   2015 
   2016 }
   2017 #endif
   2018 
   2019 /**
   2020 *
   2021 * roamingMngr_smStartIdle - Start event when in Idle state
   2022 *
   2023 * \b Description:
   2024 *
   2025 * Start event when in Idle state.
   2026  * This function is called when the station becomes CONNECTED.
   2027  * Perform the following:
   2028  * - The current state becomes WAIT_4_TRIGGER
   2029  * - Unmask Roaming events
   2030  * - Set handoverWasPerformed to FALSE
   2031  * - Start the Scan Manager
   2032 *
   2033 * \b ARGS:
   2034 *
   2035 *  I   - pData - pointer to the roamingMngr SM context  \n
   2036 *
   2037 * \b RETURNS:
   2038 *
   2039 *  OK if successful, NOK otherwise.
   2040 *
   2041 *
   2042 */
   2043 static TI_STATUS roamingMngr_smStartIdle(void *pData)
   2044 {
   2045     roamingMngr_t       *pRoamingMngr;
   2046     bssEntry_t          *pCurBssEntry;
   2047 
   2048     pRoamingMngr = (roamingMngr_t*)pData;
   2049     if (pRoamingMngr == NULL)
   2050     {
   2051         return NOK;
   2052     }
   2053     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   2054                               ("roamingMngr_smStartIdle, Unmask Roaming events and start continuos scan \n"));
   2055 
   2056     pRoamingMngr->maskRoamingEvents = FALSE;
   2057     pRoamingMngr->handoverWasPerformed = FALSE;
   2058     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   2059 
   2060     pCurBssEntry = apConn_getBSSParams(pRoamingMngr->hAPConnection);
   2061     scanMngr_startContScan(pRoamingMngr->hScanMngr, &pCurBssEntry->BSSID, pCurBssEntry->band);
   2062 
   2063     /* Start pre-authentication in order to set PMKID
   2064         for the current AP */
   2065     if (pRoamingMngr->staCapabilities.authMode==os802_11AuthModeWPA2)
   2066     {   /* No Pre-Auth is required */
   2067 		UINT8 				dummy;
   2068         WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   2069                           ("roamingMngr_smStartIdle, Pre-Auth to cur AP\n"));
   2070         apConn_preAuthenticate(pRoamingMngr->hAPConnection, (bssList_t *)&dummy, 0);
   2071     }
   2072 
   2073     return OK;
   2074 }
   2075 
   2076 
   2077 
   2078 /**
   2079 *
   2080 * roamingMngr_smNop - Do nothing
   2081 *
   2082 * \b Description:
   2083 *
   2084 * Do nothing in the SM.
   2085 *
   2086 * \b ARGS:
   2087 *
   2088 *  I   - pData - pointer to the roamingMngr SM context  \n
   2089 *
   2090 * \b RETURNS:
   2091 *
   2092 *  OK if successful, NOK otherwise.
   2093 *
   2094 *
   2095 */
   2096 static TI_STATUS roamingMngr_smNop(void *pData)
   2097 {
   2098     roamingMngr_t       *pRoamingMngr;
   2099 
   2100     pRoamingMngr = (roamingMngr_t*)pData;
   2101     if (pRoamingMngr == NULL)
   2102     {
   2103         return NOK;
   2104     }
   2105     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   2106                 (" roamingMngr_smNop\n"));
   2107 
   2108     return OK;
   2109 }
   2110 
   2111 /**
   2112 *
   2113 * roamingMngr_smUnexpected - Unexpected event
   2114 *
   2115 * \b Description:
   2116 *
   2117 * Unexpected event in the SM.
   2118 *
   2119 * \b ARGS:
   2120 *
   2121 *  I   - pData - pointer to the roamingMngr SM context  \n
   2122 *
   2123 * \b RETURNS:
   2124 *
   2125 *  OK if successful, NOK otherwise.
   2126 *
   2127 *
   2128 */
   2129 static TI_STATUS roamingMngr_smUnexpected(void *pData)
   2130 {
   2131     roamingMngr_t       *pRoamingMngr;
   2132 
   2133     pRoamingMngr = (roamingMngr_t*)pData;
   2134     if (pRoamingMngr == NULL)
   2135     {
   2136         return NOK;
   2137     }
   2138     WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   2139                 (" roamingMngr_smUnexpected, state = %d\n", pRoamingMngr->currentState));
   2140 
   2141     return NOK;
   2142 }
   2143 
   2144 
   2145 
   2146 
   2147 
   2148 /**
   2149 *
   2150 * roamingMngr_smStop - Stop all timers and clean DB
   2151 *
   2152 * \b Description:
   2153 *
   2154 * Stop event in start state. Stop timers, clean internal vars
   2155  *  and exit PS if necessary.
   2156 *
   2157 * \b ARGS:
   2158 *
   2159 *  I   - pData - pointer to the roamingMngr SM context  \n
   2160 *
   2161 * \b RETURNS:
   2162 *
   2163 *  OK if successful, NOK otherwise.
   2164 *
   2165 *
   2166 */
   2167 static TI_STATUS roamingMngr_smStop(void *pData)
   2168 {
   2169     roamingMngr_t       *pRoamingMngr;
   2170 
   2171     pRoamingMngr = (roamingMngr_t*)pData;
   2172     if (pRoamingMngr == NULL)
   2173     {
   2174         return NOK;
   2175     }
   2176     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   2177                 (" roamingMngr_smStop\n"));
   2178 
   2179     scanMngr_stopContScan(pRoamingMngr->hScanMngr);
   2180     /* clean intenal variables */
   2181     pRoamingMngr->maskRoamingEvents = TRUE;
   2182     pRoamingMngr->neighborApsExist = FALSE;
   2183     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   2184 
   2185     return OK;
   2186 }
   2187 /**
   2188 *
   2189 * roamingMngr_smStopWhileScanning -
   2190 *
   2191 * \b Description:
   2192 *
   2193 * Stop event means that the station is not in Connected State.
   2194  * Stop continuos and immediate scans and clean internal vars.
   2195 *
   2196 * \b ARGS:
   2197 *
   2198 *  I   - pData - pointer to the roamingMngr SM context  \n
   2199 *
   2200 * \b RETURNS:
   2201 *
   2202 *  OK if successful, NOK otherwise.
   2203 *
   2204 *
   2205 */
   2206 static TI_STATUS roamingMngr_smStopWhileScanning(void *pData)
   2207 {
   2208     roamingMngr_t       *pRoamingMngr;
   2209 
   2210     pRoamingMngr = (roamingMngr_t*)pData;
   2211     if (pRoamingMngr == NULL)
   2212     {
   2213         return NOK;
   2214     }
   2215     WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
   2216                 (" roamingMngr_smStopWhileScanning\n"));
   2217 
   2218     scanMngr_stopImmediateScan(pRoamingMngr->hScanMngr);
   2219     scanMngr_stopContScan(pRoamingMngr->hScanMngr);
   2220 
   2221     /* clean intenal variables */
   2222     pRoamingMngr->maskRoamingEvents = TRUE;
   2223     pRoamingMngr->neighborApsExist = FALSE;
   2224     pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
   2225 
   2226     return OK;
   2227 }
   2228 
   2229 
   2230 #ifdef TI_DBG
   2231 /**
   2232 *
   2233 * roamingMngr_debugTrace
   2234 *
   2235 * \b Description:
   2236 *
   2237 * This procedure is called for debug only, to trace the roaming triggers and events
   2238 *
   2239 * \b ARGS:
   2240 *
   2241 *  I   - hRoamingMngr - roamingMngr SM context  \n
   2242 *
   2243 * \b RETURNS:
   2244 *
   2245 *  OK if successful, NOK otherwise.
   2246 *
   2247 *
   2248 */
   2249 static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr)
   2250 {
   2251 
   2252 
   2253     roamingMngr_t       *pRoamingMngr;
   2254     UINT8               index;
   2255 
   2256     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   2257     if (pRoamingMngr == NULL)
   2258     {
   2259         return;
   2260     }
   2261 
   2262     WLAN_OS_REPORT(("******** ROAMING_TRIGGERS ********\n"));
   2263     for (index=ROAMING_TRIGGER_LOW_TX_RATE; index<ROAMING_TRIGGER_LAST; index++)
   2264     {
   2265         switch (index)
   2266         {
   2267         case ROAMING_TRIGGER_LOW_TX_RATE:
   2268             WLAN_OS_REPORT(("- Low TX rate = %d\n",     pRoamingMngr->roamingTriggerEvents[index]));
   2269             break;
   2270         case ROAMING_TRIGGER_LOW_SNR:
   2271             WLAN_OS_REPORT(("- Low Snr = %d\n",         pRoamingMngr->roamingTriggerEvents[index]));
   2272             break;
   2273         case ROAMING_TRIGGER_LOW_QUALITY:
   2274             WLAN_OS_REPORT(("- Low Quality = %d\n",     pRoamingMngr->roamingTriggerEvents[index]));
   2275             break;
   2276         case ROAMING_TRIGGER_MAX_TX_RETRIES:
   2277             WLAN_OS_REPORT(("- MAX TX retries = %d\n",  pRoamingMngr->roamingTriggerEvents[index]));
   2278             break;
   2279         case ROAMING_TRIGGER_BSS_LOSS:
   2280             WLAN_OS_REPORT(("- BSS Loss TX = %d\n",     pRoamingMngr->roamingTriggerEvents[index]));
   2281             break;
   2282         case ROAMING_TRIGGER_SWITCH_CHANNEL:
   2283             WLAN_OS_REPORT(("- Switch Channel = %d\n",  pRoamingMngr->roamingTriggerEvents[index]));
   2284             break;
   2285         case ROAMING_TRIGGER_AP_DISCONNECT:
   2286             WLAN_OS_REPORT(("- AP Disconnect = %d\n",   pRoamingMngr->roamingTriggerEvents[index]));
   2287             break;
   2288         case ROAMING_TRIGGER_SECURITY_ATTACK:
   2289             WLAN_OS_REPORT(("- SEC attack = %d\n",      pRoamingMngr->roamingTriggerEvents[index]));
   2290             break;
   2291         default:
   2292             break;
   2293         }
   2294     }
   2295 
   2296     WLAN_OS_REPORT(("******** Succ ROAMING_HANDOVERS ********\n"));
   2297 
   2298     for (index=ROAMING_TRIGGER_LOW_QUALITY; index<ROAMING_TRIGGER_LAST; index++)
   2299     {
   2300         switch (index)
   2301         {
   2302         case ROAMING_TRIGGER_LOW_TX_RATE:
   2303             WLAN_OS_REPORT(("- Low TX rate = %d\n",     pRoamingMngr->roamingHandoverEvents[index]));
   2304             break;
   2305         case ROAMING_TRIGGER_LOW_SNR:
   2306             WLAN_OS_REPORT(("- Low Snre = %d\n",        pRoamingMngr->roamingHandoverEvents[index]));
   2307             break;
   2308         case ROAMING_TRIGGER_LOW_QUALITY:
   2309             WLAN_OS_REPORT(("- Low Quality = %d\n",     pRoamingMngr->roamingHandoverEvents[index]));
   2310             break;
   2311         case ROAMING_TRIGGER_MAX_TX_RETRIES:
   2312             WLAN_OS_REPORT(("- MAX TX retries = %d\n",  pRoamingMngr->roamingHandoverEvents[index]));
   2313             break;
   2314         case ROAMING_TRIGGER_BSS_LOSS:
   2315             WLAN_OS_REPORT(("- BSS Loss TX = %d\n",     pRoamingMngr->roamingHandoverEvents[index]));
   2316             break;
   2317         case ROAMING_TRIGGER_SWITCH_CHANNEL:
   2318             WLAN_OS_REPORT(("- Switch Channel = %d\n",   pRoamingMngr->roamingHandoverEvents[index]));
   2319             break;
   2320         case ROAMING_TRIGGER_AP_DISCONNECT:
   2321             WLAN_OS_REPORT(("- AP Disconnect = %d\n",   pRoamingMngr->roamingHandoverEvents[index]));
   2322             break;
   2323         case ROAMING_TRIGGER_SECURITY_ATTACK:
   2324             WLAN_OS_REPORT(("- SEC attack = %d\n",      pRoamingMngr->roamingHandoverEvents[index]));
   2325             break;
   2326         default:
   2327             break;
   2328         }
   2329     }
   2330 
   2331     WLAN_OS_REPORT(("******** ROAMING STATISTICS ********\n"));
   2332     WLAN_OS_REPORT(("- Num of succesful handovers = %d\n", pRoamingMngr->roamingSuccesfulHandoverNum));
   2333     WLAN_OS_REPORT(("- Num of failed handovers = %d\n", pRoamingMngr->roamingFailedHandoverNum));
   2334     if (pRoamingMngr->roamingSuccesfulHandoverNum >0)
   2335     {
   2336         WLAN_OS_REPORT(("- Succesful average succesful handover duration = %d\n", pRoamingMngr->roamingAverageSuccHandoverDuration/pRoamingMngr->roamingSuccesfulHandoverNum));
   2337         WLAN_OS_REPORT(("- Succesful average roaming duration = %d\n", pRoamingMngr->roamingAverageRoamingDuration/pRoamingMngr->roamingSuccesfulHandoverNum));
   2338     }
   2339 
   2340 
   2341 }
   2342 
   2343 
   2344 /**
   2345 *
   2346 * roamingMngr_resetDebugTrace
   2347 *
   2348 * \b Description:
   2349 *
   2350 * This procedure is called for debug only, to reset Roaming debug trace
   2351 *
   2352 * \b ARGS:
   2353 *
   2354 *  I   - hRoamingMngr - roamingMngr SM context  \n
   2355 *
   2356 * \b RETURNS:
   2357 *
   2358 *  OK if successful, NOK otherwise.
   2359 *
   2360 *
   2361 */
   2362 static void roamingMngr_resetStatistics(TI_HANDLE hRoamingMngr)
   2363 {
   2364 
   2365     roamingMngr_t       *pRoamingMngr;
   2366     UINT8               index;
   2367 
   2368     pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
   2369     if (pRoamingMngr == NULL)
   2370     {
   2371         return;
   2372     }
   2373     WLAN_OS_REPORT(("Resetting all ROAMING_EVENTS \n"));
   2374 
   2375     pRoamingMngr->roamingSuccesfulHandoverNum = 0;
   2376     pRoamingMngr->roamingHandoverStartedTimestamp = 0;
   2377     pRoamingMngr->roamingHandoverCompletedTimestamp = 0;
   2378     pRoamingMngr->roamingAverageSuccHandoverDuration = 0;
   2379     pRoamingMngr->roamingAverageRoamingDuration = 0;
   2380     pRoamingMngr->roamingFailedHandoverNum = 0;
   2381 
   2382     for (index=ROAMING_TRIGGER_LOW_QUALITY; index<ROAMING_TRIGGER_LAST; index++)
   2383     {
   2384         pRoamingMngr->roamingHandoverEvents[index] = 0;
   2385         pRoamingMngr->roamingTriggerEvents[index] = 0;
   2386     }
   2387 }
   2388 
   2389 #endif /*TI_DBG*/
   2390