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