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