1 /* 2 * scanMngr.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /** \file scanMngr.c 35 * \brief This file include the scan manager module implementation 36 * 37 * \see scanMngr.h, scanMngrApi.h scanMngrTypes.h 38 */ 39 40 41 #define __FILE_ID__ FILE_ID_9 42 #include "TWDriver.h" 43 #include "roamingMngrApi.h" 44 #include "osApi.h" 45 #include "timer.h" 46 #include "ScanCncn.h" 47 #include "report.h" 48 #include "regulatoryDomainApi.h" 49 #include "siteMgrApi.h" 50 #include "scanMngr.h" 51 #include "DrvMainModules.h" 52 #include "EvHandler.h" 53 #include "apConnApi.h" 54 55 56 /* 57 *********************************************************************** 58 * Internal functions 59 *********************************************************************** 60 */ 61 /*************************************************************************** 62 * reminder64 * 63 **************************************************************************** 64 DESCRIPTION: returns the reminder of a 64 bit number division by a 32 65 bit number. 66 67 INPUT: The dividee (64 bit number to divide) 68 The divider (32 bit number to divide by) 69 70 OUTPUT: 71 72 73 RETURN: The reminder 74 ****************************************************************************/ 75 static TI_UINT32 reminder64( TI_UINT64 dividee, TI_UINT32 divider ) 76 { 77 TI_UINT32 divideeHigh, divideeLow, partA, partB, mod28n, mod24n, mod16n, partA8n, mod8n, mod4n; 78 79 divideeHigh = INT64_HIGHER( dividee ); 80 divideeLow = INT64_LOWER( dividee ); 81 82 mod8n = 256 % divider; 83 mod4n = 16 % divider; 84 85 partA = (mod4n * (divideeHigh % divider)) % divider; 86 partA8n = (partA * mod4n) % divider; 87 mod16n = (partA8n * mod8n) % divider; 88 mod24n = (mod8n * mod16n) % divider; 89 mod28n = (mod4n * mod24n) % divider; 90 91 partB = (mod4n * mod28n) % divider; 92 return ( partB + (divideeLow % divider)) % divider; 93 } 94 95 96 97 static void scanMngr_setManualScanDefaultParams(TI_HANDLE hScanMngr) 98 { 99 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 100 101 pScanMngr->manualScanParams.desiredSsid.len = 1; /* will be set by the scan concentrator */ 102 pScanMngr->manualScanParams.scanType= SCAN_TYPE_NORMAL_ACTIVE; 103 pScanMngr->manualScanParams.band = RADIO_BAND_2_4_GHZ; 104 pScanMngr->manualScanParams.probeReqNumber = 3; 105 pScanMngr->manualScanParams.probeRequestRate = RATE_MASK_UNSPECIFIED; 106 } 107 108 109 static void scanMngr_reportContinuousScanResults (TI_HANDLE hScanMngr, EScanCncnResultStatus resultStatus) 110 { 111 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 112 BssListEx_t BssListEx; 113 114 115 if (resultStatus == SCAN_CRS_SCAN_COMPLETE_OK) 116 { 117 BssListEx.pListOfAPs = scanMngr_getBSSList(hScanMngr); 118 BssListEx.scanIsRunning = pScanMngr->bContinuousScanStarted; /* false = stopped */ 119 EvHandlerSendEvent(pScanMngr->hEvHandler, IPC_EVENT_CONTINUOUS_SCAN_REPORT, (TI_UINT8*)&BssListEx, sizeof(BssListEx_t)); 120 } 121 else 122 { 123 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_reportContinuousScanResults failed. scan status %d\n", resultStatus); 124 } 125 } 126 127 128 129 /** 130 * \\n 131 * \date 01-Mar-2005\n 132 * \brief Frees scan manager resources.\n 133 * 134 * Function Scope \e Private.\n 135 * \param hScanMngr - handle to the scan manager object.\n 136 */ 137 void scanMngrFreeMem (TI_HANDLE hScanMngr) 138 { 139 scanMngr_t* pScanMngr = hScanMngr; 140 TI_UINT8 i; 141 142 /* free frame storage space */ 143 for (i = 0; i < MAX_SIZE_OF_BSS_TRACK_LIST; i++) 144 { 145 if (pScanMngr->BSSList.BSSList[i].pBuffer) 146 { 147 os_memoryFree (pScanMngr->hOS, pScanMngr->BSSList.BSSList[i].pBuffer, MAX_BEACON_BODY_LENGTH); 148 } 149 } 150 151 /* free the timer */ 152 if (pScanMngr->hContinuousScanTimer) 153 { 154 tmr_DestroyTimer (pScanMngr->hContinuousScanTimer); 155 } 156 157 /* free the scan manager object */ 158 os_memoryFree (pScanMngr->hOS, hScanMngr, sizeof(scanMngr_t)); 159 } 160 161 /** 162 * \\n 163 * \date 01-Mar-2005\n 164 * \brief Callback used by the scan concentrator for immediate scan result.\n 165 * 166 * Function Scope \e Public.\n 167 * \param hScanMngr - handle to the scan manager object.\n 168 * \param resultStatus - reason for calling this function (frame received / scan complete).\n 169 * \param frameInfo - frame related information (in case of a frame reception).\n 170 * \param SPSStatus - bitmap indicating which channels were scan, in case of an SPS scan.\n 171 */ 172 void scanMngr_immedScanCB( TI_HANDLE hScanMngr, EScanCncnResultStatus resultStatus, 173 TScanFrameInfo* frameInfo, TI_UINT16 SPSStatus ) 174 { 175 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 176 TScanBandPolicy* aPolicy; 177 EScanCncnResultStatus nextResultStatus; 178 179 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_immedScanCB called, hScanMngr=0x%x, resultStatus=%d", hScanMngr, resultStatus); 180 181 switch (resultStatus) 182 { 183 /* if this function is called because a frame was received, update the BSS list accordingly */ 184 case SCAN_CRS_RECEIVED_FRAME: 185 scanMngrUpdateReceivedFrame( hScanMngr, frameInfo ); 186 break; 187 188 /* scan was completed successfuly */ 189 case SCAN_CRS_SCAN_COMPLETE_OK: 190 /* act according to immediate scan state */ 191 switch (pScanMngr->immedScanState) 192 { 193 /* immediate scan on G finished */ 194 case SCAN_ISS_G_BAND: 195 #ifdef TI_DBG 196 pScanMngr->stats.ImmediateGByStatus[ resultStatus ]++; 197 #endif 198 /* check if another scan is needed (this time on A) */ 199 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ ); 200 if ( (NULL != aPolicy) && 201 (SCAN_TYPE_NO_SCAN != aPolicy->immediateScanMethod.scanType)) 202 { 203 /* build scan command */ 204 scanMngrBuildImmediateScanCommand( hScanMngr, aPolicy, pScanMngr->bImmedNeighborAPsOnly ); 205 206 /* if no channels are available, report error */ 207 if ( 0 < pScanMngr->scanParams.numOfChannels ) 208 { 209 /* mark that immediate scan is running on band A */ 210 pScanMngr->immedScanState = SCAN_ISS_A_BAND; 211 212 /* send scan command to scan concentrator */ 213 nextResultStatus = 214 scanCncn_Start1ShotScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED, &(pScanMngr->scanParams)); 215 if ( SCAN_CRS_SCAN_RUNNING != nextResultStatus ) 216 { 217 pScanMngr->immedScanState = SCAN_ISS_IDLE; 218 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start immediate scan on band A, return code %d.\n", resultStatus); 219 #ifdef TI_DBG 220 pScanMngr->stats.ImmediateAByStatus[ nextResultStatus ]++; 221 #endif 222 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK); 223 } 224 } 225 else 226 { 227 /* mark that immediate scan is not running */ 228 pScanMngr->immedScanState = SCAN_ISS_IDLE; 229 230 /* no channels are actually available for scan - notify the roaming manager of the scan complete */ 231 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK); 232 } 233 } 234 else 235 { 236 /* mark that immediate scan is not running */ 237 pScanMngr->immedScanState = SCAN_ISS_IDLE; 238 239 /* otherwise, notify the roaming manager of the scan complete */ 240 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK); 241 } 242 break; 243 244 /* stop immediate scan was requested */ 245 case SCAN_ISS_STOPPING: 246 /* mark that immediate scan is not running */ 247 pScanMngr->immedScanState = SCAN_ISS_IDLE; 248 249 /* notify the roaming manager of the scan complete */ 250 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_STOPPED); 251 break; 252 253 /* Scan completed on A band */ 254 case SCAN_ISS_A_BAND: 255 /* mark that immediate scan is not running */ 256 pScanMngr->immedScanState = SCAN_ISS_IDLE; 257 #ifdef TI_DBG 258 pScanMngr->stats.ImmediateAByStatus[ resultStatus ]++; 259 #endif 260 /* otherwise, notify the roaming manager of the scan complete */ 261 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK); 262 break; 263 264 default: 265 /* should not be at any other stage when CB is invoked */ 266 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediate scan CB called with scan complete TI_OK reason in state:%d", pScanMngr->immedScanState); 267 268 /* reset continuous scan to idle */ 269 pScanMngr->immedScanState = SCAN_ISS_IDLE; 270 break; 271 } 272 break; 273 274 /* scan was completed due to an error! */ 275 default: 276 #ifdef TI_DBG 277 switch (pScanMngr->immedScanState) 278 { 279 case SCAN_ISS_G_BAND: 280 pScanMngr->stats.ImmediateGByStatus[ resultStatus ]++; 281 break; 282 283 case SCAN_ISS_A_BAND: 284 pScanMngr->stats.ImmediateAByStatus[ resultStatus ]++; 285 break; 286 287 default: 288 break; 289 } 290 #endif 291 /* mark that immediate scan is not running */ 292 pScanMngr->immedScanState = SCAN_ISS_IDLE; 293 scanMngr_immediateScanComplete(hScanMngr,scanMngrConvertResultStatus(resultStatus)); 294 break; 295 } 296 } 297 298 /** 299 * \\n 300 * \date 01-Mar-2005\n 301 * \brief Callback used by the scan concentrator for continuous scan result.\n 302 * 303 * Function Scope \e Public.\n 304 * \param hScanMngr - handle to the scan manager object.\n 305 * \param resultStatus - reason for calling this function (frame received / scan complete).\n 306 * \param frameInfo - frame related info (in case of a frame reception).\n 307 * \param SPSStatus - bitmap indicating which channels were scan, in case of an SPS scan.\n 308 */ 309 void scanMngr_contScanCB( TI_HANDLE hScanMngr, EScanCncnResultStatus resultStatus, 310 TScanFrameInfo* frameInfo, TI_UINT16 SPSStatus ) 311 { 312 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 313 TScanBandPolicy *aPolicy; 314 EScanCncnResultStatus nextResultStatus; 315 316 TRACE3( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_contScanCB called, hScanMngr=0x%x, resultStatus=%d, SPSStatus=%d\n", hScanMngr, resultStatus, SPSStatus); 317 318 switch (resultStatus) 319 { 320 /* frame received - update BSS list accordingly */ 321 case SCAN_CRS_RECEIVED_FRAME: 322 scanMngrUpdateReceivedFrame( hScanMngr, frameInfo ); 323 break; 324 325 /* scan was completed successfully - either continue to next stage or simply finish this cycle */ 326 case SCAN_CRS_SCAN_COMPLETE_OK: 327 #ifdef SCAN_MNGR_DBG 328 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Continuous scan completes successfuly.\n"); 329 scanMngrDebugPrintBSSList( hScanMngr ); 330 #endif 331 #ifdef TI_DBG 332 if ( SCAN_TYPE_SPS == pScanMngr->scanParams.scanType ) 333 { 334 int i; 335 336 /*update SPS channels attendant statistics */ 337 for ( i = 0; i < pScanMngr->scanParams.numOfChannels; i++ ) 338 { 339 if ( TI_FALSE == WAS_SPS_CHANNEL_ATTENDED( SPSStatus, i )) 340 { 341 pScanMngr->stats.SPSChannelsNotAttended[ i ]++; 342 } 343 } 344 } 345 #endif 346 347 /* first, remove APs that were not tracked. Note that this function does NOT 348 increase the retry counter, and therefore there's no harm in calling it even if only 349 some of the APs were searched in the previous tracking command, or previous command was 350 discovery */ 351 scanMngrPerformAging( hScanMngr ); 352 353 354 /* if new BSS's were found (or enough scan iterations passed w/o finding any), notify the roaming manager */ 355 if ( ((TI_TRUE == pScanMngr->bNewBSSFound) || 356 (SCAN_MNGR_CONSEC_SCAN_ITER_FOR_PRE_AUTH < pScanMngr->consecNotFound)) && 357 (pScanMngr->BSSList.numOfEntries > 0)) /* in case no AP was found for specified iterations number, 358 but no AP is present, and so is pre-auth */ 359 { 360 pScanMngr->bNewBSSFound = TI_FALSE; 361 pScanMngr->consecNotFound = 0; 362 roamingMngr_updateNewBssList( pScanMngr->hRoamingMngr, (bssList_t*)&(pScanMngr->BSSList)); 363 364 if (SCANNING_OPERATIONAL_MODE_MANUAL == pScanMngr->scanningOperationalMode) 365 { 366 scanMngr_reportContinuousScanResults(hScanMngr, resultStatus); 367 } 368 } 369 370 /* act according to continuous scan state */ 371 switch (pScanMngr->contScanState) 372 { 373 case SCAN_CSS_TRACKING_G_BAND: 374 #ifdef TI_DBG 375 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++; 376 #endif 377 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n Starting SCAN_CSS_TRACKING_G_BAND \n"); 378 /* if necessary, attempt tracking on A */ 379 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ ); 380 /* if a policy is defined for A band tracking, attempt to perform it */ 381 if ( (NULL != aPolicy) && 382 (SCAN_TYPE_NO_SCAN != aPolicy->trackingMethod.scanType)) 383 { 384 /* recalculate current TSF, to adjust the TSF read at the beginning of 385 the continuous scan process with the tracking on G duration */ 386 pScanMngr->currentTSF += 387 ((os_timeStampMs( pScanMngr->hOS ) - pScanMngr->currentHostTimeStamp) * 1000); 388 389 /* build scan command */ 390 scanMngrBuildTrackScanCommand( hScanMngr, aPolicy, RADIO_BAND_5_0_GHZ ); 391 392 /* if channels are available for tracking on A */ 393 if ( 0 < pScanMngr->scanParams.numOfChannels ) 394 { 395 /* mark that continuous scan is now tracking on A */ 396 pScanMngr->contScanState = SCAN_CSS_TRACKING_A_BAND; 397 398 /* send scan command */ 399 nextResultStatus = 400 scanCncn_Start1ShotScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT, &(pScanMngr->scanParams)); 401 if ( SCAN_CRS_SCAN_RUNNING != nextResultStatus ) 402 { 403 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start tracking continuous scan on band A, return code %d.\n", resultStatus); 404 #ifdef TI_DBG 405 pScanMngr->stats.TrackingAByStatus[ nextResultStatus ]++; 406 #endif 407 pScanMngr->contScanState = SCAN_CSS_IDLE; 408 } 409 #ifdef SCAN_MNGR_DBG 410 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Tracking on A started.\n"); 411 #endif 412 return; 413 } 414 } 415 /* in case a TSF error was received on last continuous scan cycle, mark (now, that tracking 416 on both bands was attempted), that TSF values are synchronized */ 417 pScanMngr->bSynchronized = TI_TRUE; 418 419 /* the break is missing on purpose: if tracking on A was not successful (or not needed), continue to discovery */ 420 421 case SCAN_CSS_TRACKING_A_BAND: 422 #ifdef TI_DBG 423 /* update stats - since there's no break above, we must check that the state is indeed tracking on A */ 424 if ( SCAN_CSS_TRACKING_A_BAND == pScanMngr->contScanState ) 425 { 426 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++; 427 } 428 #endif 429 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n SCAN_CSS_TRACKING_A_BAND \n"); 430 /* if necessary and possible, attempt discovery */ 431 if ( (SCAN_SDP_NO_DISCOVERY != pScanMngr->currentDiscoveryPart) && 432 (pScanMngr->BSSList.numOfEntries <= pScanMngr->scanPolicy.BSSNumberToStartDiscovery)) 433 { 434 /* build scan command */ 435 scanMngrBuildDiscoveryScanCommand( hScanMngr ); 436 437 /* if channels are available for discovery */ 438 if ( 0 < pScanMngr->scanParams.numOfChannels ) 439 { 440 /* mark that continuous scan is now in discovery state */ 441 pScanMngr->contScanState = SCAN_CSS_DISCOVERING; 442 443 /* mark that no new APs were discovered in this discovery operation */ 444 pScanMngr->bNewBSSFound = TI_FALSE; 445 446 /* send scan command */ 447 nextResultStatus = 448 scanCncn_Start1ShotScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT, &(pScanMngr->scanParams)); 449 if ( SCAN_CRS_SCAN_RUNNING != nextResultStatus ) 450 { 451 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start discovery continuous scan, nextResultStatus %d.\n", nextResultStatus); 452 pScanMngr->contScanState = SCAN_CSS_IDLE; 453 } 454 #ifdef SCAN_MNGR_DBG 455 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Disocvery started.\n"); 456 #endif 457 return; 458 } 459 } 460 461 /* the break is missing on purpose: if discovery was not successful (or not needed), finish scan cycle */ 462 463 case SCAN_CSS_DISCOVERING: 464 #ifdef TI_DBG 465 /* update stats - since there's no break above, we must check that the state is indeed discocery */ 466 if ( SCAN_CSS_DISCOVERING == pScanMngr->contScanState ) 467 { 468 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand ) 469 { 470 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++; 471 } 472 else 473 { 474 pScanMngr->stats.DiscoveryAByStatus[ resultStatus ]++; 475 } 476 } 477 #endif 478 /* continuous scan cycle is complete */ 479 pScanMngr->contScanState = SCAN_CSS_IDLE; 480 481 break; 482 483 case SCAN_CSS_STOPPING: 484 /* continuous scan cycle is complete */ 485 pScanMngr->contScanState = SCAN_CSS_IDLE; 486 break; 487 488 default: 489 /* should not be at any other stage when CB is invoked */ 490 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Continuous scan CB called with scan complete TI_OK reason in state:%d\n", pScanMngr->contScanState); 491 492 /* reset continuous scan to idle */ 493 pScanMngr->contScanState = SCAN_CSS_IDLE; 494 pScanMngr->bNewBSSFound = TI_FALSE; 495 break; 496 } 497 break; 498 499 /* SPS scan was completed with TSF error */ 500 case SCAN_CRS_TSF_ERROR: 501 /* report the recovery event */ 502 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Continuous scan callback called with TSF error indication\n"); 503 /* mark that the TSF values are no longer valid */ 504 pScanMngr->bSynchronized = TI_FALSE; 505 #ifdef TI_DBG 506 switch ( pScanMngr->contScanState ) 507 { 508 case SCAN_CSS_TRACKING_G_BAND: 509 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++; 510 break; 511 512 case SCAN_CSS_TRACKING_A_BAND: 513 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++; 514 break; 515 516 default: 517 break; 518 } 519 #endif 520 /* stop continuous scan cycle for this time (to avoid tracking using discovery only on A, thus 521 having mixed results - some are synchronized, some are not */ 522 pScanMngr->contScanState = SCAN_CSS_IDLE; 523 break; 524 525 default: 526 /* report the status received */ 527 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Continuous scan CB called with status %d\n", resultStatus); 528 529 /* also perform aging (since it does not increase counter, no harm done if this was not tracking */ 530 scanMngrPerformAging( hScanMngr ); 531 #ifdef TI_DBG 532 switch ( pScanMngr->contScanState ) 533 { 534 case SCAN_CSS_TRACKING_G_BAND: 535 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++; 536 break; 537 538 case SCAN_CSS_TRACKING_A_BAND: 539 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++; 540 break; 541 542 case SCAN_CSS_DISCOVERING: 543 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand ) 544 { 545 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++; 546 } 547 else 548 { 549 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++; 550 } 551 default: 552 break; 553 } 554 #endif 555 /* finish scan for this iteration */ 556 pScanMngr->contScanState = SCAN_CSS_IDLE; 557 break; 558 } 559 } 560 561 /** 562 * \\n 563 * \date 01-Mar-2005\n 564 * \brief Sets the scan policy.\n 565 * 566 * Function Scope \e Public.\n 567 * \param hScanMngr - handle to the scan manager object.\n 568 * \param scanPolicy - a pointer to the policy data.\n 569 */ 570 void scanMngr_setScanPolicy( TI_HANDLE hScanMngr, TScanPolicy* scanPolicy ) 571 { 572 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 573 574 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setScanPolicy called, hScanMngr=0x%x.\n", hScanMngr); 575 #ifdef SCAN_MNGR_DBG 576 scanMngrTracePrintScanPolicy( scanPolicy ); 577 #endif 578 579 /* if continuous or immediate scan are running, indicate that they shouldn't proceed to next scan (if any), 580 and stop the scan operation (in case a triggered scan was in progress and the voice was stopped, the scan 581 must be stopped or a recovery will occur */ 582 if ( pScanMngr->contScanState != SCAN_CSS_IDLE ) 583 { 584 pScanMngr->contScanState = SCAN_CSS_STOPPING; 585 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT ); 586 } 587 if ( pScanMngr->immedScanState != SCAN_ISS_IDLE ) 588 { 589 pScanMngr->immedScanState = SCAN_ISS_STOPPING; 590 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED ); 591 } 592 593 /* set new scan policy */ 594 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->scanPolicy), scanPolicy, sizeof(TScanPolicy)); 595 596 /* remove all tracked APs that are not on a policy defined channel (neighbor APs haven't changed, 597 so there's no need to check them */ 598 scanMngrUpdateBSSList( hScanMngr, TI_FALSE, TI_TRUE ); 599 600 /* if continuous scan timer is running, stop it */ 601 if (pScanMngr->bTimerRunning) 602 { 603 tmr_StopTimer (pScanMngr->hContinuousScanTimer); 604 pScanMngr->bTimerRunning = TI_FALSE; 605 } 606 607 /* if continuous scan was started, start the timer using the new intervals */ 608 if (pScanMngr->bContinuousScanStarted) 609 { 610 TI_UINT32 uTimeout = pScanMngr->bLowQuality ? 611 pScanMngr->scanPolicy.deterioratingScanInterval : 612 pScanMngr->scanPolicy.normalScanInterval; 613 614 pScanMngr->bTimerRunning = TI_TRUE; 615 616 tmr_StartTimer (pScanMngr->hContinuousScanTimer, 617 scanMngr_GetUpdatedTsfDtimMibForScan, 618 (TI_HANDLE)pScanMngr, 619 uTimeout, 620 TI_TRUE); 621 } 622 623 /* reset discovery counters */ 624 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0; 625 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0; 626 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0; 627 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0; 628 /* set current discovery part to first part */ 629 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G; 630 /* now advance discovery part to first valid part */ 631 scanMngrSetNextDiscoveryPart( hScanMngr ); 632 } 633 634 /** 635 * \\n 636 * \date 06-Feb-2006\n 637 * \brief CB function for current TSF and last beacon TSF and DTIM read.\n 638 * 639 * Function Scope \e Public.\n 640 * \param hScanMngr - handle to the scan manager object.\n 641 * \param status - read status (TI_OK / TI_NOK).\n 642 * \param CB_buf - a pointer to the data read.\n 643 */ 644 void scanMngrGetCurrentTsfDtimMibCB(TI_HANDLE hScanMngr, TI_STATUS status, TI_UINT8* CB_buf) 645 { 646 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 647 648 os_memoryCopy(pScanMngr->hOS, (TI_UINT8*)&(pScanMngr->currTsfDtimMib), CB_buf, sizeof(TTsfDtim)); 649 650 /* set the current TSF and last beacon TSF and DTIM count */ 651 INT64_HIGHER( pScanMngr->currentTSF ) = pScanMngr->currTsfDtimMib.CurrentTSFHigh; 652 INT64_LOWER( pScanMngr->currentTSF ) = pScanMngr->currTsfDtimMib.CurrentTSFLow; 653 654 INT64_HIGHER( pScanMngr->lastLocalBcnTSF ) = pScanMngr->currTsfDtimMib.lastTBTTHigh; 655 INT64_LOWER( pScanMngr->lastLocalBcnTSF ) = pScanMngr->currTsfDtimMib.lastTBTTLow; 656 657 pScanMngr->lastLocalBcnDTIMCount = pScanMngr->currTsfDtimMib.LastDTIMCount; 658 659 TRACE5( pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n currentTSF = %u-%u lastLocalBcnTSF = %u-%u lastDTIMCount = %d \n", INT64_HIGHER( pScanMngr->currentTSF ), INT64_LOWER( pScanMngr->currentTSF ), INT64_HIGHER( pScanMngr->lastLocalBcnTSF ), INT64_LOWER( pScanMngr->lastLocalBcnTSF ), pScanMngr->lastLocalBcnDTIMCount ); 660 661 /* get the current host time stamp */ 662 pScanMngr->currentHostTimeStamp = os_timeStampMs( pScanMngr->hOS ); 663 664 /* now that the current TSF and last beacon TSF had been retrieved from the FW, 665 continuous scan may proceed */ 666 scanMngrPerformContinuousScan(hScanMngr); 667 } 668 669 /** 670 * \\n 671 * \date 06-Feb-2006\n 672 * \brief requests current TSF and last beacon TSF and DTIM from the FW.\n 673 * 674 * Function Scope \e Public.\n 675 * \param hScanMngr - handle to the scan manager object.\n 676 * \param bTwdInitOccured - Indicates if TWDriver recovery occured since timer started.\n 677 */ 678 void scanMngr_GetUpdatedTsfDtimMibForScan (TI_HANDLE hScanMngr, TI_BOOL bTwdInitOccured) 679 { 680 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 681 TTwdParamInfo param; 682 TI_STATUS reqStatus = TI_OK; 683 684 TRACE0( pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\nscanMngr_GetUpdatedTsfDtimMibForScan called\n"); 685 686 /* Getting the current TSF and DTIM values */ 687 param.paramType = TWD_TSF_DTIM_MIB_PARAM_ID; 688 param.content.interogateCmdCBParams.fCb = (void *)scanMngrGetCurrentTsfDtimMibCB; 689 param.content.interogateCmdCBParams.hCb = hScanMngr; 690 param.content.interogateCmdCBParams.pCb = (TI_UINT8*)&pScanMngr->currTsfDtimMib; 691 reqStatus = TWD_GetParam (pScanMngr->hTWD, ¶m); 692 if ( TI_OK != reqStatus ) 693 { 694 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, ": getParam from HAL CTRL failed wih status: %d\n", reqStatus); 695 } 696 } 697 698 /** 699 * \\n 700 * \date 01-Mar-2005\n 701 * \brief Starts a continuous scan operation.\n 702 * 703 * Function Scope \e Private.\n 704 * \param hScanMngr - handle to the scan manager object.\n 705 */ 706 void scanMngrPerformContinuousScan( TI_HANDLE hScanMngr ) 707 { 708 709 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 710 TScanBandPolicy *gPolicy, *aPolicy; 711 EScanCncnResultStatus resultStatus; 712 paramInfo_t param; 713 714 #ifdef SCAN_MNGR_DBG 715 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngrPerformContinuousScan called, hScanMngr=0x%x.\n", hScanMngr); 716 scanMngrDebugPrintBSSList( hScanMngr ); 717 #endif 718 719 /* this function is called due to continuous scan timer expiry, to start a new continuous scan cycle. 720 If the continuous scan is anything but idle, a new cycle is not started. */ 721 if ( SCAN_CSS_IDLE != pScanMngr->contScanState ) 722 { 723 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Continuous scan timer expired and continuous scan state is:%d\n", pScanMngr->contScanState); 724 return; 725 } 726 727 /* retrieve the current BSS DTIM period and beacon interval, for SPS DTIM avoidance 728 calculations later. This is done before the continuous scan process is started, 729 to check that they are not zero (in case the STA disconnected and somehow the 730 scan manager was not notified of the event). If the STA disconnected, the continuous 731 scan process is aborted */ 732 param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM; 733 siteMgr_getParam( pScanMngr->hSiteMngr, ¶m ); 734 pScanMngr->currentBSSBeaconInterval = param.content.beaconInterval; 735 736 param.paramType = SITE_MGR_DTIM_PERIOD_PARAM; 737 siteMgr_getParam( pScanMngr->hSiteMngr, ¶m ); 738 pScanMngr->currentBSSDtimPeriod = param.content.siteMgrDtimPeriod; 739 740 /* now check that none of the above is zero */ 741 if ( (0 == pScanMngr->currentBSSBeaconInterval) || (0 == pScanMngr->currentBSSDtimPeriod)) 742 { 743 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Trying to start continuous scan cycle but DTIM period=%d and beacon interval=%d\n", pScanMngr->currentBSSDtimPeriod, pScanMngr->currentBSSBeaconInterval); 744 return; 745 } 746 747 /* increase the consecutive not found counter */ 748 pScanMngr->consecNotFound++; 749 750 /* first try tracking on G */ 751 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ ); 752 /* if a policy is defined for G band tracking, attempt to perform it */ 753 if ( (NULL != gPolicy) && 754 (SCAN_TYPE_NO_SCAN != gPolicy->trackingMethod.scanType)) 755 { 756 /* build scan command */ 757 scanMngrBuildTrackScanCommand( hScanMngr, gPolicy, RADIO_BAND_2_4_GHZ ); 758 759 /* if channels are available for tracking on G */ 760 if ( 0 < pScanMngr->scanParams.numOfChannels ) 761 { 762 /* mark that continuous scan is now tracking on G */ 763 pScanMngr->contScanState = SCAN_CSS_TRACKING_G_BAND; 764 765 /* send scan command to scan concentrator with the required scan params according to scannig operational mode */ 766 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_CONT); 767 if ( SCAN_CRS_SCAN_RUNNING != resultStatus ) 768 { 769 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start tracking continuous scan on G, return code %d.\n", resultStatus); 770 #ifdef TI_DBG 771 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++; 772 #endif 773 pScanMngr->contScanState = SCAN_CSS_IDLE; 774 } 775 #ifdef SCAN_MNGR_DBG 776 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Tracking on G started.\n"); 777 #endif 778 return; 779 } 780 } 781 782 /* if not, try tracking on A */ 783 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ ); 784 /* if a policy is defined for A band tracking, attempt to perform it */ 785 if ( (NULL != aPolicy) && 786 (SCAN_TYPE_NO_SCAN != aPolicy->trackingMethod.scanType)) 787 { 788 /* build scan command */ 789 scanMngrBuildTrackScanCommand( hScanMngr, aPolicy, RADIO_BAND_5_0_GHZ ); 790 791 /* if channels are available for tracking on A */ 792 if ( 0 < pScanMngr->scanParams.numOfChannels ) 793 { 794 /* mark that continuous scan is now tracking on A */ 795 pScanMngr->contScanState = SCAN_CSS_TRACKING_A_BAND; 796 797 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */ 798 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_CONT); 799 if ( SCAN_CRS_SCAN_RUNNING != resultStatus ) 800 { 801 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start tracking continuous scan on A, return code %d.\n", resultStatus); 802 #ifdef TI_DBG 803 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++; 804 #endif 805 pScanMngr->contScanState = SCAN_CSS_IDLE; 806 } 807 #ifdef SCAN_MNGR_DBG 808 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Tracking on A started.\n"); 809 #endif 810 return; 811 } 812 } 813 /* in case a TSF error was received on last continuous scan cycle, mark (now, that tracking 814 on both bands was attempted), that TSF values are synchronized */ 815 pScanMngr->bSynchronized = TI_TRUE; 816 817 /* if this does not work as well, try discovery */ 818 /* discovery can be performed if discovery part is valid (this is maintained whenever a new policy or neighbor AP list 819 is set, a discovery scan command is built, and a new neighbor AP is discovered) */ 820 if ( (SCAN_SDP_NO_DISCOVERY != pScanMngr->currentDiscoveryPart) && 821 (pScanMngr->BSSList.numOfEntries <= pScanMngr->scanPolicy.BSSNumberToStartDiscovery)) 822 { 823 /* build scan command */ 824 scanMngrBuildDiscoveryScanCommand( hScanMngr ); 825 826 /* if channels are available for discovery */ 827 if ( 0 < pScanMngr->scanParams.numOfChannels ) 828 { 829 /* mark that continuous scan is now in discovery state */ 830 pScanMngr->contScanState = SCAN_CSS_DISCOVERING; 831 832 /* mark that no new BSS's were found (yet) */ 833 pScanMngr->bNewBSSFound = TI_FALSE; 834 835 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */ 836 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_CONT); 837 if ( SCAN_CRS_SCAN_RUNNING != resultStatus ) 838 { 839 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start discovery continuous scan, resultStatus %d.\n", resultStatus); 840 #ifdef TI_DBG 841 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand ) 842 { 843 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++; 844 } 845 else 846 { 847 pScanMngr->stats.DiscoveryAByStatus[ resultStatus ]++; 848 } 849 #endif 850 pScanMngr->contScanState = SCAN_CSS_IDLE; 851 } 852 #ifdef SCAN_MNGR_DBG 853 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Discovery started.\n"); 854 #endif 855 return; 856 } 857 } 858 859 /* if we got here, no scan had executed successfully - print a warning */ 860 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Unable to perform continuous scan.\n"); 861 } 862 863 /** 864 * \\n 865 * \date 01-Mar-2005\n 866 * \brief Perform aging on the BSS list.\n 867 * 868 * Function Scope \e Private.\n 869 * \param hScanMngr - handle to the scan manager object.\n 870 */ 871 void scanMngrPerformAging( TI_HANDLE hScanMngr ) 872 { 873 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 874 TI_UINT8 BSSEntryIndex; 875 876 #ifdef SCAN_MNGR_DBG 877 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Performing Aging.\n"); 878 #endif 879 /* loop on all entries in the BSS list */ 880 for ( BSSEntryIndex = 0; BSSEntryIndex < pScanMngr->BSSList.numOfEntries; ) 881 { 882 /* if an entry failed enough consecutive track attempts - remove it */ 883 if ( pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ].trackFailCount > 884 pScanMngr->scanPolicy.maxTrackFailures ) 885 { 886 /* will replace this entry with one further down the array, if any. Therefore, index is not increased 887 (because a new entry will be placed in the same index). If this is the last entry - the number of 888 BSSes will be decreased, and thus the loop will exit */ 889 #ifdef SCAN_MNGR_DBG 890 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Aging: removing BSSID %2x:%2x:%2x:%2x:%2x:%2x from index: %d.\n", pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 5 ], pScanMngr->BSSList.numOfEntries); 891 #endif 892 scanMngrRemoveBSSListEntry( hScanMngr, BSSEntryIndex ); 893 } 894 else 895 { 896 BSSEntryIndex++; 897 } 898 } 899 } 900 901 /** 902 * \\n 903 * \date 01-Mar-2005\n 904 * \brief Updates object data according to a received frame.\n 905 * 906 * Function Scope \e Private.\n 907 * \param hScanMngr - handle to the scan manager object.\n 908 * \param frameInfo - pointer to frame related information.\n 909 */ 910 void scanMngrUpdateReceivedFrame( TI_HANDLE hScanMngr, TScanFrameInfo* frameInfo ) 911 { 912 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 913 int BSSListIndex, neighborAPIndex; 914 TScanBandPolicy* pBandPolicy; 915 916 #ifdef SCAN_MNGR_DBG 917 scanMngrDebugPrintReceivedFrame( hScanMngr, frameInfo ); 918 #endif 919 #ifdef TI_DBG 920 pScanMngr->stats.receivedFrames++; 921 #endif 922 /* first check if the frame pass RSSI threshold. If not discard it and continue */ 923 pBandPolicy = scanMngrGetPolicyByBand( hScanMngr, frameInfo->band ); 924 if ( NULL == pBandPolicy ) /* sanity checking */ 925 { 926 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Recieved framed on band %d, for which policy is not defined!\n", frameInfo->band); 927 #ifdef TI_DBG 928 pScanMngr->stats.discardedFramesOther++; 929 #endif 930 return; 931 } 932 933 if ( frameInfo->rssi < pBandPolicy->rxRSSIThreshold ) 934 { 935 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Discarding frame beacuse RSSI %d is lower than threshold %d\n", frameInfo->rssi, pBandPolicy->rxRSSIThreshold); 936 #ifdef TI_DBG 937 pScanMngr->stats.discardedFramesLowRSSI++; 938 #endif 939 return; 940 } 941 942 /* search for this AP in the tracking list */ 943 BSSListIndex = scanMngrGetTrackIndexByBssid( hScanMngr, frameInfo->bssId ); 944 945 /* if the frame received from an AP in the track list */ 946 if ( -1 != BSSListIndex ) 947 { 948 scanMngrUpdateBSSInfo( hScanMngr, BSSListIndex, frameInfo ); 949 } 950 /* otherwise, if the list is not full and AP is either a neighbor AP or on a policy defined channel: */ 951 else 952 { 953 neighborAPIndex = scanMngrGetNeighborAPIndex( hScanMngr, frameInfo->band, frameInfo->bssId ); 954 955 if ( (pScanMngr->BSSList.numOfEntries < pScanMngr->scanPolicy.BSSListSize) && 956 ((TI_TRUE == scanMngrIsPolicyChannel( hScanMngr, frameInfo->band, frameInfo->channel )) || 957 (-1 != neighborAPIndex))) 958 { 959 /* insert the AP to the list */ 960 scanMngrInsertNewBSSToTrackingList( hScanMngr, frameInfo ); 961 962 /* if this is a neighbor AP */ 963 if ( -1 != neighborAPIndex ) 964 { 965 /* mark in the neighbor AP list that it's being tracked */ 966 pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].trackStatusList[ neighborAPIndex ] = SCAN_NDS_DISCOVERED; 967 968 /* if the discovery index for this neighbor AP band points to this AP, 969 advance it and advance discovery part if needed */ 970 if ( pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] == neighborAPIndex ) 971 { 972 do { 973 pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ]++; /* advance discovery index */ 974 /* while discovery list is not exhausted and no AP for discovery is found */ 975 } while ( (pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] < pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].numOfEntries) && 976 (SCAN_NDS_NOT_DISCOVERED != pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].trackStatusList[ pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] ])); 977 /* if discovery list isexhausted */ 978 if ( pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] == pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].numOfEntries ) 979 { 980 /* restart discovery cycle for this band's neighbor APs */ 981 pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] = 0; 982 /* set new discovery part (if needed) */ 983 scanMngrSetNextDiscoveryPart( hScanMngr ); 984 } 985 } 986 } 987 } 988 #ifdef TI_DBG 989 else 990 { 991 pScanMngr->stats.discardedFramesOther++; 992 } 993 #endif 994 } 995 } 996 997 /** 998 * \\n 999 * \date 17-Mar-2005\n 1000 * \brief Cerate a new tracking entry and store the newly discovered AP info in it.\n 1001 * 1002 * Function Scope \e Private.\n 1003 * \param hScanMngr - handle to the scan manager object.\n 1004 * \param frameInfo - a pointer to the information received from this AP.\n 1005 */ 1006 void scanMngrInsertNewBSSToTrackingList( TI_HANDLE hScanMngr, TScanFrameInfo* frameInfo ) 1007 { 1008 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1009 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION 1010 int i; 1011 #endif 1012 1013 /* mark that a new AP was discovered (for discovery stage) */ 1014 pScanMngr->bNewBSSFound = TI_TRUE; 1015 1016 /* insert fields that are not update regulary */ 1017 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries ].bNeighborAP = 1018 ( -1 == scanMngrGetNeighborAPIndex( hScanMngr, frameInfo->band, frameInfo->bssId ) ? 1019 TI_FALSE : 1020 TI_TRUE ); 1021 MAC_COPY (pScanMngr->BSSList.BSSList[pScanMngr->BSSList.numOfEntries].BSSID, *(frameInfo->bssId)); 1022 1023 /* initialize average RSSI value */ 1024 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries ].RSSI = frameInfo->rssi; 1025 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries ].lastRSSI = frameInfo->rssi; 1026 1027 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION 1028 /* initialize previous delta change array (used for SPS drift compensation) */ 1029 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].prevTSFDelta = 0; 1030 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].deltaChangeArrayIndex = 0; 1031 for ( i = 0; i < SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES; i++ ) 1032 { 1033 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].deltaChangeArray[ i ] = 0; 1034 } 1035 #endif 1036 1037 /* update regular fields */ 1038 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].trackFailCount = 0; /* for correct statistics update */ 1039 scanMngrUpdateBSSInfo( hScanMngr, pScanMngr->BSSList.numOfEntries, frameInfo ); 1040 1041 /* increase the number of tracked APs */ 1042 pScanMngr->BSSList.numOfEntries++; 1043 } 1044 1045 /** 1046 * \\n 1047 * \date 17-Mar-2005\n 1048 * \brief Updates tracked AP information.\n 1049 * 1050 * Function Scope \e Private.\n 1051 * \param hScanMngr - handle to the scan manager object.\n 1052 * \param BSSListIndex - index to the BSS list where the AP information is stored.\n 1053 * \param frameInfo - a pointer to the information received from this AP.\n 1054 */ 1055 void scanMngrUpdateBSSInfo( TI_HANDLE hScanMngr, TI_UINT8 BSSListIndex, TScanFrameInfo* frameInfo ) 1056 { 1057 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1058 1059 /* update AP data */ 1060 pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRxHostTimestamp = os_timeStampMs( pScanMngr->hOS ); 1061 pScanMngr->BSSList.BSSList[ BSSListIndex ].resultType = (frameInfo->parsedIEs->subType == BEACON) ? SCAN_RFT_BEACON : SCAN_RFT_PROBE_RESPONSE; 1062 pScanMngr->BSSList.BSSList[ BSSListIndex ].band = frameInfo->band; 1063 pScanMngr->BSSList.BSSList[ BSSListIndex ].channel = frameInfo->channel; 1064 /* if the received TSF (which is the lower 32 bits) is smaller than the lower 32 bits of the last beacon 1065 TSF, it means the higher 32 bits should be increased by 1 (TSF overflow to higher 32 bits occurred between 1066 last beacon of current AP and this frame). */ 1067 if ( INT64_LOWER( (pScanMngr->currentTSF)) > frameInfo->staTSF ) 1068 { 1069 INT64_HIGHER( (pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF)) = 1070 INT64_HIGHER( (pScanMngr->currentTSF)) + 1; 1071 } 1072 else 1073 { 1074 INT64_HIGHER( (pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF)) = 1075 INT64_HIGHER( (pScanMngr->currentTSF)); 1076 } 1077 INT64_LOWER( (pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF)) = frameInfo->staTSF; 1078 1079 if ( BEACON == frameInfo->parsedIEs->subType ) 1080 { 1081 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRxTSF), 1082 (void *)frameInfo->parsedIEs->content.iePacket.timestamp, TIME_STAMP_LEN ); 1083 pScanMngr->BSSList.BSSList[ BSSListIndex ].beaconInterval = 1084 frameInfo->parsedIEs->content.iePacket.beaconInerval; 1085 pScanMngr->BSSList.BSSList[ BSSListIndex ].capabilities = 1086 frameInfo->parsedIEs->content.iePacket.capabilities; 1087 } 1088 else 1089 { 1090 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRxTSF), 1091 (void *)frameInfo->parsedIEs->content.iePacket.timestamp, TIME_STAMP_LEN ); 1092 pScanMngr->BSSList.BSSList[ BSSListIndex ].beaconInterval = 1093 frameInfo->parsedIEs->content.iePacket.beaconInerval; 1094 pScanMngr->BSSList.BSSList[ BSSListIndex ].capabilities = 1095 frameInfo->parsedIEs->content.iePacket.capabilities; 1096 } 1097 #ifdef TI_DBG 1098 /* 1099 update track fail histogram: 1100 1. only done when tracking (to avoid updating due to "accidental re-discovery" 1101 2. only done for APs which have their track fail count larger than 0. The reason for that is because 1102 when tracking is started, the track fail count is increased, and thus if it is 0 tracking was not 1103 attempted for this AP, or more than one frame was received as a result of tracking operation for the AP. 1104 */ 1105 if ( ((SCAN_CSS_TRACKING_A_BAND == pScanMngr->contScanState) || 1106 (SCAN_CSS_TRACKING_G_BAND == pScanMngr->contScanState)) && 1107 (0 < pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount)) 1108 { 1109 if ( SCAN_MNGR_STAT_MAX_TRACK_FAILURE <= 1110 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount ) 1111 { 1112 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ SCAN_MNGR_STAT_MAX_TRACK_FAILURE - 1 ]++; 1113 } 1114 else 1115 { 1116 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount - 1 ]++; 1117 } 1118 } 1119 #endif 1120 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount = 0; 1121 1122 /* update RSSI value */ 1123 { 1124 TI_INT8 rssiPrevVal = pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI; 1125 TI_INT8 tmpRssiAvg = ((RSSI_PREVIOUS_COEFFICIENT * rssiPrevVal) + 1126 ((10-RSSI_PREVIOUS_COEFFICIENT) * frameInfo->rssi)) / 10; 1127 1128 pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRSSI = frameInfo->rssi; 1129 1130 if (rssiPrevVal!=0) 1131 { 1132 /* for faster convergence on RSSI changes use rounding error calculation with latest sample and not 1133 on latest average */ 1134 if (frameInfo->rssi > tmpRssiAvg) 1135 tmpRssiAvg++; 1136 else 1137 if (frameInfo->rssi < tmpRssiAvg) 1138 tmpRssiAvg--; 1139 1140 pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI = tmpRssiAvg; 1141 } 1142 else 1143 { 1144 pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI = frameInfo->rssi; 1145 } 1146 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "given RSSI=%d, AVRG RSSI=%d\n", frameInfo->rssi, pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI); 1147 1148 } 1149 1150 pScanMngr->BSSList.BSSList[ BSSListIndex ].rxRate = frameInfo->rate; 1151 os_memoryCopy( pScanMngr->hOS, pScanMngr->BSSList.BSSList[ BSSListIndex ].pBuffer, 1152 frameInfo->buffer, frameInfo->bufferLength ); 1153 pScanMngr->BSSList.BSSList[ BSSListIndex ].bufferLength = frameInfo->bufferLength; 1154 } 1155 1156 /** 1157 * \\n 1158 * \date 16-Mar-2005\n 1159 * \brief Search tracking list for an entry matching given BSSID.\n 1160 * 1161 * Function Scope \e Private.\n 1162 * \param hScanMngr - handle to the scan manager object.\n 1163 * \param bssId - the BSSID to search for.\n 1164 * \return entry index if found, -1 if no entry matching the BSSID was found.\n 1165 */ 1166 TI_INT8 scanMngrGetTrackIndexByBssid( TI_HANDLE hScanMngr, TMacAddr* bssId ) 1167 { 1168 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1169 int i; 1170 1171 for ( i = 0; i < pScanMngr->BSSList.numOfEntries; i++ ) 1172 { 1173 if (MAC_EQUAL(*bssId, pScanMngr->BSSList.BSSList[ i ].BSSID)) 1174 { 1175 return i; 1176 } 1177 } 1178 return -1; 1179 } 1180 1181 /** 1182 * \\n 1183 * \date 02-Mar-2005\n 1184 * \brief Search current policy for band policy 1185 * 1186 * Function Scope \e Private.\n 1187 * \param hScanMngr - handle to the scan manager object.\n 1188 * \param band - the band to find policy for.\n 1189 * \return the policy structure if found, NULL if no policy configured for this band.\n 1190 */ 1191 TScanBandPolicy* scanMngrGetPolicyByBand( TI_HANDLE hScanMngr, ERadioBand band ) 1192 { 1193 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1194 int i; 1195 1196 /* loop on all configured policies, and look for the requested band */ 1197 for ( i = 0; i < pScanMngr->scanPolicy.numOfBands; i++ ) 1198 { 1199 if ( band == pScanMngr->scanPolicy.bandScanPolicy[ i ].band ) 1200 { 1201 return &(pScanMngr->scanPolicy.bandScanPolicy[ i ]); 1202 } 1203 } 1204 1205 /* if no policy was found, there's no policy configured for the requested band */ 1206 return NULL; 1207 } 1208 1209 /** 1210 * \\n 1211 * \date 06-Mar-2005\n 1212 * \brief Sets the next discovery part according to current discovery part, policies and neighbor APs availability .\n 1213 * 1214 * Function Scope \e Private.\n 1215 * \param hScanMngr - handle to the scan manager object.\n 1216 */ 1217 void scanMngrSetNextDiscoveryPart( TI_HANDLE hScanMngr ) 1218 { 1219 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1220 scan_discoveryPart_e nextDiscoveryPart, originalDiscoveryPart; 1221 1222 /* sanity check - if discovery part is not valid, restart from first discovery part */ 1223 if ( SCAN_SDP_NO_DISCOVERY <= pScanMngr->currentDiscoveryPart ) 1224 { 1225 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G; 1226 } 1227 1228 /* if current discovery part is valid, do nothing */ 1229 if ( TI_TRUE == scanMngrIsDiscoveryValid( hScanMngr, pScanMngr->currentDiscoveryPart )) 1230 { 1231 return; 1232 } 1233 1234 /* next discovery part is found according to current part, in the following order: 1235 Neighbor APs on G, Neighbor APs on A, Channel list on G, Channel list on A */ 1236 /* get next discovery part */ 1237 nextDiscoveryPart = pScanMngr->currentDiscoveryPart; 1238 originalDiscoveryPart = pScanMngr->currentDiscoveryPart; 1239 1240 do 1241 { 1242 nextDiscoveryPart++; 1243 /* loop back to first discovery part if discovery list end had been reached */ 1244 if ( SCAN_SDP_NO_DISCOVERY == nextDiscoveryPart ) 1245 { 1246 nextDiscoveryPart = SCAN_SDP_NEIGHBOR_G; 1247 } 1248 /* try next discovery part until first one is reached again or a valid part is found */ 1249 } while( (nextDiscoveryPart != originalDiscoveryPart) && 1250 (TI_FALSE == scanMngrIsDiscoveryValid( hScanMngr, nextDiscoveryPart ))); 1251 1252 /* if a discovery part for which discovery is valid was found, use it */ 1253 if ( TI_TRUE == scanMngrIsDiscoveryValid( hScanMngr, nextDiscoveryPart )) 1254 { 1255 pScanMngr->currentDiscoveryPart = nextDiscoveryPart; 1256 } 1257 /* otherwise don't do discovery */ 1258 else 1259 { 1260 pScanMngr->currentDiscoveryPart = SCAN_SDP_NO_DISCOVERY; 1261 } 1262 } 1263 1264 /** 1265 * \\n 1266 * \date 06-Mar-2005\n 1267 * \brief Checks whether discovery should be performed on the specified discovery part.\n 1268 * 1269 * Function Scope \e Private.\n 1270 * \param hScanMngr - handle to the scan manager object.\n 1271 * \param discoveryPart - the discovery part to check.\n 1272 */ 1273 TI_BOOL scanMngrIsDiscoveryValid( TI_HANDLE hScanMngr, scan_discoveryPart_e discoveryPart ) 1274 { 1275 scanMngr_t* pScanMngr = (TI_HANDLE)hScanMngr; 1276 TScanBandPolicy *gPolicy, *aPolicy; 1277 1278 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ ); 1279 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ ); 1280 1281 switch (discoveryPart) 1282 { 1283 case SCAN_SDP_NEIGHBOR_G: 1284 /* for discovery on G neighbor APs, a policy must be defined for G, discovery scan type should be present, 1285 number of neighbor APs on G should be greater than zero, and at least one AP should be yet undiscovered */ 1286 if ( (NULL != gPolicy) && 1287 (SCAN_TYPE_NO_SCAN != gPolicy->discoveryMethod.scanType) && 1288 (0 < pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries) && 1289 (TI_TRUE == scanMngrNeighborAPsAvailableForDiscovery( hScanMngr, RADIO_BAND_2_4_GHZ ))) 1290 { 1291 return TI_TRUE; 1292 } 1293 else 1294 { 1295 return TI_FALSE; 1296 } 1297 1298 case SCAN_SDP_NEIGHBOR_A: 1299 /* for discovery on A neighbor APs, a policy must be defined for A, discovery scan type should be present, 1300 number of neighbor APs on A should be greater than zero, and at least one AP should be yet undiscovered */ 1301 if ( (NULL != aPolicy) && 1302 (SCAN_TYPE_NO_SCAN != aPolicy->discoveryMethod.scanType) && 1303 (0 < pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries) && 1304 (TI_TRUE == scanMngrNeighborAPsAvailableForDiscovery( hScanMngr, RADIO_BAND_5_0_GHZ ))) 1305 { 1306 return TI_TRUE; 1307 } 1308 else 1309 { 1310 return TI_FALSE; 1311 } 1312 1313 case SCAN_SDP_CHANNEL_LIST_G: 1314 /* for discovery on G channel list, a policy must be defined for G, discovery scan type should be present, 1315 and number of channels in G channel list should be greater than zero */ 1316 if ( (NULL != gPolicy) && 1317 (SCAN_TYPE_NO_SCAN != gPolicy->discoveryMethod.scanType) && 1318 (0 < gPolicy->numOfChannles)) 1319 { 1320 return TI_TRUE; 1321 } 1322 else 1323 { 1324 return TI_FALSE; 1325 } 1326 case SCAN_SDP_CHANNEL_LIST_A: 1327 /* for discovery on A channel list, a policy must be defined for A, discovery scan type should be present, 1328 and number of channels in A channel list should be greater than zero */ 1329 if ( (NULL != aPolicy) && 1330 (SCAN_TYPE_NO_SCAN != aPolicy->discoveryMethod.scanType) && 1331 (0 < aPolicy->numOfChannles)) 1332 { 1333 return TI_TRUE; 1334 } 1335 else 1336 { 1337 return TI_FALSE; 1338 } 1339 default: 1340 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Checking whather discovery is valid for discovery part %d", discoveryPart); 1341 return TI_FALSE; 1342 } 1343 } 1344 1345 /** 1346 * \\n 1347 * \date 07-Mar-2005\n 1348 * \brief Check whether there are neighbor APs to track on the given band.\n 1349 * 1350 * Function Scope \e Private.\n 1351 * \param hScanMngr - handle to the scan manager object.\n 1352 * \param bandPolicy - The scan policy for the requested band.\n 1353 * \param bNeighborAPsOnly - whether to scan for neighbor APs only or for all policy defined channels.\n 1354 */ 1355 TI_BOOL scanMngrNeighborAPsAvailableForDiscovery( TI_HANDLE hScanMngr, ERadioBand band ) 1356 { 1357 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1358 int i; 1359 1360 1361 /* loop on all neighbor APs of the given band */ 1362 for ( i = 0; i < pScanMngr->neighborAPsDiscoveryList[ band ].numOfEntries; i++ ) 1363 { 1364 /* if a neighbor AP is not being tracked, meaning it yet has to be discovered, return TI_TRUE */ 1365 if ( SCAN_NDS_NOT_DISCOVERED == pScanMngr->neighborAPsDiscoveryList[ band ].trackStatusList[ i ] ) 1366 { 1367 return TI_TRUE; 1368 } 1369 } 1370 /* if all neighbor APs are being tracked (or no neighbor APs available) return TI_FALSE */ 1371 return TI_FALSE; 1372 } 1373 1374 /** 1375 * \\n 1376 * \date 02-Mar-2005\n 1377 * \brief Builds a scan command on the object workspace for immediate scan.\n 1378 * 1379 * Function Scope \e Private.\n 1380 * \param hScanMngr - handle to the scan manager object.\n 1381 * \param bandPolicy - The scan policy for the requested band.\n 1382 * \param bNeighborAPsOnly - whether to scan for neighbor APs only or for all policy defined channels.\n 1383 */ 1384 void scanMngrBuildImmediateScanCommand( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy, TI_BOOL bNeighborAPsOnly ) 1385 { 1386 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1387 int channelIndex; 1388 paramInfo_t param; 1389 TMacAddr broadcastAddress; 1390 int i; 1391 1392 /* first, build the command header */ 1393 scanMngrBuildScanCommandHeader( hScanMngr, &(bandPolicy->immediateScanMethod), bandPolicy->band ); 1394 1395 /* if requested to scan on neighbor APs only */ 1396 if ( TI_TRUE == bNeighborAPsOnly ) 1397 { 1398 /* loop on all neighbor APs */ 1399 channelIndex = 0; 1400 while ( (channelIndex < pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].numOfEntries) && 1401 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND)) 1402 { 1403 /* verify channel with reg domain */ 1404 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 1405 param.content.channelCapabilityReq.band = bandPolicy->band; 1406 if ( (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) || 1407 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) || 1408 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_SPS)) 1409 { 1410 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; 1411 } 1412 else 1413 { 1414 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; 1415 } 1416 param.content.channelCapabilityReq.channelNum = 1417 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ channelIndex ].channel; 1418 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m ); 1419 1420 /* if the channel is allowed, insert it to the scan command */ 1421 if (param.content.channelCapabilityRet.channelValidity) 1422 { 1423 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->immediateScanMethod), 1424 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ channelIndex ].channel, 1425 &(pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ channelIndex ].BSSID), 1426 param.content.channelCapabilityRet.maxTxPowerDbm ); 1427 } 1428 channelIndex++; 1429 } 1430 } 1431 else 1432 /* scan on all policy defined channels */ 1433 { 1434 /* set the broadcast address */ 1435 for ( i = 0; i < MAC_ADDR_LEN; i++ ) 1436 { 1437 broadcastAddress[ i ] = 0xff; 1438 } 1439 1440 /* loop on all channels in the policy */ 1441 channelIndex = 0; 1442 while ( (channelIndex < bandPolicy->numOfChannles) && 1443 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND)) 1444 { 1445 /* verify channel with reg domain */ 1446 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 1447 param.content.channelCapabilityReq.band = bandPolicy->band; 1448 if ( (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) || 1449 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) || 1450 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_SPS)) 1451 { 1452 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; 1453 } 1454 else 1455 { 1456 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; 1457 } 1458 param.content.channelCapabilityReq.channelNum = bandPolicy->channelList[ channelIndex ]; 1459 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m ); 1460 1461 /* if the channel is allowed, insert it to the scan command */ 1462 if (param.content.channelCapabilityRet.channelValidity) 1463 { 1464 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->immediateScanMethod), 1465 bandPolicy->channelList[ channelIndex ], 1466 &broadcastAddress, 1467 param.content.channelCapabilityRet.maxTxPowerDbm ); 1468 } 1469 channelIndex++; 1470 } 1471 } 1472 } 1473 1474 /** 1475 * \\n 1476 * \date 03-Mar-2005\n 1477 * \brief Builds a scan command on the object workspace for tracking.\n 1478 * 1479 * Function Scope \e Private.\n 1480 * \param hScanMngr - handle to the scan manager object.\n 1481 * \param bandPolicy - The scan policy for the band to track on.\n 1482 * \param band - the band to scan.\n 1483 */ 1484 void scanMngrBuildTrackScanCommand( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy, ERadioBand band ) 1485 { 1486 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1487 int BSSListIndex; 1488 paramInfo_t param; 1489 TScanMethod* scanMethod; 1490 1491 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n scanMngrBuildTrackScanCommand \n"); 1492 1493 1494 /* SPS is performed differently from all other scan types, and only if TSF error has not occured */ 1495 if ( (SCAN_TYPE_SPS == bandPolicy->trackingMethod.scanType) && (TI_TRUE == pScanMngr->bSynchronized)) 1496 { 1497 /* build the command header */ 1498 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\nSPS invoked\n"); 1499 scanMngrBuildScanCommandHeader( hScanMngr, &(bandPolicy->trackingMethod), band ); 1500 1501 /* build the channel list */ 1502 scanMngrAddSPSChannels( hScanMngr, &(bandPolicy->trackingMethod), band ); 1503 return; 1504 } 1505 1506 /* the scan method to use is the method defined for tracking, unless this is SPS and TSF error occurred, 1507 in which case we use the discovery method this time. */ 1508 if ( (SCAN_TYPE_SPS == bandPolicy->trackingMethod.scanType) && (TI_FALSE == pScanMngr->bSynchronized)) 1509 { 1510 /* use discovery scan method */ 1511 scanMethod = &(bandPolicy->discoveryMethod); 1512 } 1513 else 1514 { 1515 /* use tracking method */ 1516 scanMethod = &(bandPolicy->trackingMethod); 1517 } 1518 1519 /* build the command header */ 1520 scanMngrBuildScanCommandHeader( hScanMngr, scanMethod, band ); 1521 1522 /* insert channels from tracking list according to requested band */ 1523 BSSListIndex = 0; 1524 while ( (BSSListIndex < pScanMngr->BSSList.numOfEntries) && 1525 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND)) 1526 { 1527 /* if BSS is on the right band */ 1528 if ( band == pScanMngr->BSSList.BSSList[ BSSListIndex ].band ) 1529 { 1530 /* verify the channel with the reg domain */ 1531 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 1532 param.content.channelCapabilityReq.band = band; 1533 if ( (scanMethod->scanType == SCAN_TYPE_NORMAL_PASSIVE) || 1534 (scanMethod->scanType == SCAN_TYPE_TRIGGERED_PASSIVE)) 1535 { 1536 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; 1537 } 1538 else 1539 { 1540 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; 1541 } 1542 param.content.channelCapabilityReq.channelNum = pScanMngr->BSSList.BSSList[ BSSListIndex ].channel; 1543 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m ); 1544 1545 /* if channel is verified for requested scan type */ 1546 if ( param.content.channelCapabilityRet.channelValidity ) 1547 { 1548 scanMngrAddNormalChannel( hScanMngr, scanMethod, 1549 pScanMngr->BSSList.BSSList[ BSSListIndex ].channel, 1550 &(pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID), 1551 param.content.channelCapabilityRet.maxTxPowerDbm ); 1552 1553 /* increase AP track attempts counter */ 1554 if ( (SCAN_TYPE_SPS == bandPolicy->trackingMethod.scanType) && (TI_FALSE == pScanMngr->bSynchronized)) 1555 { 1556 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount = 1557 pScanMngr->scanPolicy.maxTrackFailures + 1; 1558 } 1559 else 1560 { 1561 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount++; 1562 } 1563 } 1564 /* if channel is not verified, there are two options: 1565 1. we are using the tracking method, and thus the AP should be removed (because we are unable 1566 to track it) 1567 2. we are using the discovery method (because a TSF error occurred and tracking method is SPS). 1568 In this case, it seems we do not have to remove the AP (because the channel may not be valid 1569 for active scan but it is valid for passive scan), but since we had a TSF error the AP would 1570 be removed anyhow if not re-discovered now, so no harm done in removing it as well. */ 1571 else 1572 { 1573 /* removing an AP is done by increasing its track failure counter to maximum. Since it is 1574 not tracked, it would not be found, and thus would be removed by aging process performed 1575 at scan completion */ 1576 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount = 1577 pScanMngr->scanPolicy.maxTrackFailures + 1; 1578 #ifdef TI_DBG 1579 /* update statistics */ 1580 pScanMngr->stats.APsRemovedInvalidChannel++; 1581 #endif 1582 } 1583 } 1584 BSSListIndex++; 1585 } 1586 } 1587 1588 /** 1589 * \\n 1590 * \date 03-Mar-2005\n 1591 * \brief Builds a scan command on the object workspace for discovery.\n 1592 * 1593 * Function Scope \e Private.\n 1594 * \param hScanMngr - handle to the scan manager object.\n 1595 */ 1596 void scanMngrBuildDiscoveryScanCommand( TI_HANDLE hScanMngr ) 1597 { 1598 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1599 ERadioBand band; 1600 TScanBandPolicy* bandPolicy; 1601 1602 /* find on which band to discover at current cycle */ 1603 if ( (SCAN_SDP_NEIGHBOR_G == pScanMngr->currentDiscoveryPart) || 1604 (SCAN_SDP_CHANNEL_LIST_G == pScanMngr->currentDiscoveryPart)) 1605 { 1606 band = RADIO_BAND_2_4_GHZ; 1607 bandPolicy = scanMngrGetPolicyByBand( hScanMngr, band ); 1608 } 1609 else 1610 { 1611 band = RADIO_BAND_5_0_GHZ; 1612 bandPolicy = scanMngrGetPolicyByBand( hScanMngr, band ); 1613 } 1614 1615 if( NULL == bandPolicy) 1616 { 1617 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "scanMngrGetPolicyByBand() returned NULL.\n"); 1618 return; 1619 } 1620 1621 /* first, build the command header */ 1622 scanMngrBuildScanCommandHeader( hScanMngr, &(bandPolicy->discoveryMethod), band ); 1623 1624 /* channels are added according to current discovery part */ 1625 switch ( pScanMngr->currentDiscoveryPart ) 1626 { 1627 case SCAN_SDP_NEIGHBOR_G: 1628 /* add channels from neighbor AP discovery list */ 1629 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy ); 1630 1631 /* if neighbor AP list is exhausted, proceed to next discovery part */ 1632 if ( 0 == pScanMngr->neighborAPsDiscoveryIndex[ band ] ) 1633 { 1634 pScanMngr->currentDiscoveryPart++; 1635 scanMngrSetNextDiscoveryPart( hScanMngr ); 1636 } 1637 1638 /* if need to discover more APs, (not enough neighbor APs), proceed to G channel list */ 1639 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery ) 1640 { 1641 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy ); 1642 } 1643 1644 #ifdef TI_DBG 1645 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_2_4_GHZ; 1646 #endif 1647 break; 1648 1649 case SCAN_SDP_NEIGHBOR_A: 1650 /* add channels from neighbor AP discovery list */ 1651 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy ); 1652 1653 /* if neighbor AP list is exhausted, proceed to next discovery part */ 1654 if ( 0 == pScanMngr->neighborAPsDiscoveryIndex[ band ] ) 1655 { 1656 pScanMngr->currentDiscoveryPart++; 1657 scanMngrSetNextDiscoveryPart( hScanMngr ); 1658 } 1659 1660 /* if need to discover more APs, (not enough neighbor APs), proceed to A channel list */ 1661 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery ) 1662 { 1663 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy ); 1664 } 1665 1666 #ifdef TI_DBG 1667 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_5_0_GHZ; 1668 #endif 1669 break; 1670 1671 case SCAN_SDP_CHANNEL_LIST_G: 1672 /* add channels from policy channel list */ 1673 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy ); 1674 1675 /* if channel list is exhausted, proceed to next discovery part */ 1676 if ( 0 == pScanMngr->channelDiscoveryIndex[ band ] ) 1677 { 1678 pScanMngr->currentDiscoveryPart++; 1679 scanMngrSetNextDiscoveryPart( hScanMngr ); 1680 } 1681 1682 /* if need to discover more APs (not enough channels on channel list), proceed to G neighbor APs */ 1683 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery ) 1684 { 1685 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy ); 1686 } 1687 1688 #ifdef TI_DBG 1689 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_2_4_GHZ; 1690 #endif 1691 break; 1692 1693 case SCAN_SDP_CHANNEL_LIST_A: 1694 /* add channels from policy channel list */ 1695 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy ); 1696 1697 /* if channel list is exhausted, proceed to next discovery part */ 1698 if ( 0 == pScanMngr->channelDiscoveryIndex[ band ] ) 1699 { 1700 pScanMngr->currentDiscoveryPart++; 1701 scanMngrSetNextDiscoveryPart( hScanMngr ); 1702 } 1703 1704 /* if need to discover more APs (not enough channels on channel list), proceed to A neighbor APs */ 1705 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery ) 1706 { 1707 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy ); 1708 } 1709 #ifdef TI_DBG 1710 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_5_0_GHZ; 1711 #endif 1712 break; 1713 1714 case SCAN_SDP_NO_DISCOVERY: 1715 default: 1716 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngrBuildDiscoveryScanCommand called and current discovery part is %d", pScanMngr->currentDiscoveryPart); 1717 break; 1718 } 1719 } 1720 1721 /** 1722 * \\n 1723 * \date 02-Mar-2005\n 1724 * \brief Builds the scan command header on the object workspace.\n 1725 * 1726 * Function Scope \e Private.\n 1727 * \param hScanMngr - handle to the scan manager object.\n 1728 * \param scanMethod - The scan method (and parameters) to use.\n 1729 * \param band - the band to scan.\n 1730 */ 1731 void scanMngrBuildScanCommandHeader( TI_HANDLE hScanMngr, TScanMethod* scanMethod, ERadioBand band ) 1732 { 1733 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1734 1735 1736 /* set general scan parameters */ 1737 /* SSID is not set - scan concentrator will set it for the scan manager to current SSID */ 1738 pScanMngr->scanParams.scanType = scanMethod->scanType; 1739 pScanMngr->scanParams.band = band; 1740 1741 switch (scanMethod->scanType) 1742 { 1743 case SCAN_TYPE_NORMAL_ACTIVE: 1744 /* In active scan, the desired SSID is set by the scan concentrator to the current SSID. 1745 Stting anything not zero triggers this in the scan concentrator */ 1746 pScanMngr->scanParams.desiredSsid.len = 1; 1747 pScanMngr->scanParams.probeReqNumber = scanMethod->method.basicMethodParams.probReqParams.numOfProbeReqs; 1748 pScanMngr->scanParams.probeRequestRate = scanMethod->method.basicMethodParams.probReqParams.bitrate; 1749 break; 1750 1751 case SCAN_TYPE_TRIGGERED_ACTIVE: 1752 /* In active scan, the desired SSID is set by the scan concentrator to the current SSID. 1753 Stting anything not zero triggers this in the scan concentrator */ 1754 pScanMngr->scanParams.desiredSsid.len = 1; 1755 pScanMngr->scanParams.probeReqNumber = scanMethod->method.TidTriggerdMethodParams.basicMethodParams.probReqParams.numOfProbeReqs; 1756 pScanMngr->scanParams.probeRequestRate = scanMethod->method.TidTriggerdMethodParams.basicMethodParams.probReqParams.bitrate; 1757 pScanMngr->scanParams.Tid = scanMethod->method.TidTriggerdMethodParams.triggeringTid; 1758 break; 1759 1760 case SCAN_TYPE_TRIGGERED_PASSIVE: 1761 pScanMngr->scanParams.Tid = scanMethod->method.TidTriggerdMethodParams.triggeringTid; 1762 /* In Passive scan, Desired SSID length is set to 0 so that the Scan concentrator won't replace 1763 it with the current SSID (to be able to receive beacons from AP's with multiple or hidden 1764 SSID) */ 1765 pScanMngr->scanParams.desiredSsid.len = 0; 1766 break; 1767 1768 case SCAN_TYPE_NORMAL_PASSIVE: 1769 /* In Passive scan, Desired SSID length is set to 0 so that the Scan concentrator won't replace 1770 it with the current SSID (to be able to receive beacons from AP's with multiple or hidden 1771 SSID) */ 1772 pScanMngr->scanParams.desiredSsid.len = 0; 1773 break; 1774 1775 case SCAN_TYPE_SPS: 1776 /* SPS doesn't have SSID filter, it only uses BSSID filter */ 1777 break; 1778 1779 default: 1780 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Unrecognized scan type %d when building scan command", scanMethod->scanType); 1781 break; 1782 } 1783 1784 /* set 0 channels - actual channel will be added by caller */ 1785 pScanMngr->scanParams.numOfChannels = 0; 1786 } 1787 1788 /** 1789 * \\n 1790 * \date 06-Mar-2005\n 1791 * \brief Add neighbor APs to scan command on the object workspace for discovery scan.\n 1792 * 1793 * Function Scope \e Private.\n 1794 * \param hScanMngr - handle to the scan manager object.\n 1795 * \param bandPolicy - the scan policy for the band to use.\n 1796 */ 1797 void scanMngrAddNeighborAPsForDiscovery( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy ) 1798 { 1799 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1800 int neighborAPIndex = pScanMngr->neighborAPsDiscoveryIndex[ bandPolicy->band ]; 1801 paramInfo_t param; 1802 1803 /* loop while neighbor AP list has not been exhausted, command is not full and not enough APs for discovery had been found */ 1804 while ( (pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery) && 1805 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND) && 1806 (neighborAPIndex < pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].numOfEntries)) 1807 { 1808 /* if the AP is not being tracked */ 1809 if ( SCAN_NDS_NOT_DISCOVERED == 1810 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].trackStatusList[ neighborAPIndex ] ) 1811 { 1812 /* verify channel with reg domain */ 1813 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 1814 param.content.channelCapabilityReq.band = bandPolicy->band; 1815 if ( (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) || 1816 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) || 1817 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_SPS)) 1818 { 1819 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; 1820 } 1821 else 1822 { 1823 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; 1824 } 1825 param.content.channelCapabilityReq.channelNum = 1826 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ neighborAPIndex ].channel; 1827 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m ); 1828 1829 /* if the channel is allowed, insert it to the scan command */ 1830 if (param.content.channelCapabilityRet.channelValidity) 1831 { 1832 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->discoveryMethod), 1833 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ neighborAPIndex ].channel, 1834 &(pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ neighborAPIndex ].BSSID), 1835 param.content.channelCapabilityRet.maxTxPowerDbm ); 1836 } 1837 } 1838 neighborAPIndex++; 1839 } 1840 1841 /* if neighbor AP list has been exhuasted */ 1842 if ( neighborAPIndex == pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].numOfEntries ) 1843 { 1844 /* reset discovery index */ 1845 pScanMngr->neighborAPsDiscoveryIndex[ bandPolicy->band ] = 0; 1846 } 1847 else 1848 { 1849 /* just update neighbor APs discovery index */ 1850 pScanMngr->neighborAPsDiscoveryIndex[ bandPolicy->band ] = neighborAPIndex; 1851 } 1852 } 1853 1854 /** 1855 * \\n 1856 * \date 06-Mar-2005\n 1857 * \brief Add channel from policy channels list to scan command on the object workspace for discovery scan.\n 1858 * 1859 * Function Scope \e Private.\n 1860 * \param hScanMngr - handle to the scan manager object.\n 1861 * \param bandPolicy - the scan policy for the band to use.\n 1862 */ 1863 void scanMngrAddChannelListForDiscovery( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy ) 1864 { 1865 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1866 paramInfo_t param; 1867 TMacAddr broadcastAddress; 1868 int i, channelListIndex = pScanMngr->channelDiscoveryIndex[ bandPolicy->band ]; 1869 1870 1871 /* set broadcast MAC address */ 1872 for ( i = 0; i < MAC_ADDR_LEN; i++ ) 1873 { 1874 broadcastAddress[ i ] = 0xff; 1875 } 1876 1877 /* loop while channel list has not been exhausted, command is not full, and not enough APs for discovery had been found */ 1878 while ( (pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery) && 1879 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND) && 1880 (channelListIndex < bandPolicy->numOfChannles)) 1881 { 1882 /* verify channel with reg domain */ 1883 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 1884 param.content.channelCapabilityReq.band = bandPolicy->band; 1885 if ( (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) || 1886 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) || 1887 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_SPS)) 1888 { 1889 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; 1890 } 1891 else 1892 { 1893 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; 1894 } 1895 param.content.channelCapabilityReq.channelNum = 1896 bandPolicy->channelList[ channelListIndex ]; 1897 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m ); 1898 1899 /* if the channel is allowed, insert it to the scan command */ 1900 if (param.content.channelCapabilityRet.channelValidity) 1901 { 1902 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->discoveryMethod), 1903 bandPolicy->channelList[ channelListIndex ], 1904 &broadcastAddress, 1905 param.content.channelCapabilityRet.maxTxPowerDbm ); 1906 } 1907 channelListIndex++; 1908 } 1909 1910 /* if channel discovery list has been exhuasted */ 1911 if ( channelListIndex == bandPolicy->numOfChannles ) 1912 { 1913 /* reset discovery index */ 1914 pScanMngr->channelDiscoveryIndex[ bandPolicy->band ] = 0; 1915 } 1916 else 1917 { 1918 /* just update channel list discovery index */ 1919 pScanMngr->channelDiscoveryIndex[ bandPolicy->band ] = channelListIndex; 1920 } 1921 } 1922 1923 /** 1924 * \\n 1925 * \date 02-Mar-2005\n 1926 * \brief Add SPS channels to scan command on the object workspace.\n 1927 * 1928 * Function Scope \e Private.\n 1929 * \param hScanMngr - handle to the scan manager object.\n 1930 * \param scanMethod - The scan method (and parameters) to use.\n 1931 * \param band - the band to scan.\n 1932 */ 1933 void scanMngrAddSPSChannels( TI_HANDLE hScanMngr, TScanMethod* scanMethod, ERadioBand band ) 1934 { 1935 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 1936 TI_UINT64 EarliestTSFToInsert; 1937 TI_UINT32 timeToStartInAdvance = scanMethod->method.spsMethodParams.scanDuration / 1938 SCAN_SPS_DURATION_PART_IN_ADVANCE; 1939 scan_SPSHelper_t nextEventArray[ MAX_SIZE_OF_BSS_TRACK_LIST ]; 1940 int BSSListIndex, i, j, nextEventArrayHead, nextEventArraySize; 1941 paramInfo_t param; 1942 #ifdef SCAN_MNGR_SPS_DBG 1943 TI_UINT32 highValue, lowValue, maxNextEventArraySize; 1944 #endif 1945 1946 TRACE1(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\nscanMngrAddSPSChannels invoked for band %d\n",band); 1947 /* initialize latest TSF value */ 1948 pScanMngr->scanParams.latestTSFValue = 0; 1949 1950 /* initialize the next event arry */ 1951 nextEventArrayHead = -1; 1952 nextEventArraySize = 0; 1953 1954 #ifdef SCAN_MNGR_SPS_DBG 1955 highValue = INT64_HIGHER( pScanMngr->currentTSF ); 1956 lowValue = INT64_LOWER( pScanMngr->currentTSF ); 1957 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "current TSF: %u-%u\n", highValue, lowValue); 1958 #endif 1959 1960 /* insert channels from tracking list to next event array according to requested band */ 1961 for ( BSSListIndex = 0; BSSListIndex < pScanMngr->BSSList.numOfEntries; BSSListIndex++ ) 1962 { 1963 /* if BSS is on the right band */ 1964 if ( band == pScanMngr->BSSList.BSSList[ BSSListIndex ].band ) 1965 { 1966 /* verify the channel with the reg domain */ 1967 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 1968 param.content.channelCapabilityReq.band = band; 1969 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; 1970 param.content.channelCapabilityReq.channelNum = pScanMngr->BSSList.BSSList[ BSSListIndex ].channel; 1971 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m ); 1972 1973 /* if channel is verified for requested scan type */ 1974 if ( param.content.channelCapabilityRet.channelValidity ) 1975 { 1976 /* if this AP local TSF value is greater that latest TSF value, change it */ 1977 if ( pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF > pScanMngr->scanParams.latestTSFValue ) 1978 { 1979 /* the latest TSF value is used by the FW to detect TSF error (an AP recovery). When a TSF 1980 error occurs, the latest TSF value should be in the future (because the AP TSF was 1981 reset). */ 1982 pScanMngr->scanParams.latestTSFValue = pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF; 1983 } 1984 1985 /* calculate the TSF of the next event for tracked AP. Scan should start 1986 SCAN_SPS_DURATION_PART_IN_ADVANCE before the calculated event */ 1987 nextEventArray[ nextEventArraySize ].nextEventTSF = 1988 scanMngrCalculateNextEventTSF( hScanMngr, &(pScanMngr->BSSList), BSSListIndex, 1989 pScanMngr->currentTSF + SCAN_SPS_GUARD_FROM_CURRENT_TSF + 1990 timeToStartInAdvance ) - timeToStartInAdvance; 1991 #ifdef SCAN_MNGR_SPS_DBG 1992 highValue = INT64_HIGHER( nextEventArray[ nextEventArraySize ].nextEventTSF ); 1993 lowValue = INT64_LOWER( nextEventArray[ nextEventArraySize ].nextEventTSF ); 1994 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "BSSID:%02x:%02x:%02x:%02x:%02x:%02x will send frame at TSF:%x-%x\n", pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 5 ], highValue, lowValue); 1995 #endif 1996 nextEventArray[ nextEventArraySize ].trackListIndex = BSSListIndex; 1997 1998 /* insert it, sorted, to the next event array */ 1999 /* if need to insert as head (either because list is empty or because it has earliest TSF) */ 2000 if ( (-1 == nextEventArrayHead) || 2001 (nextEventArray[ nextEventArraySize ].nextEventTSF < nextEventArray[ nextEventArrayHead ].nextEventTSF)) 2002 { 2003 /* link the newly inserted AP to the current head */ 2004 nextEventArray[ nextEventArraySize ].nextAPIndex = nextEventArrayHead; 2005 /* make current head point to newly inserted AP */ 2006 nextEventArrayHead = nextEventArraySize; 2007 nextEventArraySize++; 2008 } 2009 /* insert into the list */ 2010 else 2011 { 2012 /* start with list head */ 2013 i = nextEventArrayHead; 2014 /* while the new AP TSF is larger and list end had not been reached */ 2015 while ( (nextEventArray[ i ].nextAPIndex != -1) && /* list end had not been reached */ 2016 (nextEventArray[ nextEventArray[ i ].nextAPIndex ].nextEventTSF < nextEventArray[ nextEventArraySize ].nextEventTSF)) /* next event TSF of the next AP in the list is smaller than that of the AP being inserted */ 2017 { 2018 /* proceed to the next AP */ 2019 i = nextEventArray[ i ].nextAPIndex; 2020 } 2021 /* insert this AP to the list, right after the next event entry found */ 2022 nextEventArray[ nextEventArraySize ].nextAPIndex = nextEventArray[ i ].nextAPIndex; 2023 nextEventArray[ i ].nextAPIndex = nextEventArraySize; 2024 nextEventArraySize++; 2025 } 2026 } 2027 /* if for some reason a channel on which an AP was found is not valid for passive scan, 2028 the AP should be removed. */ 2029 else 2030 { 2031 /* removing the AP is done by increasing its track count to maximum - and since it is 2032 not tracked it will not be discovered, and thus will be deleted when the scan is complete */ 2033 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount = 2034 pScanMngr->scanPolicy.maxTrackFailures + 1; 2035 #ifdef TI_DBG 2036 /*update statistics */ 2037 pScanMngr->stats.APsRemovedInvalidChannel++; 2038 #endif 2039 } 2040 } 2041 } 2042 2043 #ifdef SCAN_MNGR_SPS_DBG 2044 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "SPS list after first stage:\n"); 2045 scanMngrDebugPrintSPSHelperList( hScanMngr, nextEventArray, nextEventArrayHead, nextEventArraySize ); 2046 maxNextEventArraySize = nextEventArraySize; 2047 #endif 2048 2049 /* insert channels from next event array to scan command */ 2050 EarliestTSFToInsert = pScanMngr->currentTSF + SCAN_SPS_GUARD_FROM_CURRENT_TSF; 2051 /* insert all APs to scan command (as long as command is not full) */ 2052 while ( (nextEventArraySize > 0) && 2053 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_SPS_CHANNELS_PER_COMMAND)) 2054 { 2055 /* if first list entry fits, and it doesn't collide with current AP DTIM */ 2056 if ( EarliestTSFToInsert < nextEventArray[ nextEventArrayHead ].nextEventTSF ) 2057 { 2058 if ( TI_FALSE == scanMngrDTIMInRange( hScanMngr, nextEventArray[ nextEventArrayHead ].nextEventTSF, 2059 nextEventArray[ nextEventArrayHead ].nextEventTSF + scanMethod->method.spsMethodParams.scanDuration )) 2060 { 2061 /* insert it to scan command */ 2062 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.scanStartTime = 2063 INT64_LOWER( (nextEventArray[ nextEventArrayHead ].nextEventTSF)); 2064 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.scanDuration = 2065 scanMethod->method.spsMethodParams.scanDuration; 2066 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.ETMaxNumOfAPframes = 2067 scanMethod->method.spsMethodParams.ETMaxNumberOfApFrames; 2068 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.earlyTerminationEvent = 2069 scanMethod->method.spsMethodParams.earlyTerminationEvent; 2070 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.channel = 2071 pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].channel; 2072 MAC_COPY (pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.bssId, 2073 pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID); 2074 /* increase the AP track attempts counter */ 2075 pScanMngr->BSSList.scanBSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].trackFailCount++; 2076 /* increase number of channels in scan command */ 2077 pScanMngr->scanParams.numOfChannels++; 2078 /* set earliest TSF that would fit in scan command */ 2079 EarliestTSFToInsert = nextEventArray[ nextEventArrayHead ].nextEventTSF + 2080 scanMethod->method.spsMethodParams.scanDuration + 2081 SCAN_SPS_GUARD_FROM_LAST_BSS; 2082 /* remove it from next event array */ 2083 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex; 2084 nextEventArraySize--; 2085 } 2086 else 2087 { 2088 TI_UINT32 beaconIntervalUsec = 2089 pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].beaconInterval * 1024; 2090 2091 /* if the next beacon also collide with DTIM */ 2092 if ( TI_TRUE == scanMngrDTIMInRange( hScanMngr, nextEventArray[ nextEventArrayHead ].nextEventTSF + beaconIntervalUsec, 2093 nextEventArray[ nextEventArrayHead ].nextEventTSF + scanMethod->method.spsMethodParams.scanDuration + beaconIntervalUsec )) 2094 { 2095 /* An AP whose two consecutive beacons collide with current AP DTIM is not trackable by SPS!!! 2096 Shouldn't happen at a normal setup, but checked to avoid endless loop. 2097 First, remove it from the tracking list (by increasing it's track count above the maximum) */ 2098 pScanMngr->BSSList.scanBSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].trackFailCount = 2099 pScanMngr->scanPolicy.maxTrackFailures + 1; 2100 2101 /* and also remove it from the SPS list */ 2102 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex; 2103 nextEventArraySize--; 2104 2105 #ifdef TI_DBG 2106 /* update statistics */ 2107 pScanMngr->stats.APsRemovedDTIMOverlap++; 2108 #endif 2109 } 2110 else 2111 { 2112 /* calculate next event TSF - will get the next beacon, since timeToStartInAdvance is added to current beacon TSF */ 2113 nextEventArray[ nextEventArrayHead ].nextEventTSF = 2114 scanMngrCalculateNextEventTSF( hScanMngr, &(pScanMngr->BSSList), 2115 nextEventArray[ nextEventArrayHead ].trackListIndex, 2116 nextEventArray[ nextEventArrayHead ].nextEventTSF + timeToStartInAdvance + 1) 2117 - timeToStartInAdvance; 2118 2119 #ifdef SCAN_MNGR_SPS_DBG 2120 highValue = INT64_HIGHER( nextEventArray[ nextEventArrayHead ].nextEventTSF ); 2121 lowValue = INT64_LOWER( nextEventArray[ nextEventArrayHead ].nextEventTSF ); 2122 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "reacalculating next frame for BSSID:%02x:%02x:%02x:%02x:%02x:%02x at TSF:%x-%x, bacause of DTIM collision\n", pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 5 ], highValue, lowValue); 2123 #endif 2124 2125 /* reinsert to the next event array, sorted */ 2126 /* if still needs to be head, do nothing (because it's still head). otherwise: */ 2127 if ( (1 < nextEventArraySize) && /* list has more than one entry */ 2128 (nextEventArray[ nextEventArrayHead ].nextEventTSF > nextEventArray[ nextEventArray[ nextEventArrayHead ].nextAPIndex ].nextEventTSF)) /* first event in list is earlier */ 2129 { 2130 /* first remove the head from the list */ 2131 j = nextEventArrayHead; 2132 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex; 2133 2134 /* start with list head */ 2135 i = nextEventArrayHead; 2136 /* while the new AP TSF is larger and list end had not been reached */ 2137 while ( (nextEventArray[ i ].nextAPIndex != -1) && /* list end had not been reached */ 2138 (nextEventArray[ nextEventArray[ i ].nextAPIndex ].nextEventTSF < nextEventArray[ j ].nextEventTSF)) /* next event TSF of the next AP in the list is smaller than that of the AP being inserted */ 2139 { 2140 /* proceed to the next AP */ 2141 i = nextEventArray[ i ].nextAPIndex; 2142 } 2143 /* insert this AP to the list, right after the next event entry found */ 2144 nextEventArray[ j ].nextAPIndex = nextEventArray[ i ].nextAPIndex; 2145 nextEventArray[ i ].nextAPIndex = j; 2146 } 2147 2148 #ifdef SCAN_MNGR_SPS_DBG 2149 scanMngrDebugPrintSPSHelperList( hScanMngr, nextEventArray, nextEventArrayHead, maxNextEventArraySize ); 2150 #endif 2151 #ifdef TI_DBG 2152 /* update statistics */ 2153 pScanMngr->stats.SPSSavedByDTIMCheck++; 2154 #endif 2155 } 2156 } 2157 } 2158 else 2159 { 2160 /* calculate next event TSF */ 2161 nextEventArray[ nextEventArrayHead ].nextEventTSF = 2162 scanMngrCalculateNextEventTSF( hScanMngr, &(pScanMngr->BSSList), 2163 nextEventArray[ nextEventArrayHead ].trackListIndex, 2164 EarliestTSFToInsert + timeToStartInAdvance ) - timeToStartInAdvance; 2165 2166 #ifdef SCAN_MNGR_SPS_DBG 2167 highValue = INT64_HIGHER( nextEventArray[ nextEventArrayHead ].nextEventTSF ); 2168 lowValue = INT64_LOWER( nextEventArray[ nextEventArrayHead ].nextEventTSF ); 2169 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "reacalculating next frame for BSSID:%02x:%02x:%02x:%02x:%02x:%02x at TSF:%x-%x\n", pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 5 ], highValue, lowValue); 2170 #endif 2171 2172 /* reinsert to the next event array, sorted */ 2173 /* if still needs to be head, do nothing (because it's still head). otherwise: */ 2174 if ( (1 < nextEventArraySize) && /* list has more than one entry */ 2175 (nextEventArray[ nextEventArrayHead ].nextEventTSF > nextEventArray[ nextEventArray[ nextEventArrayHead ].nextAPIndex ].nextEventTSF)) /* first event in list is earlier */ 2176 { 2177 /* first remove the head from the list */ 2178 j = nextEventArrayHead; 2179 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex; 2180 2181 /* start with list head */ 2182 i = nextEventArrayHead; 2183 /* while the new AP TSF is larger and list end had not been reached */ 2184 while ( (nextEventArray[ i ].nextAPIndex != -1) && /* list end had not been reached */ 2185 (nextEventArray[ nextEventArray[ i ].nextAPIndex ].nextEventTSF < nextEventArray[ j ].nextEventTSF)) /* next event TSF of the next AP in the list is smaller than that of the AP being inserted */ 2186 { 2187 /* proceed to the next AP */ 2188 i = nextEventArray[ i ].nextAPIndex; 2189 } 2190 /* insert this AP to the list, right after the next event entry found */ 2191 nextEventArray[ j ].nextAPIndex = nextEventArray[ i ].nextAPIndex; 2192 nextEventArray[ i ].nextAPIndex = j; 2193 } 2194 2195 #ifdef SCAN_MNGR_SPS_DBG 2196 scanMngrDebugPrintSPSHelperList( hScanMngr, nextEventArray, nextEventArrayHead, maxNextEventArraySize ); 2197 #endif 2198 } 2199 } 2200 /* For SPS scan, the scan duration is added to the command, since later on current TSF cannot be 2201 reevaluated. The scan duration is TSF at end of scan minus current TSF, divided by 1000 (convert 2202 to milliseconds) plus 1 (for the division reminder). */ 2203 pScanMngr->scanParams.SPSScanDuration = 2204 (((TI_UINT32)(EarliestTSFToInsert - SCAN_SPS_GUARD_FROM_LAST_BSS - pScanMngr->currentTSF)) / 1000) + 1; 2205 } 2206 2207 /** 2208 * \\n 2209 * \date 07-Mar-2005\n 2210 * \brief Calculates local TSF of the next event (beacon or GPR) of the given tracked AP.\n 2211 * 2212 * Function Scope \e Private.\n 2213 * \param hScanMngr - handle to the scan manager object.\n 2214 * \param BSSList - a pointer to the track list.\n 2215 * \param entryIndex - the index of the AP for which calculation is requires in the tracking list.\n 2216 * \param initialTSFValue - local TSF value AFTER which the next event is to found.\n 2217 * \return The approximate current TSF 2218 */ 2219 TI_UINT64 scanMngrCalculateNextEventTSF( TI_HANDLE hScanMngr, scan_BSSList_t* BSSList, TI_UINT8 entryIndex, TI_UINT64 initialTSFValue ) 2220 { 2221 TI_UINT64 remoteBeaconTSF, localBeaconTSF; 2222 TI_INT64 localRemoteTSFDelta; 2223 TI_UINT32 reminder; 2224 TI_INT32 averageDeltaChange = 0; 2225 int i; 2226 #ifdef SCAN_MNGR_SPS_DBG 2227 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2228 #endif /* SCAN_MNGR_SPS_DBG */ 2229 2230 /* graphical representation: 2231 E E E E E E E E E 2232 Remote TSF Line: | | | | | | | | | 2233 0 remoteTSF | | | | | | | | | Returned value 2234 +-----------------------+------+------+------+------+------+------+------+------+------+------+----------------... 2235 2236 Local TSF Line: 2237 0 localTSF initialTSFValue 2238 +-------------------+---------------------------------------------------------------+-----+---------------... 2239 2240 note that: 2241 1. both lines Don't start at the same time! 2242 2. remoteTSF and localTSF were measured when last frame was received from the tracked AP. the difference between their 2243 values is the constant difference between the two lines. 2244 3. initialTSFValue is the local TSF the first event after which is requested. 2245 4. returned value is the TSF (in local scale!) of the next event of the tracked AP. 2246 5. an E represents an occurring event, which is a scheduled frame transmission (beacon or GPR) of the tracked AP. 2247 */ 2248 2249 /* 2250 * The next event TSF is calculated as follows: 2251 * first, the difference between the local TSF (that of the AP the STA is currently connected to) and the 2252 * remote TSF (that of the AP being tracked) is calculated using the TSF values measured when last scan was 2253 * performed. Than, the initial TSF value is converted to remote TSF value, using the delta just calculated. 2254 * The next remote TSF is found (in remote TSF value) by subtracting the reminder of dividing the current 2255 * remote TSF value by the remote beacon interval (time passed from last beacon) from the current remote TSF 2256 * (hence amounting to the last beacon remote TSF), and than adding beacon interval. This is finally converted 2257 * back to local TSF, which is the requested value. 2258 * 2259 * After all this is done, clock drift between current AP and remote AP is compensated. This is done in thr 2260 * following way: the delte between local TSF and remote TSF is compared to this value at the last scan 2261 * (if they are equal, the clocks tick at the same rate). This difference is store in an array holding a 2262 * configured number of such previous differences (currenlty 4). The average value of these previous values 2263 * is then calculated, and added the the TSF value calculated before. This way, the average drift between 2264 * the local AP and the candidate AP is measured, and the next drift value can be estimated and thus 2265 * taken into account. 2266 */ 2267 2268 #ifdef SCAN_MNGR_SPS_DBG 2269 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "initial TSF value:%x-%x\n", INT64_HIGHER( initialTSFValue ), INT64_LOWER( initialTSFValue )); 2270 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "local time stamp:%x-%x\n", INT64_HIGHER( BSSList->scanBSSList[ entryIndex ].localTSF ), INT64_LOWER( BSSList->scanBSSList[ entryIndex ].localTSF )); 2271 #endif 2272 /* calculate the delta between local and remote TSF */ 2273 localRemoteTSFDelta = BSSList->scanBSSList[ entryIndex ].localTSF - 2274 BSSList->BSSList[ entryIndex ].lastRxTSF; 2275 /* convert initial TSF to remote timeline */ 2276 remoteBeaconTSF = initialTSFValue - localRemoteTSFDelta; 2277 #ifdef SCAN_MNGR_SPS_DBG 2278 TRACE4( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Local TSF:%u-%u, Remote TSF: %u-%u\n", INT64_HIGHER(BSSList->scanBSSList[ entryIndex ].localTSF), INT64_LOWER(BSSList->scanBSSList[ entryIndex ].localTSF), INT64_HIGHER(BSSList->BSSList[ entryIndex ].lastRxTSF), INT64_LOWER(BSSList->BSSList[ entryIndex ].lastRxTSF))); 2279 TRACE4( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "TSF delta:%u-%u, current remote TSF:%u-%u\n", INT64_HIGHER(localRemoteTSFDelta), INT64_LOWER(localRemoteTSFDelta), INT64_HIGHER(remoteBeaconTSF ), INT64_LOWER(remoteBeaconTSF )); 2280 #endif 2281 /* find last remote beacon transmission by subtracting the reminder of current remote TSF divided 2282 by the beacon interval (indicating how much time passed since last beacon) from current remote 2283 TSF */ 2284 reminder = reminder64( remoteBeaconTSF, BSSList->BSSList[ entryIndex ].beaconInterval * 1024 ); 2285 remoteBeaconTSF -= reminder; 2286 2287 #ifdef SCAN_MNGR_SPS_DBG 2288 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "reminder=%d\n",reminder); 2289 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Last remote beacon TSF:%x-%x\n", INT64_HIGHER(remoteBeaconTSF), INT64_LOWER(remoteBeaconTSF)); 2290 #endif 2291 /* advance from last beacon to next beacon */ 2292 remoteBeaconTSF += BSSList->BSSList[ entryIndex ].beaconInterval * 1024; 2293 #ifdef SCAN_MNGR_SPS_DBG 2294 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Next remote beacon TSF:%x-%x\n", INT64_HIGHER(remoteBeaconTSF), INT64_LOWER(remoteBeaconTSF)); 2295 #endif 2296 2297 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION 2298 /* update delta change array with the change between current and last delta (if last delta is valid) */ 2299 if ( 0 != BSSList->scanBSSList[ entryIndex ].prevTSFDelta ) 2300 { 2301 BSSList->scanBSSList[ entryIndex ].deltaChangeArray[ BSSList->scanBSSList[ entryIndex ].deltaChangeArrayIndex ] = 2302 (TI_INT32)(localRemoteTSFDelta - BSSList->scanBSSList[ entryIndex ].prevTSFDelta); 2303 #ifdef SCAN_MNGR_SPS_DBG 2304 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "current delta^2:%d\n", localRemoteTSFDelta - BSSList->scanBSSList[ entryIndex ].prevTSFDelta); 2305 #endif 2306 if ( SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES == ++BSSList->scanBSSList[ entryIndex ].deltaChangeArrayIndex ) 2307 { 2308 BSSList->scanBSSList[ entryIndex ].deltaChangeArrayIndex = 0; 2309 } 2310 } 2311 BSSList->scanBSSList[ entryIndex ].prevTSFDelta = localRemoteTSFDelta; 2312 2313 /* calculate average delta change, and add (or subtract) it from beacon timing */ 2314 for ( i = 0; i < SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES; i++ ) 2315 { 2316 averageDeltaChange += BSSList->scanBSSList[ entryIndex ].deltaChangeArray[ i ]; 2317 } 2318 averageDeltaChange /= SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES; 2319 #ifdef SCAN_MNGR_SPS_DBG 2320 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "average delta change: %d\n", averageDeltaChange); 2321 #endif /* SCAN_MNGR_SPS_DBG */ 2322 remoteBeaconTSF += averageDeltaChange; 2323 #endif 2324 2325 /* convert to local TSF */ 2326 localBeaconTSF = remoteBeaconTSF + localRemoteTSFDelta; 2327 2328 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION 2329 /* if beacon (in local TSF) is before initial TSF value (possible due to drift compensation), 2330 proceed to next beacon */ 2331 if ( localBeaconTSF < initialTSFValue ) 2332 { 2333 localBeaconTSF += (BSSList->BSSList[ entryIndex ].beaconInterval * 1024); 2334 } 2335 #endif 2336 2337 return localBeaconTSF; 2338 } 2339 2340 /** 2341 * \\n 2342 * \date 20-September-2005\n 2343 * \brief Check whether a time range collides with current AP DTIM 2344 * 2345 * Function Scope \e Private.\n 2346 * \param hScanMngr - handle to the scan manager object.\n 2347 * \param rangeStart - the time range start TSF.\n 2348 * \param rangeEnd - the time range end TSF.\n 2349 * \return Whether the event collides with a DTIM (TRUF if it does, TI_FALSE if it doesn't).\n 2350 */ 2351 TI_BOOL scanMngrDTIMInRange( TI_HANDLE hScanMngr, TI_UINT64 rangeStart, TI_UINT64 rangeEnd ) 2352 { 2353 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2354 TI_UINT64 DTIMEventStart, DTIMEventEnd; 2355 TI_UINT32 DTIMPeriodInUsec; /* DTIM period in micro seconds */ 2356 2357 #ifdef SCAN_MNGR_DTIM_DBG 2358 TRACE4( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "DTIM check: SPS raneg start:%x-%x, end:%x-%x\n", INT64_HIGHER(rangeStart), INT64_LOWER(rangeStart), INT64_HIGHER(rangeEnd), INT64_LOWER(rangeEnd)); 2359 #endif 2360 2361 /* calculate DTIM period */ 2362 DTIMPeriodInUsec = pScanMngr->currentBSSBeaconInterval * 1024 * pScanMngr->currentBSSDtimPeriod; 2363 2364 #ifdef SCAN_MNGR_DTIM_DBG 2365 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "DTIM period in usec: %d\n", DTIMPeriodInUsec); 2366 #endif 2367 2368 /* calculate (from DTIM count) the first DTIM after the last seen beacon. The last seen beacon will always 2369 occur before the SPS - because it already happened, and the SPS is a future event. However, the next DTIM 2370 is not necessarily prior to the SPS - it is also a future event (if the last beacon was not a DTIM) */ 2371 if ( 0 == pScanMngr->lastLocalBcnDTIMCount ) 2372 { /* The last beacon was a DTIM */ 2373 DTIMEventStart = pScanMngr->lastLocalBcnTSF; 2374 } 2375 else 2376 { /* The last beacon was not a DTIM - calculate the next beacon that will be a DTIM */ 2377 DTIMEventStart = pScanMngr->lastLocalBcnTSF + 2378 ((pScanMngr->currentBSSDtimPeriod - pScanMngr->lastLocalBcnDTIMCount) * pScanMngr->currentBSSBeaconInterval); 2379 TRACE6(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "\n Next DTIM TSF:%u-%u , last beacon TSF:%u-%u, last DTIM count: %d, beacon interval: %d\n", INT64_HIGHER(DTIMEventStart), INT64_LOWER(DTIMEventStart), INT64_HIGHER(pScanMngr->lastLocalBcnTSF), INT64_LOWER(pScanMngr->lastLocalBcnTSF), pScanMngr->lastLocalBcnDTIMCount, pScanMngr->currentBSSBeaconInterval); 2380 } 2381 #ifdef SCAN_MNGR_DTIM_DBG 2382 TRACE6( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Next DTIM TSF:%u-%u, last beacon TSF:%u-%u, last DTIM count: %d, beacon interval: %d\n", INT64_HIGHER(DTIMEventStart), INT64_LOWER(DTIMEventStart), INT64_HIGHER(pScanMngr->lastLocalBcnTSF), INT64_LOWER(pScanMngr->lastLocalBcnTSF), pScanMngr->lastLocalBcnDTIMCount, pScanMngr->currentBSSBeaconInterval); 2383 #endif 2384 2385 /* calculate the DTIM event end (add the DTIM length). Note that broadcast frames after the DTIM are not 2386 taken into consideration because their availability and length varies. Even if at some point SPS will be 2387 missed due to broadcast RX frames, it does not mean this AP cannot be tracked. */ 2388 DTIMEventEnd = DTIMEventStart + SCAN_SPS_FW_DTIM_LENGTH; 2389 2390 /* if this DTIM is after the SPS end - than no collision will occur! */ 2391 if ( DTIMEventStart > rangeEnd ) 2392 { 2393 #ifdef SCAN_MNGR_DTIM_DBG 2394 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "no collision because DTIM is after SPS\n"); 2395 #endif 2396 return TI_FALSE; 2397 } 2398 /* if this DTIM end is not before the SPS range start - it means the DTIM is colliding with the SPS, because 2399 it neither ends before the SPS nor starts after it */ 2400 else if ( DTIMEventEnd >= rangeStart ) 2401 { 2402 #ifdef SCAN_MNGR_DTIM_DBG 2403 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Collision beacuse DTIM is not before SPS\n"); 2404 #endif 2405 return TI_TRUE; 2406 } 2407 /* the DTIM is before the SPS range - find the first DTIM after the SPS start (and check if it's colliding 2408 with the SPS range */ 2409 else 2410 { 2411 /* get the usec difference from the SPS range start to the last DTIM */ 2412 TI_UINT64 usecDiffFromRangeStartToLastDTIM = rangeStart - DTIMEventStart; 2413 /* get the reminder from the usec difference divided by the DTIM period - the time (in usec) from last DTIM 2414 to SPS start */ 2415 TI_UINT32 reminder = reminder64( usecDiffFromRangeStartToLastDTIM, DTIMPeriodInUsec ); 2416 /* get the next DTIM start time by adding DTIM period to the last DTIM before the SPS range start */ 2417 DTIMEventStart = rangeStart - reminder + DTIMPeriodInUsec; 2418 /* get DTIM end time */ 2419 DTIMEventEnd = DTIMEventStart + SCAN_SPS_FW_DTIM_LENGTH; 2420 #ifdef SCAN_MNGR_DTIM_DBG 2421 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Diff from range start to last DTIM: %x-%x, reminder:%d, DTIM start:%x-%x, DTIM end: %x-%x\n", INT64_HIGHER(usecDiffFromRangeStartToLastDTIM), INT64_LOWER(usecDiffFromRangeStartToLastDTIM), reminder, INT64_HIGHER(DTIMEventStart), INT64_LOWER(DTIMEventStart), INT64_HIGHER(DTIMEventEnd), INT64_LOWER(DTIMEventEnd)); 2422 #endif 2423 2424 /* if the SPS starts after the DTIM ends or before the DTIM starts - no collision occurs */ 2425 if ( (rangeStart > DTIMEventEnd) || (rangeEnd < DTIMEventStart)) 2426 { 2427 #ifdef SCAN_MNGR_DTIM_DBG 2428 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "No collision will occur because DTIM is before or after SPS\n"); 2429 #endif 2430 return TI_FALSE; 2431 } 2432 /* otherwise - a collision will occur! */ 2433 { 2434 #ifdef SCAN_MNGR_DTIM_DBG 2435 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Collision will occur!\n"); 2436 #endif 2437 return TI_TRUE; 2438 } 2439 } 2440 } 2441 2442 /** 2443 * \\n 2444 * \date 03-Mar-2005\n 2445 * \brief Add a normal channel entry to the object workspace scan command.\n 2446 * 2447 * Function Scope \e Private.\n 2448 * \param hScanMngr - handle to the scan manager object.\n 2449 * \param scanMethod - The scan method (and parameters) to use.\n 2450 * \param channel - the channel index.\n 2451 * \param BSSID - pointer to the BSSID to use (may be broadcast.\n 2452 * \param txPowerDbm - tx power to transmit probe requests.\n 2453 */ 2454 void scanMngrAddNormalChannel( TI_HANDLE hScanMngr, TScanMethod* scanMethod, TI_UINT8 channel, 2455 TMacAddr* BSSID, TI_UINT8 txPowerDbm ) 2456 { 2457 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2458 int commandChannelIndex; 2459 TScanBasicMethodParams* basicMethodParams; 2460 2461 /* get next channel in the object workspace */ 2462 commandChannelIndex = pScanMngr->scanParams.numOfChannels; 2463 pScanMngr->scanParams.numOfChannels++; 2464 2465 /* get basic method params pointer according to scan type */ 2466 switch ( scanMethod->scanType ) 2467 { 2468 case SCAN_TYPE_NORMAL_PASSIVE: 2469 case SCAN_TYPE_NORMAL_ACTIVE: 2470 basicMethodParams = &(scanMethod->method.basicMethodParams); 2471 break; 2472 2473 case SCAN_TYPE_TRIGGERED_PASSIVE: 2474 case SCAN_TYPE_TRIGGERED_ACTIVE: 2475 basicMethodParams = &(scanMethod->method.TidTriggerdMethodParams.basicMethodParams); 2476 break; 2477 2478 default: 2479 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Unercognized scan type %d when adding normal channel to scan list.\n", scanMethod->scanType ); 2480 basicMethodParams = NULL; 2481 return; 2482 } 2483 2484 /* set params */ 2485 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.channel = channel; 2486 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.txPowerDbm = 2487 TI_MIN( txPowerDbm, basicMethodParams->probReqParams.txPowerDbm ); 2488 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.maxChannelDwellTime = 2489 basicMethodParams->maxChannelDwellTime; 2490 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.minChannelDwellTime = 2491 basicMethodParams->minChannelDwellTime; 2492 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.earlyTerminationEvent = 2493 basicMethodParams->earlyTerminationEvent; 2494 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.ETMaxNumOfAPframes = 2495 basicMethodParams->ETMaxNumberOfApFrames; 2496 2497 MAC_COPY (pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.bssId, *BSSID); 2498 } 2499 2500 /** 2501 * \\n 2502 * \date 02-Mar-2005\n 2503 * \brief Removes an entry from the BSS list (by replacing it with another entry, if any). 2504 * 2505 * Function Scope \e Private.\n 2506 * \param hScanMngr - handle to the scan manager object.\n 2507 * \param BSSEntryIndex - index of the entry to remove.\n 2508 */ 2509 void scanMngrRemoveBSSListEntry( TI_HANDLE hScanMngr, TI_UINT8 BSSEntryIndex ) 2510 { 2511 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2512 TI_UINT8* tempResultBuffer; 2513 2514 #ifdef TI_DBG 2515 /*update statistics */ 2516 if ( SCAN_MNGR_STAT_MAX_TRACK_FAILURE <= pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ].trackFailCount ) 2517 { 2518 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ SCAN_MNGR_STAT_MAX_TRACK_FAILURE - 1 ]++; 2519 } 2520 else 2521 { 2522 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ].trackFailCount ]++; 2523 } 2524 #endif 2525 /* if no more entries are available, simply reduce the number of entries. 2526 As this is the last entry, it won't be accessed any more. */ 2527 if ( (pScanMngr->BSSList.numOfEntries-1) == BSSEntryIndex ) 2528 { 2529 2530 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Removing last entry %d in BSS list\n", pScanMngr->BSSList.numOfEntries); 2531 2532 pScanMngr->BSSList.numOfEntries--; 2533 } 2534 else 2535 { 2536 #ifdef SCAN_MNGR_DBG 2537 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Removing entry %d of %d\n", BSSEntryIndex, pScanMngr->BSSList.numOfEntries); 2538 #endif 2539 /* keep the scan result buffer pointer */ 2540 tempResultBuffer = pScanMngr->BSSList.BSSList[ BSSEntryIndex ].pBuffer; 2541 /* copy the last entry over this one */ 2542 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.BSSList[ BSSEntryIndex ]), 2543 &(pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries-1 ]), 2544 sizeof(bssEntry_t)); 2545 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ]), 2546 &(pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries-1 ]), 2547 sizeof(scan_BSSEntry_t)); 2548 /* replace the scan result buffer of the last entry */ 2549 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries-1 ].pBuffer = tempResultBuffer; 2550 /* decrease the number of BSS entries */ 2551 pScanMngr->BSSList.numOfEntries--; 2552 } 2553 } 2554 2555 /** 2556 * \\n 2557 * \date 02-Mar-2005\n 2558 * \brief Removes all BSS list entries that are neither neighbor APs not on a policy defined channel.\n 2559 * 2560 * Function Scope \e Private.\n 2561 * \param hScanMngr - handle to the scan manager object.\n 2562 * \param bCheckNeighborAPs - whether to verify that APs marked as neighbor APs are really neighbor APs.\n 2563 * \param bCheckChannels - whether to verify that APs not marked as neighbor APs are on policy defined channel.\n 2564 */ 2565 void scanMngrUpdateBSSList( TI_HANDLE hScanMngr, TI_BOOL bCheckNeighborAPs, TI_BOOL bCheckChannels ) 2566 { 2567 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2568 int BSSEntryIndex; 2569 2570 /* loop on all BSS list entry */ 2571 for ( BSSEntryIndex = 0; BSSEntryIndex < pScanMngr->BSSList.numOfEntries; BSSEntryIndex++ ) 2572 { 2573 /* an AP can be in the BSS list either because it's a neighbor AP or, if not, because it's on a 2574 policy defined channel. When Neighbor AP list is changed, it is only necessary to check APs that 2575 are in the list because they are neighbor APs. When the policy is changed, it is only necessary 2576 to check APs that are in the list because they are on a policy defined channel. */ 2577 2578 /* if a check for neighbor APs is requested, check only APs that are designated as neighbor APs, 2579 and only check if they still are neighbor APs */ 2580 if ( (TI_TRUE == bCheckNeighborAPs) && 2581 (TI_TRUE == pScanMngr->BSSList.BSSList[ BSSEntryIndex ].bNeighborAP) && 2582 (-1 == scanMngrGetNeighborAPIndex( hScanMngr, 2583 pScanMngr->BSSList.BSSList[ BSSEntryIndex ].band, 2584 &(pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID)))) 2585 { 2586 /* remove it */ 2587 scanMngrRemoveBSSListEntry( hScanMngr, BSSEntryIndex ); 2588 } 2589 2590 /* if a check for policy defined channels is requested, check only APs that are not designated as 2591 neighbor APs */ 2592 if ( (TI_TRUE == bCheckChannels) && 2593 (TI_FALSE == pScanMngr->BSSList.BSSList[ BSSEntryIndex ].bNeighborAP) && 2594 (TI_FALSE == scanMngrIsPolicyChannel( hScanMngr, 2595 pScanMngr->BSSList.BSSList[ BSSEntryIndex ].band, 2596 pScanMngr->BSSList.BSSList[ BSSEntryIndex ].channel ))) 2597 { 2598 /* remove it */ 2599 scanMngrRemoveBSSListEntry( hScanMngr, BSSEntryIndex ); 2600 } 2601 } 2602 } 2603 2604 /** 2605 * \\n 2606 * \date 02-Mar-2005\n 2607 * \brief returns the index of a neighbor AP.\n 2608 * 2609 * Function Scope \e Private.\n 2610 * \param hScanMngr - handle to the scan manager object.\n 2611 * \param band - the band on which the AP resides.\n 2612 * \param bssId - the AP's BSSID.\n 2613 * \return the index into the neighbor AP list for the given address, -1 if AP is not in list.\n 2614 */ 2615 TI_INT8 scanMngrGetNeighborAPIndex( TI_HANDLE hScanMngr, ERadioBand band, TMacAddr* bssId ) 2616 { 2617 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2618 int i; 2619 2620 /* loop on all neighbor APS for this AP's band, and compare BSSID's */ 2621 for ( i = 0; i < pScanMngr->neighborAPsDiscoveryList[ band ].numOfEntries; i++ ) 2622 { 2623 if (MAC_EQUAL (*bssId, pScanMngr->neighborAPsDiscoveryList[ band ].APListPtr[ i ].BSSID)) 2624 { 2625 return i; 2626 } 2627 } 2628 2629 /* if the AP wasn't found in the list, it's not a neighbor AP... */ 2630 return -1; 2631 } 2632 2633 /** 2634 * \\n 2635 * \date 02-Mar-2005\n 2636 * \brief Checks whether a channel is defined on a policy.\n 2637 * 2638 * Function Scope \e Private.\n 2639 * \param hScanMngr - handle to the scan manager object.\n 2640 * \param band - the band on which the channel is.\n 2641 * \param channel - the channel number.\n 2642 * \return TI_TRUE if channel is defined on policy, TI_FALSE otherwise.\n 2643 */ 2644 TI_BOOL scanMngrIsPolicyChannel( TI_HANDLE hScanMngr, ERadioBand band, TI_UINT8 channel ) 2645 { 2646 int i; 2647 TScanBandPolicy* bandPolicy = scanMngrGetPolicyByBand( hScanMngr, band ); 2648 2649 2650 /* check if the AP's band is defined in the policy */ 2651 if ( NULL == bandPolicy ) 2652 { 2653 return TI_FALSE; 2654 } 2655 2656 /* loop on all channels for the AP's band */ 2657 for ( i = 0; i < bandPolicy->numOfChannles; i++ ) 2658 { 2659 if ( bandPolicy->channelList[ i ] == channel ) 2660 { 2661 return TI_TRUE; 2662 } 2663 } 2664 2665 /* if no channel was found, the AP is NOT on a policy configured channel */ 2666 return TI_FALSE; 2667 } 2668 2669 /** 2670 * \\n 2671 * \date 18-Apr-2005\n 2672 * \brief Converts scan concentrator result status to scan manager result status, to be returned to roaming manager.\n 2673 * 2674 * Function Scope \e Private.\n 2675 * \param result status - scan concentrator result status.\n 2676 * \return appropriate scan manager status.\n 2677 */ 2678 scan_mngrResultStatus_e scanMngrConvertResultStatus( EScanCncnResultStatus resultStatus ) 2679 { 2680 switch (resultStatus) 2681 { 2682 case SCAN_CRS_SCAN_COMPLETE_OK: 2683 return SCAN_MRS_SCAN_COMPLETE_OK; 2684 /* break; - unreachable */ 2685 2686 case SCAN_CRS_SCAN_RUNNING: 2687 return SCAN_MRS_SCAN_RUNNING; 2688 /* break; - unreachable */ 2689 2690 case SCAN_CRS_SCAN_FAILED: 2691 return SCAN_MRS_SCAN_FAILED; 2692 /* break; - unreachable */ 2693 2694 case SCAN_CRS_SCAN_STOPPED: 2695 return SCAN_MRS_SCAN_STOPPED; 2696 /* break; - unreachable */ 2697 2698 case SCAN_CRS_TSF_ERROR: 2699 return SCAN_MRS_SCAN_FAILED; 2700 /* break; - unreachable */ 2701 2702 case SCAN_CRS_SCAN_ABORTED_FW_RESET: 2703 return SCAN_MRS_SCAN_ABORTED_FW_RESET; 2704 /* break; - unreachable */ 2705 2706 case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY: 2707 return SCAN_MRS_SCAN_ABORTED_HIGHER_PRIORITY; 2708 /* break; - unreachable */ 2709 2710 default: 2711 return SCAN_MRS_SCAN_FAILED; 2712 /* break; - unreachable */ 2713 } 2714 } 2715 2716 /************************************************************************/ 2717 /* Trace functions */ 2718 /************************************************************************/ 2719 2720 #ifdef REPORT_LOG 2721 2722 static char scanTypeDesc[ 6 ][ MAX_DESC_LENGTH ] = 2723 { 2724 "passive normal scan", 2725 "active normal scan", 2726 "SPS scan", 2727 "passive triggered scan", 2728 "active triggered scan", 2729 "no scan type" 2730 }; 2731 2732 static char earlyTerminationConditionDesc[ 4 ][ MAX_DESC_LENGTH ] = 2733 { 2734 "Early termination disabled", 2735 "Early termination on beacon", 2736 "Early termination on probe response", 2737 "Early termination on both" 2738 }; 2739 2740 #ifdef TI_DBG 2741 static char booleanDesc[ 2 ][ MAX_DESC_LENGTH ] = 2742 { 2743 "No", 2744 "Yes" 2745 }; 2746 2747 static char contScanStatesDesc[ SCAN_CSS_NUM_OF_STATES ][ MAX_DESC_LENGTH ] = 2748 { 2749 "IDLE", 2750 "TRACKING ON G", 2751 "TRACKING ON A", 2752 "DISCOVERING", 2753 "STOPPING" 2754 }; 2755 2756 static char immedScanStatesDesc[ SCAN_ISS_NUM_OF_STATES ][ MAX_DESC_LENGTH ] = 2757 { 2758 "IDLE", 2759 "IMMEDIATE ON G", 2760 "IMMEDIATE ON A", 2761 "STOPPING" 2762 }; 2763 2764 static char discoveryPartDesc[ SCAN_SDP_NUMBER_OF_DISCOVERY_PARTS ][ MAX_DESC_LENGTH ] = 2765 { 2766 "G neighbor APs", 2767 "A neighbor APs", 2768 "G channels", 2769 "A Channels", 2770 "No discovery" 2771 }; 2772 2773 static char neighborDiscovreyStateDesc[ SCAN_NDS_NUMBER_OF_NEIGHBOR_DISCOVERY_STATES ][ MAX_DESC_LENGTH ] = 2774 { 2775 "Discovered", 2776 "Not discovered", 2777 "Current AP" 2778 }; 2779 2780 static char earlyTerminationDesc[ SCAN_ET_COND_NUM_OF_CONDS ][ MAX_DESC_LENGTH ] = 2781 { 2782 "None", 2783 "Beacon", 2784 "Prob. resp." 2785 "Bcn & prob. resp." 2786 }; 2787 #endif 2788 2789 #endif 2790 2791 /** 2792 * \\n 2793 * \date 09-Mar-2005\n 2794 * \brief Print a neighbor AP list.\n 2795 * 2796 * Function Scope \e Private.\n 2797 * \param hScanMngr - handle to the scan manager object.\n 2798 * \param neighborAPList - the list of neighbor APs to print.\n 2799 */ 2800 void scanMngrTracePrintNeighborAPsList( TI_HANDLE hScanMngr, neighborAPList_t *neighborAPList ) 2801 { 2802 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2803 int i; 2804 2805 /* print number of entries */ 2806 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Neighbor AP list with %d entries.\n\n", neighborAPList->numOfEntries); 2807 2808 /* print all APs in list */ 2809 for ( i = 0; i < neighborAPList->numOfEntries; i++ ) 2810 { 2811 scanMngrTracePrintNeighborAP( hScanMngr, &(neighborAPList->APListPtr[ i ])); 2812 } 2813 } 2814 2815 /** 2816 * \\n 2817 * \date 09-Mar-2005\n 2818 * \brief Print a neighbor AP.\n 2819 * 2820 * Function Scope \e Private.\n 2821 * \param hScanMngr - handle to the scan manager object.\n 2822 * \param neighborAP - the neighbor AP to print.\n 2823 */ 2824 void scanMngrTracePrintNeighborAP( TI_HANDLE hScanMngr, neighborAP_t* neighborAP ) 2825 { 2826 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2827 2828 /* print neighbor AP content */ 2829 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Neighbor AP band: , channel: %d, MAC address (BSSID): %2x:%2x:%2x:%2x:%2x:%2xn", neighborAP->channel, neighborAP->BSSID[ 0 ], neighborAP->BSSID[ 1 ], neighborAP->BSSID[ 2 ], neighborAP->BSSID[ 3 ], neighborAP->BSSID[ 4 ], neighborAP->BSSID[ 5 ]); 2830 } 2831 2832 /** 2833 * \\n 2834 * \date 09-Mar-2005\n 2835 * \brief Print scan policy.\n 2836 * 2837 * Function Scope \e Private.\n 2838 * \param scanPolicy - scan policy to print.\n 2839 */ 2840 void scanMngrTracePrintScanPolicy( TScanPolicy* scanPolicy ) 2841 { 2842 int i; 2843 2844 /* print general policy parameters */ 2845 WLAN_OS_REPORT(("Global policy parameters:\n")); 2846 WLAN_OS_REPORT(("Normal scan interval: %d, deteriorating scan interval: %d\n", 2847 scanPolicy->normalScanInterval, scanPolicy->deterioratingScanInterval)); 2848 WLAN_OS_REPORT(("BSS list size: %d, numnber of tracked APs to start discovery: %d, " 2849 "Max track failures:% d\n", scanPolicy->BSSListSize, 2850 scanPolicy->BSSNumberToStartDiscovery, scanPolicy->maxTrackFailures)); 2851 2852 /* print band policy parameters for all available bands */ 2853 for ( i = 0; i < scanPolicy->numOfBands; i++ ) 2854 { 2855 scanMngrTracePrintBandScanPolicy( &(scanPolicy->bandScanPolicy[ i ])); 2856 } 2857 } 2858 2859 /** 2860 * \\n 2861 * \date 09-Mar-2005\n 2862 * \brief Print a band scan policy AP.\n 2863 * 2864 * Function Scope \e Private.\n 2865 * \param bandPolicy - the band scan policy to print.\n 2866 */ 2867 void scanMngrTracePrintBandScanPolicy( TScanBandPolicy* bandPolicy ) 2868 { 2869 int i; 2870 2871 WLAN_OS_REPORT(("Band scan policy for band: %s\n", 2872 (RADIO_BAND_2_4_GHZ == bandPolicy->band ? "2.4 GHz (b/g)" : "5.0 GHz (a)"))); 2873 WLAN_OS_REPORT(("Maximal number of channels to scan at each discovery interval %d:\n", 2874 bandPolicy->numOfChannlesForDiscovery)); 2875 WLAN_OS_REPORT(("RSSI Threshold: %d\n", bandPolicy->rxRSSIThreshold)); 2876 WLAN_OS_REPORT(("Tracking method:\n")); 2877 scanMngrTracePrintScanMethod( &(bandPolicy->trackingMethod)); 2878 WLAN_OS_REPORT(("Discovery method:\n")); 2879 scanMngrTracePrintScanMethod( &(bandPolicy->discoveryMethod)); 2880 WLAN_OS_REPORT(("Immediate scan method:\n")); 2881 scanMngrTracePrintScanMethod( &(bandPolicy->immediateScanMethod)); 2882 WLAN_OS_REPORT(("Channels: ")); 2883 for( i = 0; i < bandPolicy->numOfChannles; i++ ) 2884 { 2885 WLAN_OS_REPORT(("%d ", bandPolicy->channelList[ i ])); 2886 } 2887 WLAN_OS_REPORT(("\n")); 2888 } 2889 2890 /** 2891 * \\n 2892 * \date 09-Mar-2005\n 2893 * \brief Print a scan method 2894 * 2895 * Function Scope \e Private.\n 2896 * \param scanMethod - the scan method to print.\n 2897 */ 2898 void scanMngrTracePrintScanMethod( TScanMethod* scanMethod ) 2899 { 2900 WLAN_OS_REPORT(("Scan type: %s\n", scanTypeDesc[ scanMethod->scanType ])); 2901 2902 switch (scanMethod->scanType) 2903 { 2904 case SCAN_TYPE_NORMAL_ACTIVE: 2905 case SCAN_TYPE_NORMAL_PASSIVE: 2906 scanMngrTracePrintNormalScanMethod( &(scanMethod->method.basicMethodParams)); 2907 break; 2908 2909 case SCAN_TYPE_TRIGGERED_ACTIVE: 2910 case SCAN_TYPE_TRIGGERED_PASSIVE: 2911 scanMngrTracePrintTriggeredScanMethod( &(scanMethod->method.TidTriggerdMethodParams)); 2912 break; 2913 2914 case SCAN_TYPE_SPS: 2915 scanMngrTracePrintSPSScanMethod( &(scanMethod->method.spsMethodParams)); 2916 break; 2917 2918 case SCAN_TYPE_NO_SCAN: 2919 default: 2920 WLAN_OS_REPORT(("No scan method defined\n")); 2921 break; 2922 } 2923 } 2924 2925 /** 2926 * \\n 2927 * \date 09-Mar-2005\n 2928 * \brief print a normal scan method 2929 * 2930 * Function Scope \e Private.\n 2931 * \param basicMethodParams - the basic method parameters to print.\n 2932 */ 2933 void scanMngrTracePrintNormalScanMethod( TScanBasicMethodParams* basicMethodParams ) 2934 { 2935 WLAN_OS_REPORT(("Max channel dwell time: %d, min channel dwell time: %d\n", 2936 basicMethodParams->maxChannelDwellTime, basicMethodParams->minChannelDwellTime)); 2937 WLAN_OS_REPORT(("Early termination condition: %s, frame number for early termination: %d\n", 2938 earlyTerminationConditionDesc[ basicMethodParams->earlyTerminationEvent >> 4 ], 2939 basicMethodParams->ETMaxNumberOfApFrames)); 2940 WLAN_OS_REPORT(("Number of probe requests: %d, TX level: %d, probe request rate: %d\n", 2941 basicMethodParams->probReqParams.numOfProbeReqs, 2942 basicMethodParams->probReqParams.txPowerDbm, 2943 basicMethodParams->probReqParams.bitrate)); 2944 } 2945 2946 /** 2947 * \\n 2948 * \date 09-Mar-2005\n 2949 * \brief print an AC triggered scan method 2950 * 2951 * Function Scope \e Private.\n 2952 * \param triggeredMethodParams - the AC-triggered method parameters to print.\n 2953 */ 2954 void scanMngrTracePrintTriggeredScanMethod( TScanTidTriggeredMethodParams* triggeredMethodParams ) 2955 { 2956 WLAN_OS_REPORT(("Triggering Tid: %d\n", triggeredMethodParams->triggeringTid)); 2957 scanMngrTracePrintNormalScanMethod( &(triggeredMethodParams->basicMethodParams)); 2958 } 2959 2960 /** 2961 * \\n 2962 * \date 09-Mar-2005\n 2963 * \brief print a SPS scan method 2964 * 2965 * Function Scope \e Private.\n 2966 * \param SPSMethodParams - the SPS method parameters to print.\n 2967 */ 2968 void scanMngrTracePrintSPSScanMethod( TScanSPSMethodParams* SPSMethodParams ) 2969 { 2970 WLAN_OS_REPORT(("Early termination condition: %s, frame number for early termination: %d\n", 2971 earlyTerminationConditionDesc[ SPSMethodParams->earlyTerminationEvent ], 2972 SPSMethodParams->ETMaxNumberOfApFrames)); 2973 WLAN_OS_REPORT(("Scan duration: %d\n", SPSMethodParams->scanDuration)); 2974 } 2975 2976 /** 2977 * \\n 2978 * \date 31-Mar-2005\n 2979 * \brief print debug information for every received frame.\n 2980 * 2981 * Function Scope \e Private.\n 2982 * \param hScanMngr - handle to the scan manager object.\n 2983 * \param frameInfo - holding all frame related information.\n 2984 */ 2985 void scanMngrDebugPrintReceivedFrame( TI_HANDLE hScanMngr, TScanFrameInfo *frameInfo ) 2986 { 2987 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 2988 2989 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Scan manager received the following frame:\n"); 2990 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "from BSSID: %02x:%02x:%02x:%02x:%02x:%02x, band: %d, channel: %d\n", (*frameInfo->bssId)[ 0 ], (*frameInfo->bssId)[ 1 ], (*frameInfo->bssId)[ 2 ], (*frameInfo->bssId)[ 3 ], (*frameInfo->bssId)[ 4 ], (*frameInfo->bssId)[ 5 ], frameInfo->band, frameInfo->channel); 2991 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "rate: %d, received at TSF (lower 32 bits): %d\n", frameInfo->rate, frameInfo->staTSF); 2992 if ( BEACON == frameInfo->parsedIEs->subType ) 2993 { 2994 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "remote TSF value: %x-%x\n", INT64_HIGHER( frameInfo->parsedIEs->content.iePacket.timestamp ), INT64_LOWER( frameInfo->parsedIEs->content.iePacket.timestamp )); 2995 2996 } 2997 else 2998 { 2999 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "remote TSF value: %x-%x\n", INT64_HIGHER( frameInfo->parsedIEs->content.iePacket.timestamp ), INT64_LOWER( frameInfo->parsedIEs->content.iePacket.timestamp )); 3000 } 3001 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "RSSI: %d\n", frameInfo->rssi); 3002 } 3003 #ifdef TI_DBG 3004 /** 3005 * \\n 3006 * \date 31-Mar-2005\n 3007 * \brief print BSS list.\n 3008 * 3009 * Function Scope \e Private.\n 3010 * \param hScanMngr - handle to the scan manager object.\n 3011 */ 3012 void scanMngrDebugPrintBSSList( TI_HANDLE hScanMngr ) 3013 { 3014 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3015 int i; 3016 3017 if ( 0 == pScanMngr->BSSList.numOfEntries ) 3018 { 3019 WLAN_OS_REPORT(("BSS list is empty.\n")); 3020 return; 3021 } 3022 3023 3024 WLAN_OS_REPORT(("-------------------------------- BSS List--------------------------------\n")); 3025 3026 for ( i = 0; i < pScanMngr->BSSList.numOfEntries; i++ ) 3027 { 3028 WLAN_OS_REPORT( ("Entry number: %d\n", i)); 3029 scanMngrDebugPrintBSSEntry( hScanMngr, i ); 3030 } 3031 3032 WLAN_OS_REPORT(("--------------------------------------------------------------------------\n")); 3033 } 3034 #endif/*TI_DBG*/ 3035 /** 3036 * \\n 3037 * \date 31-Mar-2005\n 3038 * \brief print one entry in the BSS list.\n 3039 * 3040 * Function Scope \e Private.\n 3041 * \param hScanMngr - handle to the scan manager object.\n 3042 * \param entryIndex - the index of the entry to print.\n 3043 */ 3044 void scanMngrDebugPrintBSSEntry( TI_HANDLE hScanMngr, TI_UINT8 entryIndex ) 3045 { 3046 #ifdef REPORT_LOG 3047 3048 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3049 bssEntry_t* pBssEntry = &(pScanMngr->BSSList.BSSList[ entryIndex ]); 3050 scan_BSSEntry_t * pScanBssEntry = &(pScanMngr->BSSList.scanBSSList[ entryIndex ]); 3051 3052 WLAN_OS_REPORT( ("BSSID: %02x:%02x:%02x:%02x:%02x:%02x, band: %d\n", pBssEntry->BSSID[ 0 ], 3053 pBssEntry->BSSID[ 1 ], pBssEntry->BSSID[ 2 ], 3054 pBssEntry->BSSID[ 3 ], pBssEntry->BSSID[ 4 ], 3055 pBssEntry->BSSID[ 5 ], pBssEntry->band)); 3056 WLAN_OS_REPORT( ("channel: %d, beacon interval: %d, average RSSI: %d dBm\n", 3057 pBssEntry->channel, pBssEntry->beaconInterval, pBssEntry->RSSI)); 3058 WLAN_OS_REPORT( ("Neighbor AP: %s, track fail count: %d\n", 3059 (TI_TRUE == pBssEntry->bNeighborAP ? "YES" : "NO"), 3060 pScanBssEntry->trackFailCount)); 3061 WLAN_OS_REPORT( ("local TSF: %d-%d, remote TSF: %x-%x\n", 3062 INT64_HIGHER( pScanBssEntry->localTSF ), INT64_LOWER( pScanBssEntry->localTSF ), 3063 INT64_HIGHER( pBssEntry->lastRxTSF ), INT64_LOWER( pBssEntry->lastRxTSF ))); 3064 WLAN_OS_REPORT( ("Host Time Stamp: %d, last received rate: %d\n", 3065 pBssEntry->lastRxHostTimestamp, pBssEntry->rxRate)); 3066 3067 #endif 3068 } 3069 3070 /** 3071 * \\n 3072 * \date 14-Apr-2005\n 3073 * \brief print SPS helper list 3074 * 3075 * Function Scope \e Private.\n 3076 * \param hScanMngr - handle to the scan manager object.\n 3077 * \param spsHelperList - the list to print.\n 3078 * \param arrayHead - the index of the first element in the list.\n 3079 * \param arraySize - the size of the array.\n 3080 */ 3081 void scanMngrDebugPrintSPSHelperList( TI_HANDLE hScanMngr, scan_SPSHelper_t* spsHelperList, int arrayHead, int arraySize ) 3082 { 3083 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3084 int i; 3085 3086 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "SPS helper list size:%d, list head:%d\n", arraySize, arrayHead); 3087 for ( i = 0; i < arraySize; i++ ) 3088 { 3089 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "track list index:%d, BSSID:%02x:%02x:%02x:%02x:%02x:%02x\n", spsHelperList[ i ].trackListIndex, pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 5 ]); 3090 TRACE3( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "TSF:%x-%x, next entry index:%d\n", INT64_HIGHER(spsHelperList[ i ].nextEventTSF), INT64_LOWER(spsHelperList[ i ].nextEventTSF), spsHelperList[ i ].nextAPIndex); 3091 } 3092 } 3093 3094 3095 /* 3096 *********************************************************************** 3097 * API functions 3098 *********************************************************************** 3099 */ 3100 TI_HANDLE scanMngr_create( TI_HANDLE hOS ) 3101 { 3102 int i,j = 0; 3103 scanMngr_t* pScanMngr ; 3104 3105 /* allocate the scan manager object */ 3106 pScanMngr = os_memoryAlloc( hOS, sizeof(scanMngr_t)); 3107 if ( NULL == pScanMngr ) 3108 { 3109 WLAN_OS_REPORT( ("scanMngr_create: Failed allocating scan manager object storage.\n")); 3110 return NULL; 3111 } 3112 3113 os_memoryZero( pScanMngr->hOS, pScanMngr, sizeof(scanMngr_t)); 3114 3115 pScanMngr->hOS = hOS; 3116 3117 /* allocate frame storage space for BSS list */ 3118 for (i = 0; i < MAX_SIZE_OF_BSS_TRACK_LIST; i++) 3119 { 3120 pScanMngr->BSSList.BSSList[i].pBuffer = os_memoryAlloc (hOS, MAX_BEACON_BODY_LENGTH); 3121 if (pScanMngr->BSSList.BSSList[i].pBuffer == NULL) 3122 { 3123 WLAN_OS_REPORT( ("scanMngr_create: Failed allocating scan result buffer for index %d.\n", i)); 3124 /* failed to allocate a buffer - release all buffers that were allocated by now */ 3125 for (j = i - 1; j >= 0; j--) 3126 { 3127 os_memoryFree (hOS, pScanMngr->BSSList.BSSList[j].pBuffer, MAX_BEACON_BODY_LENGTH); 3128 } 3129 /* release the rest of the module */ 3130 scanMngrFreeMem ((TI_HANDLE)pScanMngr); 3131 return NULL; 3132 } 3133 } 3134 3135 return (TI_HANDLE)pScanMngr; 3136 } 3137 3138 void scanMngr_init (TStadHandlesList *pStadHandles) 3139 { 3140 scanMngr_t *pScanMngr = (scanMngr_t*)(pStadHandles->hScanMngr); 3141 int i; 3142 3143 /* store handles */ 3144 pScanMngr->hReport = pStadHandles->hReport; 3145 pScanMngr->hRegulatoryDomain = pStadHandles->hRegulatoryDomain; 3146 pScanMngr->hScanCncn = pStadHandles->hScanCncn; 3147 pScanMngr->hRoamingMngr = pStadHandles->hRoamingMngr; 3148 pScanMngr->hSiteMngr = pStadHandles->hSiteMgr; 3149 pScanMngr->hTWD = pStadHandles->hTWD; 3150 pScanMngr->hTimer = pStadHandles->hTimer; 3151 pScanMngr->hAPConnection = pStadHandles->hAPConnection; 3152 pScanMngr->hEvHandler = pStadHandles->hEvHandler; 3153 3154 /* mark the scanning operational mode to be automatic by default */ 3155 pScanMngr->scanningOperationalMode = SCANNING_OPERATIONAL_MODE_AUTO; 3156 3157 /* mark that continuous scan timer is not running */ 3158 pScanMngr->bTimerRunning = TI_FALSE; 3159 3160 /* mark that continuous scan process is not running */ 3161 pScanMngr->bContinuousScanStarted = TI_FALSE; 3162 3163 /* nullify scan policy */ 3164 os_memoryZero( pScanMngr->hOS, &(pScanMngr->scanPolicy), sizeof(TScanPolicy)); 3165 3166 /* initialize the BSS list to empty list */ 3167 pScanMngr->BSSList.numOfEntries = 0; 3168 3169 /* mark no continuous and immediate scans are currently running */ 3170 pScanMngr->contScanState = SCAN_CSS_IDLE; 3171 pScanMngr->immedScanState = SCAN_ISS_IDLE; 3172 pScanMngr->bNewBSSFound = TI_FALSE; 3173 pScanMngr->consecNotFound = 0; 3174 3175 /* mark no AP recovery occured */ 3176 pScanMngr->bSynchronized = TI_TRUE; 3177 3178 /* mark no neighbor APs */ 3179 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries = 0; 3180 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries = 0; 3181 3182 /* mark no discovery process */ 3183 pScanMngr->currentDiscoveryPart = SCAN_SDP_NO_DISCOVERY; 3184 3185 /* initialize the low quality indication to indicate that normal quality interval should be used */ 3186 pScanMngr->bLowQuality = TI_FALSE; 3187 3188 /* clear current BSS field (put broadcast MAC) */ 3189 for (i = 0; i < MAC_ADDR_LEN; i++) 3190 { 3191 pScanMngr->currentBSS[i] = 0xff; 3192 } 3193 pScanMngr->currentBSSBand = RADIO_BAND_2_4_GHZ; 3194 3195 /* create timer */ 3196 pScanMngr->hContinuousScanTimer = tmr_CreateTimer (pScanMngr->hTimer); 3197 if (pScanMngr->hContinuousScanTimer == NULL) 3198 { 3199 TRACE0(pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_init(): Failed to create hContinuousScanTimer!\n"); 3200 } 3201 3202 /* register scan concentrator callbacks */ 3203 scanCncn_RegisterScanResultCB( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT, 3204 scanMngr_contScanCB, pStadHandles->hScanMngr ); 3205 scanCncn_RegisterScanResultCB( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED, 3206 scanMngr_immedScanCB, pStadHandles->hScanMngr ); 3207 3208 #ifdef TI_DBG 3209 /* nullify statistics */ 3210 os_memoryZero( pScanMngr->hOS, &(pScanMngr->stats), sizeof(scan_mngrStat_t)); 3211 /* nullify scan parameters - for debug prints before start */ 3212 os_memoryZero( pScanMngr->hOS, &(pScanMngr->scanParams), sizeof(TScanParams)); 3213 /* initialize other variables for debug print */ 3214 pScanMngr->bImmedNeighborAPsOnly = TI_FALSE; 3215 pScanMngr->bNewBSSFound = TI_FALSE; 3216 #endif 3217 } 3218 3219 void scanMngr_unload (TI_HANDLE hScanMngr) 3220 { 3221 scanMngrFreeMem (hScanMngr); 3222 } 3223 3224 scan_mngrResultStatus_e scanMngr_startImmediateScan( TI_HANDLE hScanMngr, TI_BOOL bNeighborAPsOnly ) 3225 { 3226 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3227 TScanBandPolicy *gPolicy, *aPolicy; 3228 EScanCncnResultStatus resultStatus; 3229 3230 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startImmediateScan called, hScanMngr=0x%x, bNeighborAPsOnly=.\n", hScanMngr); 3231 3232 /* sanity check - whether immediate scan is already running */ 3233 if ( SCAN_ISS_IDLE != pScanMngr->immedScanState ) 3234 { 3235 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediate scan attempted while it is already running, in state:%d.\n", pScanMngr->immedScanState); 3236 return SCAN_MRS_SCAN_NOT_ATTEMPTED_ALREADY_RUNNING; 3237 } 3238 3239 /* get policies by band */ 3240 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ ); 3241 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ ); 3242 3243 /* check whether a policy is defined for at least one band */ 3244 if ( ((NULL == gPolicy) || (SCAN_TYPE_NO_SCAN == gPolicy->immediateScanMethod.scanType)) && /* no policy for G band */ 3245 ((NULL == aPolicy) || (SCAN_TYPE_NO_SCAN == aPolicy->immediateScanMethod.scanType))) /* no policy for A band */ 3246 { 3247 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediatse scan attempted when no policy is defined.\n"); 3248 return SCAN_MRS_SCAN_NOT_ATTEMPTED_EMPTY_POLICY; 3249 } 3250 3251 /* First try to scan on G band - if a policy is defined and channels are available */ 3252 if ( (NULL != gPolicy) && /* policy is defined for G */ 3253 (SCAN_TYPE_NO_SCAN != gPolicy->immediateScanMethod.scanType)) 3254 { 3255 /* build scan command */ 3256 scanMngrBuildImmediateScanCommand( hScanMngr, gPolicy, bNeighborAPsOnly ); 3257 3258 /* if no channels are available, proceed to band A */ 3259 if ( 0 < pScanMngr->scanParams.numOfChannels ) 3260 { 3261 /* mark that immediate scan is running on band G */ 3262 pScanMngr->immedScanState = SCAN_ISS_G_BAND; 3263 pScanMngr->bImmedNeighborAPsOnly = bNeighborAPsOnly; 3264 3265 /* if continuous scan is running, mark that it should quit */ 3266 if ( SCAN_CSS_IDLE != pScanMngr->contScanState ) 3267 { 3268 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startImmediateScan called 1, switched to STOPPING state \n"); 3269 3270 pScanMngr->contScanState = SCAN_CSS_STOPPING; 3271 } 3272 3273 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */ 3274 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_IMMED); 3275 3276 if ( SCAN_CRS_SCAN_RUNNING != resultStatus ) 3277 { 3278 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start immediate scan on band G, return code %d.\n", resultStatus); 3279 #ifdef TI_DBG 3280 pScanMngr->stats.ImmediateGByStatus[ resultStatus ]++; 3281 #endif 3282 return SCAN_MRS_SCAN_FAILED; 3283 } 3284 return SCAN_MRS_SCAN_RUNNING; 3285 } 3286 } 3287 3288 /* if G scan did not start (because no policy is configured or no channels are available, try A band */ 3289 if ( (NULL != aPolicy) && 3290 (SCAN_TYPE_NO_SCAN != aPolicy->immediateScanMethod.scanType)) 3291 { 3292 /* build scan command */ 3293 scanMngrBuildImmediateScanCommand( hScanMngr, aPolicy, bNeighborAPsOnly ); 3294 3295 /* if no channels are available, report error */ 3296 if ( 0 == pScanMngr->scanParams.numOfChannels ) 3297 { 3298 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "No channels available for scan operation.\n"); 3299 return SCAN_MRS_SCAN_NOT_ATTEMPTED_NO_CHANNLES_AVAILABLE; 3300 } 3301 else 3302 { 3303 /* mark that immediate scan is running on band A */ 3304 pScanMngr->immedScanState = SCAN_ISS_A_BAND; 3305 3306 /* if continuous scan is running, mark that it should quit */ 3307 if ( SCAN_CSS_IDLE != pScanMngr->contScanState ) 3308 { 3309 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startImmediateScan called 2, switched to STOPPING state \n"); 3310 3311 pScanMngr->contScanState = SCAN_CSS_STOPPING; 3312 } 3313 3314 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */ 3315 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_IMMED); 3316 if ( SCAN_CRS_SCAN_RUNNING != resultStatus ) 3317 { 3318 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start immediate scan on band A, return code %d.\n", resultStatus); 3319 #ifdef TI_DBG 3320 pScanMngr->stats.ImmediateAByStatus[ resultStatus ]++; 3321 #endif 3322 return SCAN_MRS_SCAN_FAILED; 3323 } 3324 return SCAN_MRS_SCAN_RUNNING; 3325 } 3326 } 3327 else 3328 { 3329 /* since we passed the policy check, we arrived here because we didn't had channel on G and policy on A */ 3330 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "No channels available for scan operation.\n"); 3331 return SCAN_MRS_SCAN_NOT_ATTEMPTED_NO_CHANNLES_AVAILABLE; 3332 } 3333 } 3334 3335 void scanMngr_stopImmediateScan( TI_HANDLE hScanMngr ) 3336 { 3337 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3338 3339 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngrStopImmediateScan called, hScanMngr=0x%x", hScanMngr); 3340 3341 /* check that immediate scan is running */ 3342 if ( (SCAN_ISS_A_BAND != pScanMngr->immedScanState) && (SCAN_ISS_G_BAND != pScanMngr->immedScanState)) 3343 { 3344 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediate scan stop request when immediate scan is in state:%d", pScanMngr->immedScanState); 3345 return; 3346 } 3347 3348 #ifdef TI_DBG 3349 switch ( pScanMngr->immedScanState ) 3350 { 3351 case SCAN_ISS_G_BAND: 3352 pScanMngr->stats.ImmediateGByStatus[ SCAN_CRS_SCAN_STOPPED ]++; 3353 break; 3354 3355 case SCAN_ISS_A_BAND: 3356 pScanMngr->stats.ImmediateAByStatus[ SCAN_CRS_SCAN_STOPPED ]++; 3357 break; 3358 3359 default: 3360 break; 3361 } 3362 #endif 3363 /* mark immediate scan status as stopping */ 3364 pScanMngr->immedScanState = SCAN_ISS_STOPPING; 3365 3366 /* send a stop command to scan concentrator */ 3367 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED ); 3368 } 3369 3370 void scanMngr_startContScan( TI_HANDLE hScanMngr, TMacAddr* currentBSS, ERadioBand currentBSSBand ) 3371 { 3372 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3373 int currentBSSNeighborIndex; 3374 3375 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_StartContScan called, hScanMngr=0x%x.\n", hScanMngr); 3376 3377 /* if continuous scan is already running, it means we get a start command w/o stop */ 3378 if ( TI_TRUE == pScanMngr->bContinuousScanStarted ) 3379 { 3380 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Start continuous scan requested when continuous scan is running.\n"); 3381 return; 3382 } 3383 3384 /* mark that continuous scan was started */ 3385 pScanMngr->bContinuousScanStarted = TI_TRUE; 3386 3387 /* before reading and marking the new BSS - make sure that the old one is marked as NOT DISCOVERED */ 3388 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, pScanMngr->currentBSSBand, &(pScanMngr->currentBSS)); 3389 if ( -1 != currentBSSNeighborIndex ) 3390 { 3391 pScanMngr->neighborAPsDiscoveryList[ pScanMngr->currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] = 3392 SCAN_NDS_NOT_DISCOVERED; 3393 } 3394 3395 /* Now copy current BSS - to be used when setting neighbor APs */ 3396 pScanMngr->currentBSSBand = currentBSSBand; 3397 MAC_COPY (pScanMngr->currentBSS, *currentBSS); 3398 3399 /* if current BSS is in the neighbor AP list, mark it as current BSS */ 3400 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, currentBSSBand, currentBSS ); 3401 if ( -1 != currentBSSNeighborIndex ) 3402 { 3403 pScanMngr->neighborAPsDiscoveryList[ currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] = 3404 SCAN_NDS_CURRENT_AP; 3405 } 3406 3407 /* reset discovery cycle */ 3408 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0; 3409 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0; 3410 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0; 3411 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0; 3412 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G; 3413 scanMngrSetNextDiscoveryPart( hScanMngr ); 3414 3415 /* clear the BSS tracking list */ 3416 pScanMngr->BSSList.numOfEntries = 0; 3417 3418 /* start timer (if timeout is configured) */ 3419 if ( ((TI_TRUE == pScanMngr->bLowQuality) && (0 < pScanMngr->scanPolicy.normalScanInterval)) || 3420 ((TI_FALSE == pScanMngr->bLowQuality) && (0 < pScanMngr->scanPolicy.deterioratingScanInterval))) 3421 { 3422 TI_UINT32 uTimeout = pScanMngr->bLowQuality ? 3423 pScanMngr->scanPolicy.deterioratingScanInterval : 3424 pScanMngr->scanPolicy.normalScanInterval; 3425 3426 pScanMngr->bTimerRunning = TI_TRUE; 3427 3428 tmr_StartTimer (pScanMngr->hContinuousScanTimer, 3429 scanMngr_GetUpdatedTsfDtimMibForScan, 3430 (TI_HANDLE)pScanMngr, 3431 uTimeout, 3432 TI_TRUE); 3433 } 3434 } 3435 3436 void scanMngr_stopContScan( TI_HANDLE hScanMngr ) 3437 { 3438 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3439 TI_UINT8 i; 3440 3441 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_stopContScan called, hScanMngr=0x%x, state =%d\n", hScanMngr, pScanMngr->contScanState); 3442 3443 /* if continuous scan is not running, it means we get a stop command w/o start */ 3444 if ( TI_FALSE == pScanMngr->bContinuousScanStarted ) 3445 { 3446 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Stop continuous scan when continuous scan is not running.\n"); 3447 return; 3448 } 3449 3450 /* mark that continuous scan is not running */ 3451 pScanMngr->bContinuousScanStarted = TI_FALSE; 3452 3453 /* stop timer */ 3454 if ( TI_TRUE == pScanMngr->bTimerRunning ) 3455 { 3456 tmr_StopTimer (pScanMngr->hContinuousScanTimer); 3457 pScanMngr->bTimerRunning = TI_FALSE; 3458 } 3459 3460 /* if continuous scan is currently running */ 3461 if ( (SCAN_CSS_IDLE != pScanMngr->contScanState) && 3462 (SCAN_CSS_STOPPING != pScanMngr->contScanState)) 3463 { 3464 /* send a stop scan command to the scan concentartor */ 3465 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT ); 3466 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_stopContScan called, switched to STOPPING state \n"); 3467 3468 #ifdef TI_DBG 3469 switch ( pScanMngr->contScanState ) 3470 { 3471 case SCAN_CSS_TRACKING_G_BAND: 3472 pScanMngr->stats.TrackingGByStatus[ SCAN_CRS_SCAN_STOPPED ]++; 3473 break; 3474 3475 case SCAN_CSS_TRACKING_A_BAND: 3476 pScanMngr->stats.TrackingAByStatus[ SCAN_CRS_SCAN_STOPPED ]++; 3477 break; 3478 3479 case SCAN_CSS_DISCOVERING: 3480 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand ) 3481 { 3482 pScanMngr->stats.DiscoveryGByStatus[ SCAN_CRS_SCAN_STOPPED ]++; 3483 } 3484 else 3485 { 3486 pScanMngr->stats.DiscoveryAByStatus[ SCAN_CRS_SCAN_STOPPED ]++; 3487 } 3488 break; 3489 3490 default: 3491 break; 3492 } 3493 #endif 3494 /* mark that continuous scan is stopping */ 3495 pScanMngr->contScanState = SCAN_CSS_STOPPING; 3496 } 3497 3498 /* clear current neighbor APs */ 3499 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries = 0; 3500 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries = 0; 3501 3502 /* clear current BSS field .This is for the case that scanMngr_setNeighborAPs() is called before scanMngr_startcontScan() */ 3503 for ( i = 0; i < MAC_ADDR_LEN; i++ ) 3504 { 3505 pScanMngr->currentBSS[ i ] = 0xff; 3506 } 3507 3508 } 3509 3510 bssList_t* scanMngr_getBSSList( TI_HANDLE hScanMngr ) 3511 { 3512 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3513 TI_UINT8 BSSIndex; 3514 paramInfo_t param; 3515 3516 3517 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_getBSSList called, hScanMngr=0x%x.\n", hScanMngr); 3518 3519 /* loop on all BSS'es */ 3520 for ( BSSIndex = 0; BSSIndex < pScanMngr->BSSList.numOfEntries; ) 3521 { 3522 /* verify channel validity with the reg domain - for active scan! 3523 (because connection will be attempted on the channel... */ 3524 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 3525 param.content.channelCapabilityReq.band = pScanMngr->BSSList.BSSList[ BSSIndex ].band; 3526 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; 3527 param.content.channelCapabilityReq.channelNum = pScanMngr->BSSList.BSSList[ BSSIndex ].channel; 3528 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m ); 3529 3530 /* if channel is not valid */ 3531 if ( !param.content.channelCapabilityRet.channelValidity ) 3532 { 3533 /* will replace this entry with one further down the array, if any. Therefore, index is not increased 3534 (because a new entry will be placed in the same index). If this is the last entry - the number of 3535 BSSes will be decreased, and thus the loop will exit */ 3536 scanMngrRemoveBSSListEntry( hScanMngr, BSSIndex ); 3537 } 3538 else 3539 { 3540 BSSIndex++; 3541 } 3542 } 3543 3544 /* return the BSS list */ 3545 return (bssList_t*)&(pScanMngr->BSSList); 3546 } 3547 3548 void scanMngr_setNeighborAPs( TI_HANDLE hScanMngr, neighborAPList_t* neighborAPList ) 3549 { 3550 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3551 int neighborAPIndex, currentBSSNeighborIndex; 3552 3553 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setNeighborAPs called, hScanMngr=0x%x.\n", hScanMngr); 3554 #ifdef TI_DBG 3555 scanMngrTracePrintNeighborAPsList( hScanMngr, neighborAPList ); 3556 #endif 3557 /* if continuous scan is running, indicate that it shouldn't proceed to next scan (if any) */ 3558 if ( pScanMngr->contScanState != SCAN_CSS_IDLE ) 3559 { 3560 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setNeighborAPs called, switched to STOPPING state \n"); 3561 3562 pScanMngr->contScanState = SCAN_CSS_STOPPING; 3563 } 3564 3565 /* clear current neighbor APs */ 3566 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries = 0; 3567 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries = 0; 3568 3569 /* copy new neighbor APs, according to band */ 3570 for ( neighborAPIndex = 0; neighborAPIndex < neighborAPList->numOfEntries; neighborAPIndex++ ) 3571 { 3572 /* insert to appropriate list */ 3573 os_memoryCopy( pScanMngr->hOS, 3574 &(pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].APListPtr[ pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries ]), 3575 &(neighborAPList->APListPtr[ neighborAPIndex ]), 3576 sizeof(neighborAP_t)); 3577 3578 /* if AP is in track list, mark as discovered. This is done only if continuous scan 3579 has already started, to ensure the roaming canidate list holds valid information */ 3580 if ( TI_TRUE == pScanMngr->bContinuousScanStarted ) 3581 { 3582 pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].trackStatusList[ pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries ] = 3583 ( -1 == scanMngrGetTrackIndexByBssid( hScanMngr, &(neighborAPList->APListPtr[ neighborAPIndex ].BSSID)) ? 3584 SCAN_NDS_NOT_DISCOVERED : 3585 SCAN_NDS_DISCOVERED ); 3586 } 3587 else 3588 { 3589 /* if continuous scan has not yet started, all AP's are yet to be discovered... */ 3590 pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].trackStatusList[ pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries ] = 3591 SCAN_NDS_NOT_DISCOVERED; 3592 } 3593 3594 /* increase neighbor AP count */ 3595 pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries++; 3596 } 3597 3598 /* remove all tracked APs that are designated as neighbor APs, but are not anymore. Policy has not 3599 changed, so there's no need to check APs that are not neighbor APs and were inserted to the BSS 3600 list because they are on a policy defined channel. */ 3601 scanMngrUpdateBSSList( hScanMngr, TI_TRUE, TI_FALSE ); 3602 3603 /* if current BSS is a neighbor AP, mark it */ 3604 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, 3605 pScanMngr->currentBSSBand, 3606 &(pScanMngr->currentBSS)); 3607 if ( -1 != currentBSSNeighborIndex ) 3608 { 3609 pScanMngr->neighborAPsDiscoveryList[ pScanMngr->currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] = 3610 SCAN_NDS_CURRENT_AP; 3611 } 3612 3613 /* reset discovery counters */ 3614 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0; 3615 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0; 3616 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0; 3617 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0; 3618 /* set current discovery part to first part (G neighbor APs) */ 3619 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G; 3620 /* now advance discovery part */ 3621 scanMngrSetNextDiscoveryPart( hScanMngr ); 3622 } 3623 3624 void scanMngr_qualityChangeTrigger( TI_HANDLE hScanMngr, TI_BOOL bLowQuality ) 3625 { 3626 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3627 3628 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_qualityChangeTrigger called, hScanMngr=0x%x, bLowQuality=.\n", hScanMngr); 3629 3630 /* remember the low quality trigger (in case policy changes, to know which timer interval to use) */ 3631 pScanMngr->bLowQuality = bLowQuality; 3632 3633 /* This function shouldn't be called when continuous scan is not running */ 3634 if ( TI_FALSE == pScanMngr->bContinuousScanStarted ) 3635 { 3636 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Quality change trigger when continuous scan is not running.\n"); 3637 } 3638 3639 /* If the timer is running, stop it and start it again with the new interval */ 3640 if (pScanMngr->bTimerRunning) 3641 { 3642 TI_UINT32 uTimeout = pScanMngr->bLowQuality ? 3643 pScanMngr->scanPolicy.deterioratingScanInterval : 3644 pScanMngr->scanPolicy.normalScanInterval; 3645 3646 tmr_StopTimer (pScanMngr->hContinuousScanTimer); 3647 3648 tmr_StartTimer (pScanMngr->hContinuousScanTimer, 3649 scanMngr_GetUpdatedTsfDtimMibForScan, 3650 (TI_HANDLE)pScanMngr, 3651 uTimeout, 3652 TI_TRUE); 3653 } 3654 } 3655 3656 void scanMngr_handoverDone( TI_HANDLE hScanMngr, TMacAddr* macAddress, ERadioBand band ) 3657 { 3658 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3659 int i, currentBSSNeighborIndex; 3660 3661 /* mark that TSF values are not synchronized */ 3662 pScanMngr->bSynchronized = TI_FALSE; 3663 3664 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_handoverDone called\n"); 3665 3666 /* if previous AP is in neighbor AP list, mark it as not discoverd */ 3667 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, 3668 pScanMngr->currentBSSBand, 3669 &(pScanMngr->currentBSS)); 3670 if ( -1 != currentBSSNeighborIndex ) 3671 { 3672 pScanMngr->neighborAPsDiscoveryList[ pScanMngr->currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] = 3673 SCAN_NDS_NOT_DISCOVERED; 3674 } 3675 3676 /* copy new current AP info */ 3677 pScanMngr->currentBSSBand = band; 3678 MAC_COPY (pScanMngr->currentBSS, *macAddress); 3679 3680 /* if new current AP is a neighbor AP, mark it */ 3681 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, band, macAddress ); 3682 if ( -1 != currentBSSNeighborIndex ) 3683 { 3684 pScanMngr->neighborAPsDiscoveryList[ band ].trackStatusList[ currentBSSNeighborIndex ] = 3685 SCAN_NDS_CURRENT_AP; 3686 /* note - no need to update discovery index - when adding neighbor APs the check (whether discovery should 3687 be attempted) is done for every channel! */ 3688 } 3689 3690 /* if a continuous scan is running, mark that it should stop */ 3691 if ( SCAN_CSS_IDLE != pScanMngr->contScanState ) 3692 { 3693 3694 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_handoverDone called, switched to STOPPING state \n"); 3695 3696 pScanMngr->contScanState = SCAN_CSS_STOPPING; 3697 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT ); 3698 } 3699 3700 /* if the new AP is in the track list */ 3701 i = scanMngrGetTrackIndexByBssid( hScanMngr, macAddress ); 3702 if ( i != -1 ) 3703 { 3704 /* remove it */ 3705 scanMngrRemoveBSSListEntry( hScanMngr, i ); 3706 } 3707 } 3708 3709 TI_STATUS scanMngr_getParam( TI_HANDLE hScanMngr, paramInfo_t *pParam ) 3710 { 3711 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3712 3713 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_getParam called, hScanMngr=0x%x, pParam=0x%x\n", hScanMngr, pParam); 3714 3715 /* act according to parameter type */ 3716 switch ( pParam->paramType ) 3717 { 3718 case SCAN_MNGR_BSS_LIST_GET: 3719 os_memoryCopy(pScanMngr->hOS, pParam->content.pScanBssList, scanMngr_getBSSList( hScanMngr ), sizeof(bssList_t)); 3720 break; 3721 3722 default: 3723 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Scan manager getParam called with param type %d.\n", pParam->paramType); 3724 return PARAM_NOT_SUPPORTED; 3725 /* break; - unreachable */ 3726 } 3727 3728 return TI_OK; 3729 } 3730 3731 3732 3733 3734 3735 3736 TI_STATUS scanMngr_setParam( TI_HANDLE hScanMngr, paramInfo_t *pParam ) 3737 { 3738 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3739 3740 TRACE3( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setParam called, hScanMngr=0x%x, pParam=0x%x, pParam->paramType=%d\n", hScanMngr, pParam, pParam->paramType); 3741 3742 /* act according to parameter type */ 3743 switch ( pParam->paramType ) 3744 { 3745 case SCAN_MNGR_SET_CONFIGURATION: 3746 scanMngr_setScanPolicy( hScanMngr, pParam->content.pScanPolicy); 3747 break; 3748 3749 default: 3750 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Set param, Params is not supported:%d\n", pParam->paramType); 3751 return PARAM_NOT_SUPPORTED; 3752 } 3753 3754 return TI_OK; 3755 } 3756 3757 3758 /** 3759 * \fn scanMngr_SetDefaults 3760 * \brief Set default values to the Scan Manager 3761 * 3762 * \param hScanMngr - handle to the SME object 3763 * \param pInitParams - values read from registry / ini file 3764 * \return None 3765 */ 3766 void scanMngr_SetDefaults (TI_HANDLE hScanMngr, TRoamScanMngrInitParams *pInitParams) 3767 { 3768 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3769 TScanPolicy defaultScanPolicy; 3770 paramInfo_t *pParam; 3771 int i; 3772 3773 WLAN_OS_REPORT(("pInitParams->RoamingScanning_2_4G_enable %d \n",pInitParams->RoamingScanning_2_4G_enable )); 3774 3775 pParam = os_memoryAlloc(pScanMngr->hOS, sizeof(paramInfo_t)); 3776 if (!pParam) 3777 return; 3778 if (pInitParams->RoamingScanning_2_4G_enable) 3779 { 3780 /* Configure default scan policy for 2.4G */ 3781 defaultScanPolicy.normalScanInterval = 10000; 3782 defaultScanPolicy.deterioratingScanInterval = 5000; 3783 defaultScanPolicy.maxTrackFailures = 3; 3784 defaultScanPolicy.BSSListSize = 4; 3785 defaultScanPolicy.BSSNumberToStartDiscovery = 1; 3786 defaultScanPolicy.numOfBands = 1; 3787 3788 defaultScanPolicy.bandScanPolicy[0].band = RADIO_BAND_2_4_GHZ; 3789 defaultScanPolicy.bandScanPolicy[0].rxRSSIThreshold = -80; 3790 defaultScanPolicy.bandScanPolicy[0].numOfChannlesForDiscovery = 3; 3791 defaultScanPolicy.bandScanPolicy[0].numOfChannles = 14; 3792 3793 for ( i = 0; i < 14; i++ ) 3794 { 3795 defaultScanPolicy.bandScanPolicy[0].channelList[ i ] = i + 1; 3796 } 3797 3798 3799 3800 defaultScanPolicy.bandScanPolicy[0].trackingMethod.scanType = SCAN_TYPE_NO_SCAN; 3801 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE; 3802 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0; 3803 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.maxChannelDwellTime = 0; 3804 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.minChannelDwellTime = 0; 3805 3806 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.bitrate = RATE_MASK_UNSPECIFIED; /* Let the FW select */ 3807 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = 0; 3808 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.txPowerDbm = 0; 3809 3810 defaultScanPolicy.bandScanPolicy[0].discoveryMethod.scanType = SCAN_TYPE_NO_SCAN; 3811 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE; 3812 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0; 3813 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.maxChannelDwellTime = 0; 3814 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.minChannelDwellTime = 0; 3815 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.bitrate = RATE_MASK_UNSPECIFIED; /* Let the FW select */ 3816 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = 0; 3817 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.txPowerDbm = 0; 3818 3819 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.scanType = SCAN_TYPE_NORMAL_ACTIVE; 3820 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.maxChannelDwellTime = 30000; 3821 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.minChannelDwellTime = 15000; 3822 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE; 3823 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0; 3824 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = 3; 3825 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.probReqParams.bitrate = 4;//RATE_MASK_UNSPECIFIED; /* Let the FW select */ 3826 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER; 3827 3828 3829 pParam->paramType = SCAN_MNGR_SET_CONFIGURATION; 3830 3831 /* scanMngr_setParam() copy the content and not the pointer */ 3832 pParam->content.pScanPolicy = &defaultScanPolicy; 3833 pParam->paramLength = sizeof(TScanPolicy); 3834 3835 scanMngr_setParam (hScanMngr, pParam); 3836 3837 } 3838 os_memoryFree(pScanMngr->hOS, pParam, sizeof(paramInfo_t)); 3839 /* Configure default scan parameters - SHIRIT END */ 3840 } 3841 /** 3842 * 3843 * scanMngr_startManual API 3844 * 3845 * Description: 3846 * 3847 * save the manual scan params later to be used upon the scan concentrator object 3848 * and change the conn status to connected 3849 * 3850 * ARGS: 3851 * hScanMngr - Scan manager handle \n 3852 * 3853 * RETURNS: 3854 * void 3855 */ 3856 void scanMngr_startManual(TI_HANDLE hScanMngr) 3857 { 3858 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3859 TScanBandPolicy* gPolicy; 3860 3861 pScanMngr->scanningOperationalMode = SCANNING_OPERATIONAL_MODE_MANUAL; 3862 pScanMngr->connStatus = CONNECTION_STATUS_CONNECTED; 3863 3864 scanMngr_setManualScanDefaultParams(hScanMngr); 3865 TRACE0(pScanMngr->hReport,REPORT_SEVERITY_INFORMATION, "scanMngr_startManual() called. \n"); 3866 3867 /* get policies by band */ 3868 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ ); /* TODO: check if neccessary!!!*/ 3869 } 3870 3871 /** 3872 * 3873 * scanMngr_stopManual API 3874 * 3875 * Description: 3876 * 3877 * set the connection status to NOT_CONNECTED 3878 * 3879 * ARGS: 3880 * hScanMngr - Scan manager handle \n 3881 * pTargetAp - the target AP to connect with info. 3882 * 3883 * RETURNS: 3884 * void 3885 */ 3886 void scanMngr_stopManual(TI_HANDLE hScanMngr) 3887 { 3888 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3889 pScanMngr->connStatus = CONNECTION_STATUS_NOT_CONNECTED; 3890 } 3891 3892 /** 3893 * 3894 * scanMngr_setManualScanChannelList API 3895 * 3896 * Description: 3897 * 3898 * save the channel list received form the application. 3899 * 3900 * ARGS: 3901 * hScanMngr - Scan manager handle \n 3902 * pTargetAp - the target AP to connect with info. 3903 * 3904 * RETURNS: 3905 * TI_OK 3906 */ 3907 TI_STATUS scanMngr_setManualScanChannelList (TI_HANDLE hScanMngr, channelList_t* pChannelList) 3908 { 3909 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3910 3911 pScanMngr->manualScanParams.numOfChannels = pChannelList->numOfChannels; 3912 os_memoryCopy(pScanMngr->hOS, 3913 (void*)&pScanMngr->manualScanParams.channelEntry[0], 3914 &pChannelList->channelEntry[0], 3915 pChannelList->numOfChannels * sizeof(TScanChannelEntry)); 3916 3917 return TI_OK; 3918 } 3919 3920 /** 3921 * 3922 * scanMngr_Start1ShotScan API 3923 * 3924 * Description: 3925 * 3926 * send the required scan params to the scan concentartor module 3927 * according to the scanning manual mode. 3928 * 3929 * ARGS: 3930 * hScanMngr - scan manager handle \n 3931 * eClient - the client that requests this scan command. 3932 * 3933 * RETURNS: 3934 * EScanCncnResultStatus - the scan concentrator result 3935 */ 3936 EScanCncnResultStatus scanMngr_Start1ShotScan (TI_HANDLE hScanMngr, EScanCncnClient eClient) 3937 { 3938 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3939 TScanParams* pScanParams; 3940 EScanCncnResultStatus status; 3941 3942 TRACE2(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_Start1ShotScan started... .Operational mode: %d, ScanClient=%d. \n", 3943 pScanMngr->scanningOperationalMode, eClient); 3944 3945 if(SCANNING_OPERATIONAL_MODE_AUTO == pScanMngr->scanningOperationalMode) 3946 { 3947 pScanParams = &(pScanMngr->scanParams); 3948 } 3949 else 3950 { 3951 pScanParams = &(pScanMngr->manualScanParams); /* the scan params that were previously saved in the scanMngr_startManual()*/ 3952 } 3953 3954 status = scanCncn_Start1ShotScan(pScanMngr->hScanCncn, eClient, pScanParams); 3955 return status; 3956 } 3957 3958 /** 3959 * 3960 * scanMngr_immediateScanComplete API 3961 * 3962 * Description: 3963 * 3964 * called upon the immediate scan complete (manual or auto), 3965 and call the roaming manager to handle this callback. 3966 * 3967 * ARGS: 3968 * hScanMngr - Scan manager handle \n 3969 * scanCmpltStatus - the scan complete status 3970 * 3971 * RETURNS: 3972 * EScanCncnResultStatus - the scan concentrator result 3973 */ 3974 TI_STATUS scanMngr_immediateScanComplete(TI_HANDLE hScanMngr, scan_mngrResultStatus_e scanCmpltStatus) 3975 { 3976 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 3977 3978 if(SCANNING_OPERATIONAL_MODE_AUTO == pScanMngr->scanningOperationalMode) 3979 { 3980 roamingMngr_immediateScanComplete(pScanMngr->hRoamingMngr, scanCmpltStatus); 3981 } 3982 else 3983 { 3984 scanMngr_reportImmediateScanResults(hScanMngr, SCAN_MRS_SCAN_COMPLETE_OK); 3985 roamingMngr_immediateScanByAppComplete(pScanMngr->hRoamingMngr, scanCmpltStatus); 3986 } 3987 return TI_OK; 3988 } 3989 3990 3991 /** 3992 * 3993 * scanMngr_reportImmediateScanResults API 3994 * 3995 * Description: 3996 * 3997 * report the immediate scan results to the application 3998 * 3999 * ARGS: 4000 * hScanMngr - Scan manager handle \n 4001 * scanCmpltStatus - the scan complete status 4002 * 4003 * RETURNS: 4004 * EScanCncnResultStatus - the scan concentrator result 4005 */ 4006 TI_STATUS scanMngr_reportImmediateScanResults(TI_HANDLE hScanMngr, scan_mngrResultStatus_e scanCmpltStatus) 4007 { 4008 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 4009 bssList_t *pListOfAPs; 4010 4011 4012 if (scanCmpltStatus == SCAN_MRS_SCAN_COMPLETE_OK) 4013 { 4014 TRACE0(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION ,"scanMngr_reportImmediateScanResults(): reporting scan results to App \n"); 4015 pListOfAPs = scanMngr_getBSSList(hScanMngr); 4016 EvHandlerSendEvent(pScanMngr->hEvHandler, IPC_EVENT_IMMEDIATE_SCAN_REPORT, (TI_UINT8*)pListOfAPs, sizeof(bssList_t)); 4017 } 4018 else 4019 { 4020 TRACE1(pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_reportImmediateScanResults was not completed successfully. status: %d\n", scanCmpltStatus); 4021 return TI_NOK; 4022 } 4023 4024 return TI_OK; 4025 } 4026 4027 4028 /** 4029 * 4030 * scanMngr_startContinuousScanByApp API 4031 * 4032 * Description: 4033 * 4034 * start continuous scan by application 4035 * 4036 * ARGS: 4037 * hScanMngr - Scan manager handle \n 4038 * pChannelList - the channel list to scan 4039 * 4040 * RETURNS: 4041 * TI_OK - if connected, if not returns TI_NOK 4042 */ 4043 TI_STATUS scanMngr_startContinuousScanByApp (TI_HANDLE hScanMngr, channelList_t* pChannelList) 4044 { 4045 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 4046 bssEntry_t *pCurBssEntry; 4047 4048 scanMngr_setManualScanDefaultParams(hScanMngr); 4049 4050 TRACE1(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startContinuousScanByApp().pScanMngr->connStatus = %d \n", pScanMngr->connStatus); 4051 4052 if (CONN_STATUS_CONNECTED == pScanMngr->connStatus) 4053 { 4054 scanMngr_setManualScanChannelList(hScanMngr,pChannelList); 4055 pCurBssEntry = apConn_getBSSParams(pScanMngr->hAPConnection); 4056 scanMngr_startContScan(hScanMngr, &pCurBssEntry->BSSID, pCurBssEntry->band); 4057 } 4058 else 4059 { 4060 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_startContinuousScanByApp failed. connection status %d\n", pScanMngr->connStatus); 4061 return TI_NOK; 4062 } 4063 4064 return TI_OK; 4065 } 4066 4067 /** 4068 * 4069 * scanMngr_stopContinuousScanByApp API 4070 * 4071 * Description: 4072 * 4073 * stop the continuous scan already started by and reoprt to application 4074 * 4075 * ARGS: 4076 * hScanMngr - Scan manager handle \n 4077 * 4078 * RETURNS: 4079 * TI_OK - always 4080 */ 4081 TI_STATUS scanMngr_stopContinuousScanByApp (TI_HANDLE hScanMngr) 4082 { 4083 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 4084 4085 TRACE0(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_stopContinuousScanByApp(). call scanMngr_stopContScan() \n"); 4086 scanMngr_stopContScan(hScanMngr); 4087 scanMngr_reportContinuousScanResults(hScanMngr,SCAN_CRS_SCAN_COMPLETE_OK); 4088 return TI_OK; 4089 } 4090 4091 4092 4093 4094 4095 #ifdef TI_DBG 4096 /** 4097 * \\n 4098 * \date 26-May-2005\n 4099 * \brief Print scan manager statistics.\n 4100 * 4101 * Function Scope \e Public.\n 4102 * \param hScanMngr - handle to the scan manager object.\n 4103 */ 4104 void scanMngr_statsPrint( TI_HANDLE hScanMngr ) 4105 { 4106 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 4107 4108 WLAN_OS_REPORT(("-------------- Scan Manager Statistics ---------------\n")); 4109 WLAN_OS_REPORT(("Discovery scans on G result histogram:\n")); 4110 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.DiscoveryGByStatus ); 4111 WLAN_OS_REPORT(("\nDiscovery scans on A result histogram:\n")); 4112 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.DiscoveryAByStatus ); 4113 WLAN_OS_REPORT(("\nTracking scans on G result histogram:\n")); 4114 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.TrackingGByStatus ); 4115 WLAN_OS_REPORT(("\nTracking scans on A result histogram:\n")); 4116 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.TrackingAByStatus ); 4117 WLAN_OS_REPORT(("\nImmediate scans on G result histogram:\n")); 4118 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.ImmediateGByStatus ); 4119 WLAN_OS_REPORT(("\nImmediate scans on A result histogram:\n")); 4120 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.ImmediateAByStatus ); 4121 WLAN_OS_REPORT(("\nTrack fail count histogram:\n")); 4122 scanMngrStatsPrintTrackFailHistogrsm( pScanMngr->stats.ConsecutiveTrackFailCountHistogram ); 4123 WLAN_OS_REPORT(("Frames received:%d, frames discarded low RSSI:%d, frames discarded other:%d\n", 4124 pScanMngr->stats.receivedFrames, pScanMngr->stats.discardedFramesLowRSSI, 4125 pScanMngr->stats.discardedFramesOther)); 4126 WLAN_OS_REPORT(("\nSPS channels not attened histogram:\n")); 4127 scanMngrStatsPrintSPSChannelsHistogram( pScanMngr->stats.SPSChannelsNotAttended ); 4128 WLAN_OS_REPORT(("\nSPS attempts changed due to DTIM collision:%d, APs removed due to DTIM overlap: %d\n", 4129 pScanMngr->stats.SPSSavedByDTIMCheck, pScanMngr->stats.APsRemovedDTIMOverlap)); 4130 WLAN_OS_REPORT(("APs removed due to invalid channel: %d\n", pScanMngr->stats.APsRemovedInvalidChannel)); 4131 } 4132 4133 /** 4134 * \\n 4135 * \date 26-May-2005\n 4136 * \brief Print scan result histogram statistics.\n 4137 * 4138 * Function Scope \e Private.\n 4139 * \param scanResultHistogram - Scan results histogram (by scan complete reason).\n 4140 */ 4141 void scanMngrStatsPrintScanResultHistogram( TI_UINT32 scanResultHistogram[] ) 4142 { 4143 WLAN_OS_REPORT(("Complete TI_OK failed stopped TSF error FW reset aborted\n")); 4144 WLAN_OS_REPORT(("%-6d %-5d %-5d %-5d %-5d %-5d\n", 4145 scanResultHistogram[ SCAN_CRS_SCAN_COMPLETE_OK ], 4146 scanResultHistogram[ SCAN_CRS_SCAN_FAILED ], 4147 scanResultHistogram[ SCAN_CRS_SCAN_STOPPED ], 4148 scanResultHistogram[ SCAN_CRS_TSF_ERROR ], 4149 scanResultHistogram[ SCAN_CRS_SCAN_ABORTED_FW_RESET ], 4150 scanResultHistogram[ SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY ])); 4151 } 4152 4153 /** 4154 * \\n 4155 * \date 26-May-2005\n 4156 * \brief Print track fail count histogram statistics.\n 4157 * 4158 * Function Scope \e Private.\n 4159 * \param trackFailHistogram - tracking failure histogram (by tracking retry).\n 4160 */ 4161 void scanMngrStatsPrintTrackFailHistogrsm( TI_UINT32 trackFailHistogram[] ) 4162 { 4163 WLAN_OS_REPORT(("Attempts: 0 1 2 3 4\n")); 4164 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d %-6d\n\n", 4165 trackFailHistogram[0], trackFailHistogram[1],trackFailHistogram[2], 4166 trackFailHistogram[3], trackFailHistogram[4])); 4167 WLAN_OS_REPORT(("Attempts: 5 6 7 8 9 or more\n")); 4168 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d %-6d\n\n", 4169 trackFailHistogram[5], trackFailHistogram[6],trackFailHistogram[7], 4170 trackFailHistogram[8],trackFailHistogram[9])); 4171 } 4172 4173 /** 4174 * \\n 4175 * \date 24-July-2005\n 4176 * \brief Print SPS attendant channel histogram statistics.\n 4177 * 4178 * Function Scope \e Private.\n 4179 * \param SPSChannelsNotAttendedHistogram - SPS channels attendant histogram.\n 4180 */ 4181 void scanMngrStatsPrintSPSChannelsHistogram( TI_UINT32 SPSChannelsNotAttendedHistogram[] ) 4182 { 4183 WLAN_OS_REPORT(("Channel index: 0 1 2 3\n")); 4184 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n", 4185 SPSChannelsNotAttendedHistogram[ 0 ], SPSChannelsNotAttendedHistogram[ 1 ], 4186 SPSChannelsNotAttendedHistogram[ 2 ], SPSChannelsNotAttendedHistogram[ 3 ])); 4187 WLAN_OS_REPORT(("Channel index: 4 5 6 7\n")); 4188 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n", 4189 SPSChannelsNotAttendedHistogram[ 4 ], SPSChannelsNotAttendedHistogram[ 5 ], 4190 SPSChannelsNotAttendedHistogram[ 6 ], SPSChannelsNotAttendedHistogram[ 7 ])); 4191 WLAN_OS_REPORT(("Channel index: 8 9 10 11\n")); 4192 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n", 4193 SPSChannelsNotAttendedHistogram[ 8 ], SPSChannelsNotAttendedHistogram[ 9 ], 4194 SPSChannelsNotAttendedHistogram[ 10 ], SPSChannelsNotAttendedHistogram[ 11 ])); 4195 WLAN_OS_REPORT(("Channel index: 12 13 14 15\n")); 4196 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n", 4197 SPSChannelsNotAttendedHistogram[ 12 ], SPSChannelsNotAttendedHistogram[ 13 ], 4198 SPSChannelsNotAttendedHistogram[ 14 ], SPSChannelsNotAttendedHistogram[ 15 ])); 4199 } 4200 4201 /** 4202 * \\n 4203 * \date 26-May-2005\n 4204 * \brief Reset scan manager statistics.\n 4205 * 4206 * Function Scope \e Public.\n 4207 * \param hScanMngr - handle to the scan manager object.\n 4208 */ 4209 void scanMngr_statsReset( TI_HANDLE hScanMngr ) 4210 { 4211 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 4212 4213 os_memoryZero( pScanMngr->hOS, &(pScanMngr->stats), sizeof(scan_mngrStat_t)); 4214 } 4215 4216 /** 4217 * \\n 4218 * \date 25-July-2005\n 4219 * \brief Print Neighbor AP list.\n 4220 * 4221 * Function Scope \e Public.\n 4222 * \param hScanMngr - Handle to the scan manager object.\n 4223 */ 4224 void scanMngrDebugPrintNeighborAPList( TI_HANDLE hScanMngr ) 4225 { 4226 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 4227 int i,j; 4228 4229 WLAN_OS_REPORT(("-------------- Scan Manager Neighbor APs List ---------------\n")); 4230 for ( i = 0; i < RADIO_BAND_NUM_OF_BANDS; i++ ) 4231 { 4232 WLAN_OS_REPORT(("Neighbor AP list for band:%d\n", i)); 4233 if ( 0 == pScanMngr->neighborAPsDiscoveryList[ i ].numOfEntries ) 4234 { 4235 WLAN_OS_REPORT(("Neighbor AP list is empty.\n")); 4236 continue; /* to next band */ 4237 } 4238 WLAN_OS_REPORT(("%-17s %-4s %-7s %-30s\n", "BSSID", "Band", "Channel", "Discovery state")); 4239 WLAN_OS_REPORT(("------------------------------------------------------\n")); 4240 for ( j = 0; j < pScanMngr->neighborAPsDiscoveryList[ i ].numOfEntries; i++ ) 4241 { 4242 scanMngrDebugPrintNeighborAP( &(pScanMngr->neighborAPsDiscoveryList[ i ].APListPtr[ j ]), 4243 pScanMngr->neighborAPsDiscoveryList[ i ].trackStatusList[ j ] ); 4244 } 4245 } 4246 } 4247 4248 /** 4249 * \\n 4250 * \date 25-July-2005\n 4251 * \brief Print One neighbor AP entry.\n 4252 * 4253 * Function Scope \e Private.\n 4254 * \param pNeighborAp - pointer to the neighbor AP data.\n 4255 * \param discovery state - the discovery state of this neighbor AP.\n 4256 */ 4257 void scanMngrDebugPrintNeighborAP( neighborAP_t* pNeighborAp, scan_neighborDiscoveryState_e discoveryState ) 4258 { 4259 WLAN_OS_REPORT(("%02x:%02x:%02x:%02x:%02x:%02x %-4d %-7d %-30s\n", 4260 pNeighborAp->BSSID[ 0 ], pNeighborAp->BSSID[ 1 ], pNeighborAp->BSSID[ 2 ], 4261 pNeighborAp->BSSID[ 3 ], pNeighborAp->BSSID[ 4 ], pNeighborAp->BSSID[ 5 ], 4262 pNeighborAp->band, pNeighborAp->channel, neighborDiscovreyStateDesc[ discoveryState ])); 4263 } 4264 4265 /** 4266 * \\n 4267 * \date 27-July-2005\n 4268 * \brief Prints a scan command.\n 4269 * 4270 * Function Scope \e Private.\n 4271 * \param pScanParams - a pointer to the scan parameters structure.\n 4272 */ 4273 void scanMngrDebugPrintScanCommand( TScanParams* pScanParams ) 4274 { 4275 int i; 4276 4277 if ( 0 == pScanParams->numOfChannels ) 4278 { 4279 WLAN_OS_REPORT(("Invalid scan command.\n")); 4280 return; 4281 } 4282 4283 WLAN_OS_REPORT(("Scan type: %s, band: %d\n", scanTypeDesc[ pScanParams->scanType ], pScanParams->band)); 4284 4285 switch (pScanParams->scanType) 4286 { 4287 case SCAN_TYPE_NORMAL_ACTIVE: 4288 WLAN_OS_REPORT(("Probe request number:%d, rate:%x, TX level:%d\n", 4289 pScanParams->probeReqNumber, pScanParams->probeRequestRate)); 4290 /* break is missing on purpose!!! */ 4291 4292 case SCAN_TYPE_NORMAL_PASSIVE: 4293 WLAN_OS_REPORT(("SSID: %s\n", pScanParams->desiredSsid)); 4294 WLAN_OS_REPORT(("%-4s %-17s %-17s %-20s %-8s %-14s %-14s\n", "Chnl", "BSSID", "Early ter. event", 4295 "Early ter. frame num", "TX level", "Max dwell time", "Min dwell time")); 4296 WLAN_OS_REPORT(("------------------------------------------------------------------------------------------------------\n")); 4297 for ( i = 0; i < pScanParams->numOfChannels; i++ ) 4298 { 4299 scanMngrDebugPrintNormalChannelParam( &(pScanParams->channelEntry[ i ].normalChannelEntry)); 4300 } 4301 break; 4302 4303 case SCAN_TYPE_TRIGGERED_ACTIVE: 4304 WLAN_OS_REPORT(("Probe request number:%d, rate:%x, TX level:%d\n", 4305 pScanParams->probeReqNumber, pScanParams->probeRequestRate )); 4306 /* break is missing on purpose!!! */ 4307 4308 case SCAN_TYPE_TRIGGERED_PASSIVE: 4309 WLAN_OS_REPORT(("SSID: %s, Tid: %d\n", pScanParams->desiredSsid, pScanParams->Tid)); 4310 WLAN_OS_REPORT(("%-4s %-17s %-17s %-20s %-8s %-14s %-14s\n", "Chnl", "BSSID", "Early ter. event", 4311 "Early ter. frame num", "TX level", "Max dwell time", " Min dwell time")); 4312 WLAN_OS_REPORT(("------------------------------------------------------------------------------------------------------\n")); 4313 for ( i = 0; i < pScanParams->numOfChannels; i++ ) 4314 { 4315 scanMngrDebugPrintNormalChannelParam( &(pScanParams->channelEntry[ i ].normalChannelEntry)); 4316 } 4317 break; 4318 4319 case SCAN_TYPE_SPS: 4320 WLAN_OS_REPORT(("Total scan duration (for scan timer): %d, latest TSF value: %x-%x\n", 4321 pScanParams->SPSScanDuration, 4322 INT64_HIGHER(pScanParams->latestTSFValue), INT64_LOWER(pScanParams->latestTSFValue))); 4323 WLAN_OS_REPORT(("%-4s %-17s %-17s %-7s %-16s %-20s\n", "Chnl", "BSSID", "Start time (TSF)", "Duration", 4324 "Early ter. event", "Early ter. frame num")); 4325 WLAN_OS_REPORT(("---------------------------------------------------------------------------------------\n")); 4326 for ( i = 0; i < pScanParams->numOfChannels; i++ ) 4327 { 4328 scanMngrDebugPrintSPSChannelParam( &(pScanParams->channelEntry[ i ].SPSChannelEntry)); 4329 } 4330 break; 4331 4332 case SCAN_TYPE_NO_SCAN: 4333 default: 4334 WLAN_OS_REPORT(("Invalid scan type: %d\n", pScanParams->scanType)); 4335 break; 4336 } 4337 4338 } 4339 4340 /** 4341 * \\n 4342 * \date 27-July-2005\n 4343 * \brief Prints scan command single normal channel.\n 4344 * 4345 * Function Scope \e Private.\n 4346 * \param pNormalChannel - a pointer to the normal channel to print.\n 4347 */ 4348 void scanMngrDebugPrintNormalChannelParam( TScanNormalChannelEntry* pNormalChannel ) 4349 { 4350 WLAN_OS_REPORT(("%-4d %02x:%02x:%02x:%02x:%02x:%02x %-17s %-20d %-8d %-14d %-14d\n", pNormalChannel->channel, 4351 pNormalChannel->bssId[ 0 ], pNormalChannel->bssId[ 1 ], pNormalChannel->bssId[ 2 ], 4352 pNormalChannel->bssId[ 3 ], pNormalChannel->bssId[ 4 ], pNormalChannel->bssId[ 5 ], 4353 earlyTerminationDesc[ pNormalChannel->earlyTerminationEvent >> 8 ], 4354 pNormalChannel->ETMaxNumOfAPframes, pNormalChannel->txPowerDbm, 4355 pNormalChannel->minChannelDwellTime, pNormalChannel->maxChannelDwellTime)); 4356 } 4357 4358 /** 4359 * \\n 4360 * \date 27-July-2005\n 4361 * \brief Prints scan command single SPS channel.\n 4362 * 4363 * Function Scope \e Private.\n 4364 * \param pSPSChannel - a pointer to the SPS channel to print.\n 4365 */ 4366 void scanMngrDebugPrintSPSChannelParam( TScanSpsChannelEntry* pSPSChannel ) 4367 { 4368 WLAN_OS_REPORT(("%-4d %02x:%02x:%02x:%02x:%02x:%02x %8x-%8x %-7d %-16s %-3d\n", 4369 pSPSChannel->channel, pSPSChannel->bssId[ 0 ], pSPSChannel->bssId[ 1 ], 4370 pSPSChannel->bssId[ 2 ], pSPSChannel->bssId[ 3 ], pSPSChannel->bssId[ 4 ], 4371 pSPSChannel->bssId[ 5 ], INT64_HIGHER(pSPSChannel->scanStartTime), 4372 INT64_LOWER(pSPSChannel->scanStartTime), pSPSChannel->scanDuration, 4373 earlyTerminationDesc[ pSPSChannel->earlyTerminationEvent >> 8 ], pSPSChannel->ETMaxNumOfAPframes)); 4374 } 4375 4376 /** 4377 * \\n 4378 * \date 25-July-2005\n 4379 * \brief Prints all data in the scan manager object.\n 4380 * 4381 * Function Scope \e Public.\n 4382 * \param hScanMngr - handle to the scan manager object.\n 4383 */ 4384 void scanMngrDebugPrintObject( TI_HANDLE hScanMngr ) 4385 { 4386 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr; 4387 4388 WLAN_OS_REPORT(("-------------- Scan Manager Object Dump ---------------\n")); 4389 WLAN_OS_REPORT(("Continuous scan timer running: %s, Continuous scan started:%s\n", 4390 booleanDesc[ pScanMngr->bTimerRunning ], booleanDesc[ pScanMngr->bContinuousScanStarted ])); 4391 WLAN_OS_REPORT(("Current BSS in low quality: %s, AP TSF synchronized: %s\n", 4392 booleanDesc[ pScanMngr->bLowQuality ], booleanDesc[ pScanMngr->bSynchronized ])); 4393 WLAN_OS_REPORT(("Continuous scan state: %s, Immediate scan state: %s\n", 4394 contScanStatesDesc[ pScanMngr->contScanState ], immedScanStatesDesc[ pScanMngr->immedScanState ])); 4395 WLAN_OS_REPORT(("Discovery part: %s, G channels discovery Index: %d, A channels discovery index: %d\n", 4396 discoveryPartDesc[ pScanMngr->currentDiscoveryPart ], 4397 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ], 4398 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ])); 4399 WLAN_OS_REPORT(("G neighbor APs discovery index: %d, A neighbor APs discovery index: %d\n", 4400 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ], 4401 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ])); 4402 WLAN_OS_REPORT(("Current BSS MAC: %02x:%02x:%02x:%02x:%02x:%02x, Current BSS band: %d\n", 4403 pScanMngr->currentBSS[ 0 ], pScanMngr->currentBSS[ 1 ], pScanMngr->currentBSS[ 2 ], 4404 pScanMngr->currentBSS[ 3 ], pScanMngr->currentBSS[ 4 ], pScanMngr->currentBSS[ 5 ], 4405 pScanMngr->currentBSSBand)); 4406 WLAN_OS_REPORT(("Last beacon DTIM count:%d, TSF:%x-%x\n", 4407 pScanMngr->lastLocalBcnDTIMCount, 4408 INT64_HIGHER(pScanMngr->currentTSF), INT64_LOWER(pScanMngr->currentTSF))); 4409 WLAN_OS_REPORT(("-------------- Scan Manager Policy ---------------\n")); 4410 scanMngrTracePrintScanPolicy( &(pScanMngr->scanPolicy)); 4411 WLAN_OS_REPORT(("-------------- Scan Manager BSS List ---------------\n")); 4412 scanMngrDebugPrintBSSList( hScanMngr ); 4413 scanMngrDebugPrintNeighborAPList( hScanMngr ); 4414 scanMngr_statsPrint( hScanMngr ); 4415 WLAN_OS_REPORT(("New BSS found during last discovery:%s, Number of scan cycles during which no new AP was found: %d\n", 4416 booleanDesc[ pScanMngr->bNewBSSFound ], pScanMngr->consecNotFound)); 4417 WLAN_OS_REPORT(("Scan for neighbor APs only at last immediate scan: %s\n", 4418 booleanDesc[ pScanMngr->bImmedNeighborAPsOnly ])); 4419 WLAN_OS_REPORT(("-------------- Last issued scan command ---------------\n")); 4420 scanMngrDebugPrintScanCommand( &(pScanMngr->scanParams)); 4421 WLAN_OS_REPORT(("-------------- Handles ---------------\n")); 4422 WLAN_OS_REPORT(("Continuous scan timer: %x, OS:% x, Reg. domain: %x\n", 4423 pScanMngr->hContinuousScanTimer, pScanMngr->hOS, pScanMngr->hRegulatoryDomain)); 4424 WLAN_OS_REPORT(("Report: %x, Roaming manager: %x, Scan concentrator: %x\n", 4425 pScanMngr->hReport, pScanMngr->hRoamingMngr, pScanMngr->hScanCncn)); 4426 } 4427 4428 #endif /* TI_DBG */ 4429