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 *)¶m; 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,¶m); 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, ¶m); 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