1 /* 2 * currBss.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /** \file currBss.c 35 * \brief Current BSS info 36 * 37 * \see currBss.h 38 */ 39 40 /**************************************************************************** 41 * * 42 * MODULE: Current BSS * 43 * PURPOSE: * 44 * Roaming ability of eSTA is implemented by Roaming Manager Component and 45 * described in "Roaming Manager module LLD" document, and by 46 * AP Connection module. AP Connection module implemented as two sub-modules. 47 * The major one is AP Connection, that is responsible for: 48 * - providing Roaming Manager with access to other parts of WLAN Driver, 49 * - implementing low levels of roaming mechanism. 50 * Current BSS sub-module takes care of: 51 * - maintaining database of current AP info, 52 * - providing access to database of current AP info. 53 * The Current BSS represents the BSS we are currently connected to. 54 * Among other parameters, it holds the capabilities of the current AP, 55 * its ID and its quality. 56 * When FW indicates 'Out of Sync' event, Current BSS module is responsible 57 * for awaking the device, sending unicast Probe request, waiting for 58 * response and - in case FW comes to the conclusion that there was 59 * no response - for triggering "Beacon missed" to AP Connection module. 60 * In eSTA5.0 FW updates and checks the quality of the connection with 61 * current AP. Current BSS module is responsible to handle event of type 62 * 'Low RSSI' from FW. Third type of roaming event reported by FW is 63 * 'Consecutive no ack on TX", and it is handled as well by Current 64 * BSS module.Upon reception of any roaming event from FW, Current BSS 65 * module is transferring this event to the AP Connection module in case 66 * of BSS connection, or to SME module in case of IBSS connection. 67 * When WLAN driver is working in IBSS mode, Current BSS module is holding 68 * the parameters of BSS (channel, band, SSID etc.). 69 * * 70 ****************************************************************************/ 71 72 #define __FILE_ID__ FILE_ID_65 73 #include "currBss.h" 74 #include "currBssApi.h" 75 #include "osApi.h" 76 #include "report.h" 77 #include "802_11Defs.h" 78 #include "DataCtrl_Api.h" 79 #include "qosMngr_API.h" 80 #include "regulatoryDomainApi.h" 81 #include "apConn.h" 82 #include "scanMngrApi.h" 83 #include "MacServices_api.h" 84 #include "smeApi.h" 85 #include "sme.h" 86 #include "TWDriver.h" 87 #include "EvHandler.h" 88 #include "DrvMainModules.h" 89 #include "siteMgrApi.h" 90 #include "roamingMngrTypes.h" 91 92 /* Constants */ 93 #define TRIGGER_LOW_RSSI_PACING 1000 94 #define TRIGGER_LOW_SNR_PACING 1000 95 #define TRIGGER_BG_SCAN_PACING 10 96 #define TRIGGER_BG_SCAN_HYSTERESIS 3 97 static const TI_UINT32 KEEP_ALIVE_NULL_DATA_INDEX = 3; 98 99 /* Enumerations */ 100 101 102 /* Typedefs */ 103 104 typedef TI_UINT8 (*currBSS_beaconRxCallb_t) (TI_HANDLE hModule, TI_UINT64 staTSF, TI_UINT8 dtimCount); 105 106 107 /* Structures */ 108 109 110 /* Internal functions prototypes */ 111 112 static void currBSS_lowRssiThrCrossed(currBSS_t *hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 113 static void currBSS_lowSnrThrCrossed(currBSS_t *hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 114 static void currBSS_BackgroundScanQuality(TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 115 static void currBSS_consecTxErrors(currBSS_t *hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 116 static void currBSS_BssLost (currBSS_t *hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 117 static void currBSS_reportRoamingEvent(currBSS_t *hCurrBSS, apConn_roamingTrigger_e roamingEventType, roamingEventData_u *pRoamingEventData); 118 static void currBSS_updateBSSLoss(currBSS_t *pCurrBSS); 119 120 static TI_STATUS currBss_HandleTriggerEvent(TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength, TI_UINT8 eventID); 121 static triggerDesc_t* currBss_findEmptyUserTrigger(TI_HANDLE hCurrBSS, TI_UINT16 clientID, TI_UINT8* triggerIdx); 122 static void currBSS_RssiSnrTrigger0 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 123 static void currBSS_RssiSnrTrigger1 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 124 static void currBSS_RssiSnrTrigger2 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 125 static void currBSS_RssiSnrTrigger3 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 126 static void currBSS_RssiSnrTrigger4 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 127 static void currBSS_RssiSnrTrigger5 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 128 static void currBSS_RssiSnrTrigger6 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 129 static void currBSS_RssiSnrTrigger7 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength); 130 131 /* Public functions implementation */ 132 133 134 135 /** 136 * 137 * currBSS_create 138 * 139 * \b Description: 140 * 141 * Create the Current BSS context: allocate memory for internal variables 142 * 143 * \b ARGS: 144 * 145 * I - hOS - the handle to the OS object 146 * 147 * \b RETURNS: 148 * 149 * TI_OK on success, TI_NOK on failure. 150 * 151 * \sa 152 */ 153 TI_HANDLE currBSS_create(TI_HANDLE hOs) 154 { 155 currBSS_t *pCurrBss; 156 157 if ((pCurrBss = os_memoryAlloc(hOs, sizeof(currBSS_t))) != NULL) 158 { 159 pCurrBss->hOs = hOs; 160 161 return pCurrBss; 162 } 163 else /* Failed to allocate control block */ 164 { 165 WLAN_OS_REPORT(("FATAL ERROR: currBSS_create(): Error allocating cb - aborting\n")); 166 return NULL; 167 } 168 } 169 170 171 /** 172 * 173 * currBSS_unload 174 * 175 * \b Description: 176 * 177 * Finish Current BSS module work. 178 * 179 * \b ARGS: 180 * 181 * 182 * \b RETURNS: 183 * 184 * TI_OK on success, TI_NOK on failure. 185 * 186 * \sa 187 */ 188 TI_STATUS currBSS_unload(TI_HANDLE hCurrBSS) 189 { 190 currBSS_t *pCurrBSS; 191 192 if (hCurrBSS != NULL) 193 { 194 pCurrBSS = (currBSS_t *)hCurrBSS; 195 196 /* Free pre-allocated control block */ 197 os_memoryFree(pCurrBSS->hOs, pCurrBSS, sizeof(currBSS_t)); 198 } 199 return TI_OK; 200 } 201 202 203 /** 204 * 205 * currBSS_init 206 * 207 * \b Description: 208 * 209 * Get other modules handles. 210 * 211 * \b ARGS: 212 * 213 * I pStadHandles - The driver modules handles 214 * 215 * \b RETURNS: 216 * 217 * void 218 * 219 * \sa 220 */ 221 void currBSS_init (TStadHandlesList *pStadHandles) 222 { 223 currBSS_t *pCurrBSS = (currBSS_t *)(pStadHandles->hCurrBss); 224 int i=0; 225 226 pCurrBSS->hAPConn = pStadHandles->hAPConnection; 227 pCurrBSS->hTWD = pStadHandles->hTWD; 228 pCurrBSS->hMlme = pStadHandles->hMlmeSm; 229 pCurrBSS->hPowerMngr = pStadHandles->hPowerMgr; 230 pCurrBSS->hSme = pStadHandles->hSme; 231 pCurrBSS->hSiteMgr = pStadHandles->hSiteMgr; 232 pCurrBSS->hReport = pStadHandles->hReport; 233 pCurrBSS->hScanMngr = pStadHandles->hScanMngr; 234 pCurrBSS->hEvHandler = pStadHandles->hEvHandler; 235 pCurrBSS->hTxCtrl = pStadHandles->hTxCtrl; 236 237 for (i=0; i< MAX_NUM_OF_RSSI_SNR_TRIGGERS ; i++) 238 { 239 pCurrBSS->aTriggersDesc[i].clientID = 0; 240 pCurrBSS->aTriggersDesc[i].fCB = NULL; 241 pCurrBSS->aTriggersDesc[i].hCB = NULL; 242 pCurrBSS->aTriggersDesc[i].WasRegisteredByApp = TI_FALSE; 243 244 } 245 } 246 247 248 /** 249 * 250 * currBSS_SetDefaults 251 * 252 * \b Description: 253 * 254 * Prepare Current BSS module to work 255 * 256 * \b ARGS: 257 * 258 * I - hCurrBSS - Current BSS handle \n 259 * 260 * \b RETURNS: 261 * 262 * TI_OK on success, TI_NOK on failure. 263 * 264 * \sa 265 */ 266 TI_STATUS currBSS_SetDefaults (TI_HANDLE hCurrBSS, TCurrBssInitParams *pInitParams) 267 { 268 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 269 TRroamingTriggerParams params; 270 RssiSnrTriggerCfg_t tTriggerCfg; 271 272 /* save the roaming operational mode */ 273 pCurrBSS->RoamingOperationalMode = pInitParams->RoamingOperationalMode; 274 275 /* Registration succeeded, continue with init procedure */ 276 pCurrBSS->band = RADIO_BAND_2_4_GHZ; 277 pCurrBSS->channel = 0; 278 pCurrBSS->isConnected = TI_FALSE; 279 pCurrBSS->type = BSS_ANY; 280 pCurrBSS->currAPInfo.RSSI = 0; 281 pCurrBSS->bUseSGParams = TI_FALSE; 282 pCurrBSS->uDefaultKeepAlivePeriod = pInitParams->uNullDataKeepAlivePeriod; 283 284 285 /* register the static callbacks */ 286 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_0,(void*) currBSS_RssiSnrTrigger0, pCurrBSS); 287 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_1,(void*) currBSS_RssiSnrTrigger1, pCurrBSS); 288 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_2,(void*) currBSS_RssiSnrTrigger2, pCurrBSS); 289 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_3,(void*) currBSS_RssiSnrTrigger3, pCurrBSS); 290 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_4,(void*) currBSS_RssiSnrTrigger4, pCurrBSS); 291 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_5,(void*) currBSS_RssiSnrTrigger5, pCurrBSS); 292 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_6,(void*) currBSS_RssiSnrTrigger6, pCurrBSS); 293 TWD_RegisterEvent(pCurrBSS->hTWD,TWD_OWN_EVENT_RSSI_SNR_TRIGGER_7,(void*) currBSS_RssiSnrTrigger7, pCurrBSS); 294 295 if (ROAMING_OPERATIONAL_MODE_AUTO == pCurrBSS->RoamingOperationalMode) 296 { 297 /* Configure and enable the Low RSSI, the Low SNR and the Missed beacon events */ 298 currBSS_RegisterTriggerEvent(hCurrBSS, TWD_OWN_EVENT_RSSI_SNR_TRIGGER_0, 0, (void*)currBSS_lowRssiThrCrossed, hCurrBSS); 299 currBSS_RegisterTriggerEvent(hCurrBSS, TWD_OWN_EVENT_RSSI_SNR_TRIGGER_1, 0, (void*)currBSS_lowSnrThrCrossed, hCurrBSS); 300 currBSS_RegisterTriggerEvent(hCurrBSS, TWD_OWN_EVENT_RSSI_SNR_TRIGGER_4, 0, (void*)currBSS_BackgroundScanQuality, hCurrBSS); 301 302 pCurrBSS->lowRssiThreshold = RSSI_DEFAULT_THRESHOLD; 303 tTriggerCfg.index = TRIGGER_EVENT_LOW_RSSI; 304 tTriggerCfg.threshold = pCurrBSS->lowRssiThreshold; 305 tTriggerCfg.pacing = TRIGGER_LOW_RSSI_PACING; 306 tTriggerCfg.metric = METRIC_EVENT_RSSI_BEACON; 307 tTriggerCfg.type = RX_QUALITY_EVENT_LEVEL; 308 tTriggerCfg.direction = RSSI_EVENT_DIR_LOW; 309 tTriggerCfg.hystersis = 0; 310 tTriggerCfg.enable = TI_TRUE; 311 TWD_CfgRssiSnrTrigger (pCurrBSS->hTWD, &tTriggerCfg); 312 313 pCurrBSS->lowSnrThreshold = SNR_DEFAULT_THRESHOLD; 314 tTriggerCfg.index = TRIGGER_EVENT_LOW_SNR; 315 tTriggerCfg.threshold = pCurrBSS->lowSnrThreshold; 316 tTriggerCfg.pacing = TRIGGER_LOW_SNR_PACING; 317 tTriggerCfg.metric = METRIC_EVENT_SNR_BEACON; 318 tTriggerCfg.type = RX_QUALITY_EVENT_LEVEL; 319 tTriggerCfg.direction = RSSI_EVENT_DIR_LOW; 320 tTriggerCfg.hystersis = 0; 321 tTriggerCfg.enable = TI_TRUE; 322 TWD_CfgRssiSnrTrigger (pCurrBSS->hTWD, &tTriggerCfg); 323 324 pCurrBSS->highQualityForBkgrdScan = RSSI_DEFAULT_THRESHOLD; 325 pCurrBSS->lowQualityForBkgrdScan = RSSI_DEFAULT_THRESHOLD; 326 tTriggerCfg.index = TRIGGER_EVENT_BG_SCAN; 327 tTriggerCfg.threshold = pCurrBSS->lowQualityForBkgrdScan; 328 tTriggerCfg.pacing = TRIGGER_BG_SCAN_PACING; 329 tTriggerCfg.metric = METRIC_EVENT_RSSI_DATA; 330 tTriggerCfg.type = RX_QUALITY_EVENT_EDGE; 331 tTriggerCfg.direction = RSSI_EVENT_DIR_BIDIR; 332 tTriggerCfg.hystersis = TRIGGER_BG_SCAN_HYSTERESIS; 333 tTriggerCfg.enable = TI_TRUE; 334 TWD_CfgRssiSnrTrigger (pCurrBSS->hTWD, &tTriggerCfg); 335 336 /* Register for 'BSS-Loss' event */ 337 TWD_RegisterEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_BSS_LOSE, (void *)currBSS_BssLost, pCurrBSS); 338 TWD_EnableEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_BSS_LOSE); 339 340 /* save last configured value for handling Soft Gemini changes */ 341 pCurrBSS->numExpectedTbttForBSSLoss = OUT_OF_SYNC_DEFAULT_THRESHOLD; 342 params.TsfMissThreshold = OUT_OF_SYNC_DEFAULT_THRESHOLD; 343 params.BssLossTimeout = NO_BEACON_DEFAULT_TIMEOUT; 344 TWD_CfgConnMonitParams (pCurrBSS->hTWD, ¶ms); 345 346 /* Register for 'Consec. Tx error' */ 347 TWD_RegisterEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_MAX_TX_RETRY, (void *)currBSS_consecTxErrors, pCurrBSS); 348 TWD_EnableEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_MAX_TX_RETRY); 349 350 pCurrBSS->maxTxRetryThreshold = NO_ACK_DEFAULT_THRESHOLD; 351 params.maxTxRetry = NO_ACK_DEFAULT_THRESHOLD; 352 TWD_CfgMaxTxRetry (pCurrBSS->hTWD, ¶ms); 353 } 354 355 return TI_OK; 356 } 357 358 359 /** 360 * 361 * currBSS_updateRoamingTriggers 362 * 363 * \b Description: 364 * 365 * Configure parameter of Current BSS 366 * 367 * \b ARGS: 368 * 369 * I - hCurrBSS - Current BSS handle \n 370 * I - params - pointer to datablock of roaming threshols \n 371 * 372 * \b RETURNS: 373 * 374 * TI_OK on success, TI_NOK on failure. 375 * 376 * \sa 377 */ 378 TI_STATUS currBSS_updateRoamingTriggers (TI_HANDLE hCurrBSS, roamingMngrThresholdsConfig_t *params) 379 { 380 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 381 TRroamingTriggerParams roamingTriggersParams; 382 RssiSnrTriggerCfg_t tTriggerCfg; 383 384 if (pCurrBSS->lowRssiThreshold != params->lowRssiThreshold) 385 { 386 pCurrBSS->lowRssiThreshold = params->lowRssiThreshold; 387 388 tTriggerCfg.index = TRIGGER_EVENT_LOW_RSSI; 389 tTriggerCfg.threshold = pCurrBSS->lowRssiThreshold; 390 tTriggerCfg.pacing = TRIGGER_LOW_RSSI_PACING; 391 tTriggerCfg.metric = METRIC_EVENT_RSSI_BEACON; 392 tTriggerCfg.type = RX_QUALITY_EVENT_LEVEL; 393 tTriggerCfg.direction = RSSI_EVENT_DIR_LOW; 394 tTriggerCfg.hystersis = 0; 395 tTriggerCfg.enable = TI_TRUE; 396 397 TWD_CfgRssiSnrTrigger (pCurrBSS->hTWD, &tTriggerCfg); 398 } 399 400 if (pCurrBSS->lowSnrThreshold != params->lowSnrThreshold) 401 { 402 pCurrBSS->lowSnrThreshold = params->lowSnrThreshold; 403 404 tTriggerCfg.index = TRIGGER_EVENT_LOW_SNR; 405 tTriggerCfg.threshold = pCurrBSS->lowSnrThreshold; 406 tTriggerCfg.pacing = TRIGGER_LOW_SNR_PACING; 407 tTriggerCfg.metric = METRIC_EVENT_SNR_BEACON; 408 tTriggerCfg.type = RX_QUALITY_EVENT_LEVEL; 409 tTriggerCfg.direction = RSSI_EVENT_DIR_LOW; 410 tTriggerCfg.hystersis = 0; 411 tTriggerCfg.enable = TI_TRUE; 412 413 TWD_CfgRssiSnrTrigger (pCurrBSS->hTWD, &tTriggerCfg); 414 } 415 416 if (pCurrBSS->lowQualityForBkgrdScan != params->lowQualityForBackgroungScanCondition) 417 { 418 pCurrBSS->lowQualityForBkgrdScan = params->lowQualityForBackgroungScanCondition; 419 tTriggerCfg.index = TRIGGER_EVENT_BG_SCAN; 420 tTriggerCfg.threshold = pCurrBSS->lowQualityForBkgrdScan; 421 tTriggerCfg.pacing = TRIGGER_BG_SCAN_PACING; 422 tTriggerCfg.metric = METRIC_EVENT_RSSI_DATA; 423 tTriggerCfg.type = RX_QUALITY_EVENT_EDGE; 424 tTriggerCfg.direction = RSSI_EVENT_DIR_BIDIR; 425 tTriggerCfg.hystersis = TRIGGER_BG_SCAN_HYSTERESIS; 426 tTriggerCfg.enable = TI_TRUE; 427 428 TWD_CfgRssiSnrTrigger (pCurrBSS->hTWD, &tTriggerCfg); 429 } 430 431 if (pCurrBSS->numExpectedTbttForBSSLoss != params->numExpectedTbttForBSSLoss) 432 { 433 /* save last configured value for handling Soft Gemini changes */ 434 pCurrBSS->numExpectedTbttForBSSLoss = params->numExpectedTbttForBSSLoss; 435 /* Configure TWD with 'No BSS' thresholds (Same as the other parameters but in a special 436 function for the Soft Gemini module consideration) */ 437 currBSS_updateBSSLoss(pCurrBSS); 438 } 439 440 /* Configure TWD with 'Consecutive NACK' thresholds */ 441 if (pCurrBSS->maxTxRetryThreshold != params->dataRetryThreshold) 442 { 443 pCurrBSS->maxTxRetryThreshold = params->dataRetryThreshold; 444 roamingTriggersParams.maxTxRetry = pCurrBSS->maxTxRetryThreshold; 445 TWD_CfgMaxTxRetry (pCurrBSS->hTWD, &roamingTriggersParams); 446 } 447 448 pCurrBSS->highQualityForBkgrdScan = params->normalQualityForBackgroungScanCondition; 449 450 return TI_OK; 451 } 452 453 /** 454 * 455 * currBSS_getRoamingParams 456 * 457 * \b Description: 458 * 459 * Retrieves the roaming triggers stored in the CurrBSS module. 460 * 461 * \b ARGS: 462 * 463 * I - hCurrBSS - Current BSS handle \n 464 * O - aNumExpectedTbttForBSSLoss - Current BSS handle \n 465 * O - aLowQualityForBackgroungScanCondition - Current BSS handle \n 466 * O - aNormalQualityForBackgroungScanCondition - Current BSS handle \n 467 * 468 * \b RETURNS: 469 * 470 * TI_OK on success, TI_NOK on failure. 471 * 472 * \sa 473 */ 474 TI_STATUS currBSS_getRoamingParams(TI_HANDLE hCurrBSS, 475 TI_UINT8 * aNumExpectedTbttForBSSLoss, 476 TI_INT8 * aLowQualityForBackgroungScanCondition, 477 TI_INT8 * aNormalQualityForBackgroungScanCondition) 478 { 479 currBSS_t * pCurrBSS = (currBSS_t *) hCurrBSS; 480 481 *aNumExpectedTbttForBSSLoss = pCurrBSS->numExpectedTbttForBSSLoss; 482 *aLowQualityForBackgroungScanCondition = pCurrBSS->lowQualityForBkgrdScan; 483 *aNormalQualityForBackgroungScanCondition = pCurrBSS->highQualityForBkgrdScan; 484 485 return TI_OK; 486 } 487 488 /** 489 * 490 * currBSS_SGconfigureBSSLoss 491 * 492 * \b Description: 493 * 494 * This function is called by the Soft Gemini module in order to enable/disable the use of 495 * the compensation value for the BSSLoss count , and the percent of increasing that value 496 * It also set the new parameter to the FW (with another generic function) 497 * The compensation is needed since BT activity might over-run recieved beacons 498 * 499 * 500 * \b ARGS: 501 * 502 * I - hCurrBSS - Current BSS handle \n 503 * SGcompensationPercent - percent of increasing the BSSLoss value to the FW \n 504 * bUseSGParams - whether to use the SG compensation 505 * 506 * \b RETURNS: 507 * 508 * - 509 * 510 * \sa 511 */ 512 513 void currBSS_SGconfigureBSSLoss(TI_HANDLE hCurrBSS, 514 TI_UINT32 SGcompensationPercent , TI_BOOL bUseSGParams) 515 { 516 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 517 518 pCurrBSS->bUseSGParams = bUseSGParams; 519 pCurrBSS->SGcompensationPercent = SGcompensationPercent; 520 521 TRACE1(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION, "CurrBSS_SGConf: SG =%d\n", pCurrBSS->bUseSGParams); 522 523 /* update the change of BSSLoss in the FW */ 524 currBSS_updateBSSLoss(pCurrBSS); 525 } 526 527 /** 528 * 529 * currBSS_updateBSSLoss 530 * 531 * \b Description: 532 * 533 * This function updates only BSS Loss parameter , we need it to be able to consider the 534 * Soft Gemini status , and change the parameter according to it 535 * 536 * \b ARGS: 537 * 538 * I - pCurrBSS - Current BSS handle \n 539 * 540 * \b RETURNS: 541 * 542 * - 543 * 544 * \sa 545 */ 546 void currBSS_updateBSSLoss(currBSS_t *pCurrBSS) 547 { 548 TRroamingTriggerParams roamingTriggersParams; 549 550 /* In Ad-Hoc we use default parameter */ 551 if (pCurrBSS->type == BSS_INDEPENDENT) 552 { 553 roamingTriggersParams.TsfMissThreshold = OUT_OF_SYNC_IBSS_THRESHOLD; 554 } 555 else /* In Infra we use the saved parameter */ 556 { 557 roamingTriggersParams.TsfMissThreshold = pCurrBSS->numExpectedTbttForBSSLoss; 558 } 559 560 roamingTriggersParams.BssLossTimeout = NO_BEACON_DEFAULT_TIMEOUT; 561 562 TRACE2(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION, ": SG=%d, Band=%d\n", pCurrBSS->bUseSGParams, pCurrBSS->currAPInfo.band); 563 564 565 /* if Soft Gemini is enabled - increase the BSSLoss value (because BT activity might over-run beacons) */ 566 if ((pCurrBSS->bUseSGParams) && (pCurrBSS->currAPInfo.band == RADIO_BAND_2_4_GHZ)) 567 { 568 roamingTriggersParams.TsfMissThreshold = (roamingTriggersParams.TsfMissThreshold * 569 (100 + pCurrBSS->SGcompensationPercent)) / 100; 570 571 TRACE2(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION, ": old value = %d, new value (for SG compensation) = %d\n", pCurrBSS->numExpectedTbttForBSSLoss,roamingTriggersParams.TsfMissThreshold); 572 } 573 574 TWD_CfgConnMonitParams (pCurrBSS->hTWD, &roamingTriggersParams); 575 } 576 577 /** 578 * 579 * currBSS_swChFinished 580 * 581 * \b Description: 582 * 583 * Called when switch channel process is complete in order to reset RSSI calculations 584 * 585 * \b ARGS: 586 * 587 * I - hCurrBSS - Current BSS handle \n 588 * 589 * \b RETURNS: 590 * 591 * - 592 * 593 * \sa 594 */ 595 void currBSS_restartRssiCounting(TI_HANDLE hCurrBSS) 596 { 597 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 598 599 pCurrBSS->currAPInfo.RSSI = 0; 600 } 601 602 /** 603 * 604 * currBSS_getBssInfo 605 * 606 * \b Description: 607 * 608 * Get parameter of Current BSS 609 * 610 * \b ARGS: 611 * 612 * I - hCurrBSS - Current BSS handle \n 613 * 614 * \b RETURNS: 615 * 616 * pointer to current BSS info block. 617 * 618 * \sa 619 */ 620 bssEntry_t *currBSS_getBssInfo(TI_HANDLE hCurrBSS) 621 { 622 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 623 624 /* Return pointer to current AP info */ 625 return &(pCurrBSS->currAPInfo); 626 } 627 628 629 /** 630 * 631 * currBSS_probRespReceivedCallb 632 * 633 * \b Description: 634 * 635 * Callback function, provided to MLME module. Called each time Probe response received. 636 * This function verifies that the Probe response was sent by current AP, and then 637 * updates current AP database. 638 * 639 * \b ARGS: 640 * 641 * I - hCurrBSS - Current BSS handle \n 642 * 643 * \b RETURNS: 644 * 645 * TI_OK on success, TI_NOK on failure. 646 * 647 * \sa 648 */ 649 TI_STATUS currBSS_probRespReceivedCallb(TI_HANDLE hCurrBSS, 650 TRxAttr *pRxAttr, 651 TMacAddr *bssid, 652 mlmeFrameInfo_t *pFrameInfo, 653 TI_UINT8 *dataBuffer, 654 TI_UINT16 bufLength) 655 { 656 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 657 paramInfo_t *pParam; 658 659 pParam = (paramInfo_t *)os_memoryAlloc(pCurrBSS->hOs, sizeof(paramInfo_t)); 660 if (!pParam) 661 return TI_NOK; 662 663 pParam->paramType = SITE_MGR_CURRENT_BSSID_PARAM; 664 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 665 666 if (pCurrBSS->isConnected && MAC_EQUAL (pParam->content.siteMgrDesiredBSSID, *bssid)) 667 { 668 siteMgr_updateSite(pCurrBSS->hSiteMgr, bssid, pFrameInfo, pRxAttr->channel, (ERadioBand)pRxAttr->band, TI_FALSE); 669 /* Save the IE part of the Probe Response buffer in the site table */ 670 siteMgr_saveProbeRespBuffer(pCurrBSS->hSiteMgr, bssid, (TI_UINT8 *)dataBuffer, bufLength); 671 } 672 os_memoryFree(pCurrBSS->hOs, pParam, sizeof(paramInfo_t)); 673 return TI_OK; 674 } 675 676 677 678 /** 679 * 680 * currBSS_beaconReceivedCallb 681 * 682 * \b Description: 683 * 684 * Callback function, provided to MLME module. Called each time Beacon received. 685 * This function verifies that the Probe response was sent by current AP, and then 686 * updates current AP database. 687 * 688 * \b ARGS: 689 * 690 * I - hCurrBSS - Current BSS handle \n 691 * 692 * \b RETURNS: 693 * 694 * TI_OK on success, TI_NOK on failure. 695 * 696 * \sa 697 */ 698 TI_STATUS currBSS_beaconReceivedCallb(TI_HANDLE hCurrBSS, 699 TRxAttr *pRxAttr, 700 TMacAddr *bssid, 701 mlmeFrameInfo_t *pFrameInfo, 702 TI_UINT8 *dataBuffer, 703 TI_UINT16 bufLength) 704 { 705 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 706 paramInfo_t *pParam; 707 ScanBssType_enum bssType; 708 709 pParam = (paramInfo_t *)os_memoryAlloc(pCurrBSS->hOs, sizeof(paramInfo_t)); 710 if (!pParam) 711 return TI_NOK; 712 713 bssType = ((pFrameInfo->content.iePacket.capabilities >> CAP_ESS_SHIFT) & CAP_ESS_MASK) ? BSS_INFRASTRUCTURE : BSS_INDEPENDENT; 714 pParam->paramType = SITE_MGR_CURRENT_BSSID_PARAM; 715 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 716 717 if (pCurrBSS->isConnected && MAC_EQUAL(pParam->content.siteMgrDesiredBSSID, *bssid)) 718 { 719 siteMgr_updateSite(pCurrBSS->hSiteMgr, bssid, pFrameInfo, pRxAttr->channel, (ERadioBand)pRxAttr->band, TI_FALSE); 720 /* Save the IE part of the beacon buffer in the site table */ 721 siteMgr_saveBeaconBuffer(pCurrBSS->hSiteMgr, bssid, (TI_UINT8 *)dataBuffer, bufLength); 722 } 723 else if(pCurrBSS->isConnected && (bssType==BSS_INDEPENDENT)) 724 { 725 siteMgr_IbssMerge(pCurrBSS->hSiteMgr, pParam->content.siteMgrDesiredBSSID, *bssid, 726 pFrameInfo, pRxAttr->channel, (ERadioBand)pRxAttr->band); 727 siteMgr_saveBeaconBuffer(pCurrBSS->hSiteMgr, bssid, (TI_UINT8 *)dataBuffer, bufLength); 728 } 729 os_memoryFree(pCurrBSS->hOs, pParam, sizeof(paramInfo_t)); 730 return TI_OK; 731 } 732 733 734 /** 735 * 736 * currBSS_updateConnectedState 737 * 738 * \b Description: 739 * 740 * This function is called when FW recovery performed. 741 * 742 * \b ARGS: 743 * 744 * I - hCurrBSS - Current BSS handle \n 745 * I - isConnected - TI_TRUE or TI_FALSE \n 746 * I - type - IBSS or EBSS \n 747 * 748 * \b RETURNS: 749 * 750 * - 751 * 752 * \sa 753 */ 754 void currBSS_updateConnectedState(TI_HANDLE hCurrBSS, TI_BOOL isConnected, ScanBssType_e type) 755 { 756 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 757 758 pCurrBSS->type = type; 759 pCurrBSS->isConnected = isConnected; 760 761 if (isConnected) 762 { 763 /*** Store the info of current AP ***/ 764 paramInfo_t *pParam; 765 766 pParam = (paramInfo_t *)os_memoryAlloc(pCurrBSS->hOs, sizeof(paramInfo_t)); 767 if (!pParam) 768 return; 769 770 /* BSSID */ 771 pParam->paramType = SITE_MGR_CURRENT_BSSID_PARAM; 772 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 773 MAC_COPY (pCurrBSS->currAPInfo.BSSID, pParam->content.siteMgrDesiredBSSID); 774 775 /* Rx rate */ 776 pParam->paramType = SITE_MGR_LAST_RX_RATE_PARAM; 777 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 778 pCurrBSS->currAPInfo.rxRate = pParam->content.ctrlDataCurrentBasicRate; 779 780 /* Band */ 781 pParam->paramType = SITE_MGR_RADIO_BAND_PARAM; 782 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 783 pCurrBSS->currAPInfo.band = pParam->content.siteMgrRadioBand; 784 785 /* Channel */ 786 pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM; 787 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 788 pCurrBSS->currAPInfo.channel = pParam->content.siteMgrCurrentChannel; 789 790 /* Last Rx Tsf */ 791 pParam->paramType = SITE_MGR_CURRENT_TSF_TIME_STAMP; 792 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 793 os_memoryCopy(pCurrBSS->hOs, &pCurrBSS->currAPInfo.lastRxTSF, 794 pParam->content.siteMgrCurrentTsfTimeStamp, sizeof(pCurrBSS->currAPInfo.lastRxTSF)); 795 796 /* Beacon interval */ 797 pParam->paramType = SITE_MGR_BEACON_INTERVAL_PARAM; 798 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 799 pCurrBSS->currAPInfo.beaconInterval = pParam->content.beaconInterval; 800 801 /* Capability */ 802 pParam->paramType = SITE_MGR_SITE_CAPABILITY_PARAM; 803 siteMgr_getParam(pCurrBSS->hSiteMgr,pParam); 804 pCurrBSS->currAPInfo.capabilities = pParam->content.siteMgrSiteCapability; 805 pParam->paramType = SITE_MGR_CURRENT_TSF_TIME_STAMP; 806 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 807 808 /* pCurrBSS->currAPInfo.lastRxHostTimestamp = *((TI_UINT64 *)(pIEs->TimeStamp));*/ /* TBD*/ 809 os_memoryCopy(pCurrBSS->hOs, &pCurrBSS->currAPInfo.lastRxHostTimestamp, pParam->content.siteMgrCurrentTsfTimeStamp, sizeof(TI_UINT32)); 810 811 pParam->paramType = SITE_MGR_LAST_BEACON_BUF_PARAM; 812 siteMgr_getParam(pCurrBSS->hSiteMgr, pParam); 813 pCurrBSS->currAPInfo.pBuffer = pParam->content.siteMgrLastBeacon.buffer; 814 pCurrBSS->currAPInfo.bufferLength = pParam->content.siteMgrLastBeacon.bufLength; 815 pCurrBSS->currAPInfo.resultType = (pParam->content.siteMgrLastBeacon.isBeacon) ? SCAN_RFT_BEACON : SCAN_RFT_PROBE_RESPONSE; 816 817 /* Set BSS Loss to Fw - note that it depends on the Connection type - (Infa/IBSS) */ 818 currBSS_updateBSSLoss(pCurrBSS); 819 820 if(type == BSS_INFRASTRUCTURE) 821 { 822 TI_UINT32 uKeepAlivePreiod = pCurrBSS->uDefaultKeepAlivePeriod * 1000; /* convert to ms */ 823 TSetTemplate tKeepAliveTemplate; 824 TKeepAliveParams tKeepAliveParams; 825 826 /* 827 * only configure the null-data keepa-live message if the interval is valid 828 * (either the default interval or the one from teh XCC IE) 829 */ 830 if (0 != uKeepAlivePreiod) 831 { 832 TRACE0(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION , "currBSS_updateConnectedState: Configuring null-data keep-alive"); 833 834 /* build null-data template */ 835 tKeepAliveTemplate.ptr = &(pCurrBSS->keepAliveBuffer[ 0 ]); 836 if ( TI_OK != txCtrlServ_buildNullFrame (pCurrBSS->hTxCtrl, 837 tKeepAliveTemplate.ptr, &(tKeepAliveTemplate.len))) 838 { 839 TRACE0(pCurrBSS->hReport, REPORT_SEVERITY_ERROR , "currBSS_updateConnectedState: error building null data frame\n"); 840 841 } 842 843 /* configure null-data template */ 844 tKeepAliveTemplate.type = KEEP_ALIVE_TEMPLATE; 845 tKeepAliveTemplate.index = KEEP_ALIVE_NULL_DATA_INDEX; 846 tKeepAliveTemplate.uRateMask = RATE_MASK_UNSPECIFIED; 847 TWD_CmdTemplate (pCurrBSS->hTWD, &tKeepAliveTemplate, NULL, NULL); 848 849 /* configure paramters */ 850 tKeepAliveParams.index = KEEP_ALIVE_NULL_DATA_INDEX; 851 tKeepAliveParams.enaDisFlag = TI_TRUE; /* enabled */ 852 tKeepAliveParams.trigType = KEEP_ALIVE_TRIG_TYPE_NO_TX; 853 tKeepAliveParams.interval = uKeepAlivePreiod; 854 TWD_CfgKeepAlive (pCurrBSS->hTWD, &tKeepAliveParams); 855 } 856 } 857 os_memoryFree(pCurrBSS->hOs, pParam, sizeof(paramInfo_t)); 858 } 859 else 860 { 861 if(type == BSS_INFRASTRUCTURE) 862 { 863 TKeepAliveParams tKeepAliveParams; 864 865 /* disable NULL-data keep-palive template */ 866 tKeepAliveParams.index = KEEP_ALIVE_NULL_DATA_INDEX; 867 tKeepAliveParams.enaDisFlag = TI_FALSE; /* disabled */ 868 tKeepAliveParams.interval = 1000; /* minimum accepted by the FW */ 869 tKeepAliveParams.trigType = KEEP_ALIVE_TRIG_TYPE_NO_TX; 870 TWD_CfgKeepAlive (pCurrBSS->hTWD, &tKeepAliveParams); 871 872 } 873 } 874 } 875 876 877 /** 878 * 879 * currBSS_BssLost 880 * 881 * \b Description: 882 * 883 * Callback function, called upon BSS-Loss event from FW. 884 * 885 * \b ARGS: 886 * 887 * I - hCurrBSS - Current BSS handle \n 888 * 889 * \b RETURNS: 890 * 891 * void 892 * 893 * \sa 894 */ 895 static void currBSS_BssLost (currBSS_t *hCurrBSS, 896 TI_UINT8 *data, 897 TI_UINT8 dataLength) 898 { 899 currBSS_reportRoamingEvent(hCurrBSS, ROAMING_TRIGGER_BSS_LOSS, NULL); 900 } 901 902 903 /** 904 * 905 * currBSS_consecTxErrors 906 * 907 * \b Description: 908 * 909 * Callback function, provided to HAL module. 910 * 911 * \b ARGS: 912 * 913 * I - pCurrBSS - Current BSS handle \n 914 * 915 * \b RETURNS: 916 * 917 * TI_OK on success, TI_NOK on failure. 918 * 919 * \sa 920 */ 921 static void currBSS_consecTxErrors(currBSS_t *hCurrBSS, 922 TI_UINT8 *data, 923 TI_UINT8 dataLength) 924 { 925 currBSS_reportRoamingEvent(hCurrBSS, ROAMING_TRIGGER_MAX_TX_RETRIES, NULL); 926 } 927 928 929 /** 930 * 931 * currBSS_lowRssiThrCrossed 932 * 933 * \b Description: 934 * 935 * Callback function, provided to HAL module. 936 * 937 * \b ARGS: 938 * 939 * I - pCurrBSS - Current BSS handle \n 940 * 941 * \b RETURNS: 942 * 943 * TI_OK on success, TI_NOK on failure. 944 * 945 * \sa 946 */ 947 static void currBSS_lowRssiThrCrossed(currBSS_t *hCurrBSS, 948 TI_UINT8 *data, 949 TI_UINT8 dataLength) 950 { 951 currBSS_reportRoamingEvent(hCurrBSS, ROAMING_TRIGGER_LOW_QUALITY, NULL); 952 } 953 954 955 /** 956 * 957 * currBSS_lowSnrThrCrossed 958 * 959 * \b Description: 960 * 961 * Callback function, provided to HAL module. 962 * 963 * \b ARGS: 964 * 965 * I - pCurrBSS - Current BSS handle \n 966 * 967 * \b RETURNS: 968 * 969 * TI_OK on success, TI_NOK on failure. 970 * 971 * \sa 972 */ 973 static void currBSS_lowSnrThrCrossed(currBSS_t *hCurrBSS, 974 TI_UINT8 *data, 975 TI_UINT8 dataLength) 976 { 977 currBSS_reportRoamingEvent(hCurrBSS, ROAMING_TRIGGER_LOW_SNR, NULL); 978 } 979 980 /** 981 * 982 * currBSS_reportRoamingEvent 983 * 984 * \b Description: 985 * 986 * This function checks the mode of Current BSS module. 987 * If connected to EBSS, it reports roaming event to AP Connection. 988 * 989 * \b ARGS: 990 * 991 * I - pCurrBSS - Current BSS handle \n 992 * I - roamingEventType - Roaming trigger to report \n 993 * 994 * \b RETURNS: 995 * 996 * TI_OK on success, TI_NOK on failure. 997 * 998 * \sa 999 */ 1000 static void currBSS_reportRoamingEvent(currBSS_t *pCurrBSS, 1001 apConn_roamingTrigger_e roamingEventType, 1002 roamingEventData_u *pRoamingEventData) 1003 { 1004 TRACE1(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION, "currBSS_reportRoamingEvent: trigger %d\n", roamingEventType); 1005 1006 if (pCurrBSS->isConnected) 1007 { 1008 if (pCurrBSS->type == BSS_INFRASTRUCTURE) 1009 { 1010 apConn_reportRoamingEvent(pCurrBSS->hAPConn, roamingEventType, pRoamingEventData); 1011 } 1012 else /* IBSS */ 1013 { 1014 if( roamingEventType == ROAMING_TRIGGER_BSS_LOSS ) 1015 { 1016 /* If in IBSS call the SME restart function, this logic issues a DISCONNECT 1017 * event and tries to connect to other STA or establish self connection. 1018 */ 1019 sme_Restart (pCurrBSS->hSme); 1020 } 1021 } 1022 } 1023 } 1024 1025 1026 /** 1027 * 1028 * currBSS_GetDefaultKeepAlivePeriod 1029 * 1030 * \b Description: 1031 * 1032 * Get DefaultKeepAlivePeriod parameter value. 1033 * 1034 * \b ARGS: 1035 * 1036 * I - hCurrBSS - Current BSS handle \n 1037 * I - uDefaultKeepAlivePeriod - The value \n 1038 * 1039 * \b RETURNS: 1040 * 1041 * None. 1042 * 1043 * \sa 1044 */ 1045 void currBSS_GetDefaultKeepAlivePeriod (TI_HANDLE hCurrBSS, TI_UINT8* uKeepAlivePeriod) 1046 { 1047 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1048 1049 *uKeepAlivePeriod = pCurrBSS->uDefaultKeepAlivePeriod; 1050 } 1051 1052 1053 /** 1054 * 1055 * currBSS_BackgroundScanQuality 1056 * 1057 * \b Description: 1058 * 1059 * Called be EventMBox upon Background Scan Quality Trigger. 1060 * 1061 * \b ARGS: 1062 * 1063 * I - hCurrBSS - Current BSS handle \n 1064 * 1065 * \b RETURNS: 1066 * 1067 * None. 1068 * 1069 * \sa 1070 */ 1071 static void currBSS_BackgroundScanQuality(TI_HANDLE hCurrBSS, 1072 TI_UINT8 *data, 1073 TI_UINT8 dataLength) 1074 { 1075 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1076 TI_UINT8 averageRssi = *data; 1077 paramInfo_t *pParam; 1078 1079 TRACE1(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION, "BackgroundScanQuality Event: RSSI = %d\n", averageRssi ); 1080 1081 /* Report to AP Connection about reaching RSSI low or normal (high) threshold */ 1082 if (averageRssi < pCurrBSS->lowQualityForBkgrdScan) 1083 { 1084 apConn_reportRoamingEvent(pCurrBSS->hAPConn, ROAMING_TRIGGER_LOW_QUALITY_FOR_BG_SCAN, NULL); 1085 } 1086 else 1087 { 1088 apConn_reportRoamingEvent(pCurrBSS->hAPConn, ROAMING_TRIGGER_NORMAL_QUALITY_FOR_BG_SCAN, NULL); 1089 } 1090 1091 /* Update RSSI: */ 1092 pCurrBSS->currAPInfo.RSSI = averageRssi; 1093 1094 /* Update Site Table in order to represent the RSSI of current AP correctly in the utility */ 1095 pParam = (paramInfo_t *)os_memoryAlloc(pCurrBSS->hOs, sizeof(paramInfo_t)); 1096 if (!pParam) 1097 return; 1098 pParam->paramType = SITE_MGR_CURRENT_SIGNAL_PARAM; 1099 pParam->content.siteMgrCurrentSignal.rssi = averageRssi; 1100 siteMgr_setParam(pCurrBSS->hSiteMgr, pParam); 1101 os_memoryFree(pCurrBSS->hOs, pParam, sizeof(paramInfo_t)); 1102 } 1103 1104 /* EMP specific functions - lior*/ 1105 1106 1107 /** 1108 * 1109 * currBss_findEmptyUserTrigger 1110 * 1111 * \b Description: 1112 * 1113 * Called be EventMBox upon Background Scan Quality Trigger. 1114 * 1115 * \b ARGS: 1116 * 1117 * I - hCurrBSS - Current BSS handle \n 1118 * 1119 * \b RETURNS: 1120 * 1121 * None. 1122 * 1123 * \sa 1124 */ 1125 static triggerDesc_t* currBss_findEmptyUserTrigger(TI_HANDLE hCurrBSS, TI_UINT16 clientID, TI_UINT8* triggerIdx) 1126 { 1127 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1128 TI_UINT8 i=0; 1129 1130 for (i=0; i< MAX_NUM_OF_RSSI_SNR_TRIGGERS ; i++) 1131 { 1132 if (clientID == pCurrBSS->aTriggersDesc[i].clientID || /* if the same client ID found, overwrite this trigger*/ 1133 (pCurrBSS->aTriggersDesc[i].WasRegisteredByApp == TI_FALSE && pCurrBSS->aTriggersDesc[i].fCB == NULL)) 1134 { 1135 *triggerIdx = i; 1136 return &pCurrBSS->aTriggersDesc[i]; 1137 } 1138 } 1139 1140 return NULL; 1141 } 1142 1143 1144 /** 1145 * \fn currBSS_RegisterTriggerEvent 1146 * \brief register the event in the currBss static table. 1147 * 1148 * \Args: 1149 * \param hCurrBSS - Current BSS handle 1150 * \param triggerID - The RSSI/SNR trigger ID as defined in the TWD. this arg is the table index. 1151 * \param clientID - The client ID, '0' value means internal driver module client 1152 * \param fCB - the trigger event handler. NULL value will be set for external app registration. 1153 * \return >= 0 if the empty Trigger event ID (index table) has been found and occupied 1154 else -1 to signal an error 1155 * \sa 1156 */ 1157 TI_INT8 currBSS_RegisterTriggerEvent (TI_HANDLE hCurrBSS, TI_UINT8 triggerID,TI_UINT16 clientID, void* fCB, TI_HANDLE hCB) 1158 { 1159 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1160 triggerDesc_t *pEmptyTrigger; 1161 TI_UINT8 emptyTriggerIdx = 0; 1162 1163 if (triggerID >= MAX_NUM_OF_RSSI_SNR_TRIGGERS) 1164 { 1165 TRACE1(pCurrBSS->hReport, REPORT_SEVERITY_ERROR , "currBSS_RegisterTriggerEvent: triggerID=%d is not in legal range \n", triggerID); 1166 return -1; 1167 } 1168 1169 TRACE3(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION, "currBSS_RegisterTriggerEvent: triggerID=%d, clientID=%d , fCB=%d. \n",triggerID, clientID ,fCB); 1170 1171 if(clientID > 0) /* this event is registered by application */ 1172 { 1173 pEmptyTrigger = currBss_findEmptyUserTrigger(hCurrBSS, clientID, &emptyTriggerIdx); 1174 if (pEmptyTrigger != NULL) 1175 { 1176 pEmptyTrigger->clientID = clientID; 1177 pEmptyTrigger->fCB = NULL; 1178 pEmptyTrigger->hCB = NULL; 1179 pEmptyTrigger->WasRegisteredByApp = TI_TRUE; 1180 } 1181 else 1182 { 1183 TRACE0(pCurrBSS->hReport, REPORT_SEVERITY_ERROR , "currBSS_RegisterTriggerEvent: Table is full!. no Empty trigger is available! \n"); 1184 return -1; 1185 } 1186 } 1187 else 1188 { 1189 pCurrBSS->aTriggersDesc[triggerID].clientID = 0; 1190 pCurrBSS->aTriggersDesc[triggerID].fCB = fCB; 1191 pCurrBSS->aTriggersDesc[triggerID].hCB = hCB; 1192 pCurrBSS->aTriggersDesc[triggerID].WasRegisteredByApp = TI_FALSE; 1193 } 1194 1195 TWD_EnableEvent (pCurrBSS->hTWD, triggerID); 1196 return emptyTriggerIdx; 1197 } 1198 1199 1200 1201 1202 /** 1203 * \fn currBss_HandleTriggerEvent 1204 * \brief called by the user trigger event callbcack. 1205 * 1206 * \Args: 1207 * \param hCurrBSS - Current BSS handle 1208 * \param data - The event data 1209 * \param dataLength - The event data length 1210 * \param eventID - The event ID 1211 * \return TI_STATUS 1212 * \sa 1213 */ 1214 static TI_STATUS currBss_HandleTriggerEvent(TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength, TI_UINT8 eventID) 1215 { 1216 triggerDesc_t *pTrigger; 1217 triggerDataEx_t triggerInfo; 1218 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1219 1220 TRACE1(pCurrBSS->hReport ,REPORT_SEVERITY_INFORMATION, "currBss_HandleTriggerEvent(). eventID =%d \n",eventID); 1221 1222 if (eventID < MAX_NUM_OF_RSSI_SNR_TRIGGERS) 1223 { 1224 pTrigger = &pCurrBSS->aTriggersDesc[eventID]; 1225 } 1226 else 1227 { 1228 return TI_NOK; 1229 } 1230 1231 if (TI_FALSE == pTrigger->WasRegisteredByApp) 1232 { 1233 ((TCurrBssDataCb)pTrigger->fCB)(pTrigger->hCB, data, dataLength); 1234 } 1235 else 1236 { 1237 triggerInfo.pData = data; 1238 triggerInfo.dataLength = dataLength; 1239 triggerInfo.clientID = pTrigger->clientID; 1240 EvHandlerSendEvent(pCurrBSS->hEvHandler, IPC_EVENT_RSSI_SNR_TRIGGER, (TI_UINT8*)&triggerInfo, sizeof(triggerDataEx_t)); 1241 } 1242 1243 return TI_OK; 1244 } 1245 1246 /** 1247 * \fn currBSS_RssiSnrTrigger0-7 1248 * \brief User Defined Trigger 0-7 callbacks 1249 * 1250 * Called by EventMBox upon User Defined Trigger 0 - 7. 1251 * 1252 * \note 1253 * \param hCurrBSS - Current BSS handle 1254 * \param data - The event data 1255 * \param dataLength - The event data length 1256 * \return void 1257 * \sa 1258 */ 1259 1260 static void currBSS_RssiSnrTrigger0 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1261 { 1262 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_0; 1263 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1264 } 1265 static void currBSS_RssiSnrTrigger1 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1266 { 1267 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_1; 1268 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1269 } 1270 static void currBSS_RssiSnrTrigger2 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1271 { 1272 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_2; 1273 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1274 } 1275 static void currBSS_RssiSnrTrigger3 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1276 { 1277 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_3; 1278 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1279 } 1280 static void currBSS_RssiSnrTrigger4 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1281 { 1282 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_4; 1283 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1284 } 1285 static void currBSS_RssiSnrTrigger5 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1286 { 1287 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_5; 1288 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1289 } 1290 static void currBSS_RssiSnrTrigger6 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1291 { 1292 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_6; 1293 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1294 } 1295 static void currBSS_RssiSnrTrigger7 (TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1296 { 1297 TI_UINT8 eventID = TWD_OWN_EVENT_RSSI_SNR_TRIGGER_7; 1298 currBss_HandleTriggerEvent (hCurrBSS, data, dataLength, eventID); 1299 } 1300 1301 1302 static TI_STATUS currBSS_BssLossThresholdCrossed(TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1303 { 1304 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1305 triggerDataEx_t triggerInfo; 1306 1307 triggerInfo.pData = data; 1308 triggerInfo.dataLength = dataLength; 1309 triggerInfo.clientID = pCurrBSS->BssLossClientID; 1310 EvHandlerSendEvent(pCurrBSS->hEvHandler, IPC_EVENT_BSS_LOSS, (TI_UINT8*)&triggerInfo, sizeof(triggerDataEx_t)); 1311 1312 currBSS_reportRoamingEvent(hCurrBSS, ROAMING_TRIGGER_BSS_LOSS, NULL); 1313 return TI_OK; 1314 } 1315 1316 static TI_STATUS currBSS_MaxTxRetryThresholdCrossed(TI_HANDLE hCurrBSS, TI_UINT8 *data, TI_UINT8 dataLength) 1317 { 1318 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1319 triggerDataEx_t triggerInfo; 1320 1321 triggerInfo.pData = data; 1322 triggerInfo.dataLength = dataLength; 1323 triggerInfo.clientID = pCurrBSS->TxRetryClientID; 1324 EvHandlerSendEvent(pCurrBSS->hEvHandler, IPC_EVENT_TX_RETRY_FALIURE, (TI_UINT8*)&triggerInfo, sizeof(triggerDataEx_t)); 1325 1326 currBSS_reportRoamingEvent(hCurrBSS, ROAMING_TRIGGER_BSS_LOSS, NULL); 1327 return TI_OK; 1328 } 1329 1330 1331 1332 TI_STATUS currBss_registerBssLossEvent(TI_HANDLE hCurrBSS,TI_UINT32 uNumOfBeacons, TI_UINT16 uClientID) 1333 { 1334 TRroamingTriggerParams params; 1335 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1336 1337 TRACE2(pCurrBSS->hReport,REPORT_SEVERITY_INFORMATION , "currBss_registerBssLossEvent() uNumOfBeacons=%d,uClientID =%d \n", uNumOfBeacons,uClientID ); 1338 1339 /* Register for 'BSS-Loss' event */ 1340 TWD_RegisterEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_BSS_LOSE, (void *)currBSS_BssLossThresholdCrossed, pCurrBSS); 1341 TWD_EnableEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_BSS_LOSE); 1342 1343 /* save the client ID for this event registration */ 1344 pCurrBSS->BssLossClientID = uClientID; 1345 1346 pCurrBSS->numExpectedTbttForBSSLoss = uNumOfBeacons; 1347 params.TsfMissThreshold = uNumOfBeacons; /* number of missing beacon allowed before out-of-sync event is issued*/ 1348 params.BssLossTimeout = NO_BEACON_DEFAULT_TIMEOUT; 1349 TWD_CfgConnMonitParams (pCurrBSS->hTWD, ¶ms); 1350 1351 return TI_OK; 1352 } 1353 1354 TI_STATUS currBss_registerTxRetryEvent(TI_HANDLE hCurrBSS,TI_UINT8 uMaxTxRetryThreshold, TI_UINT16 uClientID) 1355 { 1356 TRroamingTriggerParams params; 1357 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1358 1359 TRACE2(pCurrBSS->hReport,REPORT_SEVERITY_INFORMATION , "currBss_registerTxRetryEvent() uMaxTxRetryThreshold=%d,uClientID =%d \n", uMaxTxRetryThreshold,uClientID ); 1360 /* Register for 'Consec. Tx error' */ 1361 TWD_RegisterEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_MAX_TX_RETRY, (void *)currBSS_MaxTxRetryThresholdCrossed, pCurrBSS); 1362 TWD_EnableEvent (pCurrBSS->hTWD, TWD_OWN_EVENT_MAX_TX_RETRY); 1363 1364 pCurrBSS->maxTxRetryThreshold = uMaxTxRetryThreshold; 1365 params.maxTxRetry = uMaxTxRetryThreshold; 1366 TWD_CfgMaxTxRetry (pCurrBSS->hTWD, ¶ms); 1367 1368 return TI_OK; 1369 } 1370 1371 1372 1373 1374 1375 TI_STATUS currBSS_setParam(TI_HANDLE hCurrBSS, paramInfo_t *pParam) 1376 { 1377 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1378 TI_STATUS status = TI_OK; 1379 1380 if (pParam == NULL) 1381 { 1382 TRACE0(pCurrBSS->hReport, REPORT_SEVERITY_ERROR , " currBSS_setParam(): pParam is NULL!\n"); 1383 return TI_NOK; 1384 } 1385 1386 TRACE1(pCurrBSS->hReport,REPORT_SEVERITY_INFORMATION , "currBSS_setParam() %X \n", pParam->paramType); 1387 1388 switch (pParam->paramType) 1389 { 1390 case CURR_BSS_REGISTER_LINK_QUALITY_EVENT_PARAM: 1391 { 1392 TUserDefinedQualityTrigger *pUserTrigger = &pParam->content.rssiSnrTrigger; 1393 RssiSnrTriggerCfg_t tTriggerCfg; 1394 TI_INT8 triggerID = 0; 1395 1396 TRACE8(pCurrBSS->hReport, REPORT_SEVERITY_INFORMATION , "currBSS_setParam - USER_DEFINED_TRIGGER: \n index = %d, \n threshold = %d, \n pacing = %d, \n metric = %d, \n type = %d, \n direction = %d, \n hystersis = %d, \n enable = %d \n",pUserTrigger->uIndex,pUserTrigger->iThreshold,pUserTrigger->uPacing,pUserTrigger->uMetric,pUserTrigger->uType,pUserTrigger->uDirection,pUserTrigger->uHystersis,pUserTrigger->uEnable); 1397 /* Copy from user structure to driver structure */ 1398 tTriggerCfg.index = pUserTrigger->uIndex; 1399 tTriggerCfg.threshold = pUserTrigger->iThreshold; 1400 tTriggerCfg.pacing = pUserTrigger->uPacing; 1401 tTriggerCfg.metric = pUserTrigger->uMetric; 1402 tTriggerCfg.type = pUserTrigger->uType; 1403 tTriggerCfg.direction = pUserTrigger->uDirection; 1404 tTriggerCfg.hystersis = pUserTrigger->uHystersis; 1405 tTriggerCfg.enable = pUserTrigger->uEnable; 1406 1407 /* the registration request is not from EMP (clientID must be greater than 0) 1408 so it is probably external user mode application like the CLI that sends always '0' as client ID*/ 1409 if (pUserTrigger->uClientID == 0) 1410 { 1411 pUserTrigger->uClientID = pUserTrigger->uIndex + 1; /* use the index (starting from '0') as positive client ID*/ 1412 } 1413 /* Register the event and enable it before configuration. */ 1414 triggerID = currBSS_RegisterTriggerEvent(hCurrBSS, (TI_UINT8)0, pUserTrigger->uClientID, (void*)0, hCurrBSS); 1415 1416 if (triggerID < 0) 1417 { 1418 TRACE0(pCurrBSS->hReport, REPORT_SEVERITY_ERROR , "currBSS_setParam: RSSI/SNR user trigger registration FAILED!! \n"); 1419 return TI_NOK; 1420 } 1421 else 1422 { 1423 tTriggerCfg.index = (uint8)triggerID; /* the index is used for the eventMBox triggerID mapping*/ 1424 } 1425 /* Send user defined trigger to FW (the related FW events are handled by the currBSS) */ 1426 status = TWD_CfgRssiSnrTrigger (pCurrBSS->hTWD, &tTriggerCfg); 1427 1428 } 1429 break; 1430 1431 default: 1432 TRACE1(pCurrBSS->hReport, REPORT_SEVERITY_ERROR, "currBSS_setParam bad param= %X\n", pParam->paramType); 1433 break; 1434 } 1435 1436 return status; 1437 } 1438 1439 1440 TI_STATUS currBSS_getParam(TI_HANDLE hCurrBSS, paramInfo_t *pParam) 1441 { 1442 return TI_NOK; 1443 } 1444 1445 void currBss_DbgPrintTriggersTable(TI_HANDLE hCurrBSS) 1446 { 1447 #ifdef REPORT_LOG 1448 int i=0; 1449 currBSS_t *pCurrBSS = (currBSS_t *)hCurrBSS; 1450 1451 WLAN_OS_REPORT(("\n ------------------- Triggers Table -------------------------- \n")); 1452 1453 for (i=0; i< MAX_NUM_OF_RSSI_SNR_TRIGGERS ; i++) 1454 { 1455 WLAN_OS_REPORT(("\n TriggerIdx[%d]: clientID=%d , fCB=%d, WasRegisteredByApp=%d. \n", 1456 i, 1457 pCurrBSS->aTriggersDesc[i].clientID, 1458 pCurrBSS->aTriggersDesc[i].fCB, 1459 pCurrBSS->aTriggersDesc[i].WasRegisteredByApp)); 1460 } 1461 WLAN_OS_REPORT(("\n --------------------------------------------------------------- \n")); 1462 #endif 1463 } 1464