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 */ 84typedef 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 */ 96typedef 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 */ 110typedef 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 */ 120typedef 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 137typedef struct _roamingMngr_t roamingMngr_t; 138/* Structures */ 139typedef 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 151struct _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 217static 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 226static 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 */ 241static TI_STATUS roamingMngr_smEvent(UINT8 *currState, UINT8 event, void* data); 242static TI_STATUS roamingMngr_smUnexpected(void *pData); 243static TI_STATUS roamingMngr_smNop(void *pData); 244static TI_STATUS roamingMngr_smStartIdle(void *pData); 245static TI_STATUS roamingMngr_smStop(void *pData); 246static TI_STATUS roamingMngr_smStopWhileScanning(void *pData); 247static TI_STATUS roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr); 248static TI_STATUS roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr); 249static TI_STATUS roamingMngr_smSelection(TI_HANDLE hRoamingMngr); 250static TI_STATUS roamingMngr_smHandover(TI_HANDLE hRoamingMngr); 251static TI_STATUS roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr); 252static TI_STATUS roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr); 253static TI_STATUS roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr); 254static 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 */ 260TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData); 261/* called when CONN status event occurs */ 262TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData); 263/* called when Neighbor APs is updated */ 264TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData); 265 266/* internal functions */ 267static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, UINT32 initVec); 268 269#ifdef TI_DBG 270/* debug function */ 271static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr); 272static 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*/ 294TI_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*/ 342static 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*/ 381TI_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 422TI_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 */ 597extern 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*/ 618TI_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*/ 759TI_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*/ 931TI_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*/ 1047TI_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*/ 1131TI_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*/ 1187TI_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*/ 1295TI_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*/ 1356static 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*/ 1421static 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*/ 1496static 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*/ 1554static 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*/ 1670static 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*/ 1784static 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*/ 1835static 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*/ 1907static 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*/ 1954static 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*/ 1997static 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*/ 2043static 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*/ 2096static 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*/ 2129static 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*/ 2167static 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*/ 2206static 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*/ 2249static 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*/ 2362static 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