OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / hardware / ti / wlan / wl1271 / stad / src / Sta_Management / scanResultTable.c
1 /*
2  * scanResultTable.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  scanResultTable.c 
35  *  \brief implements a table holding scan results, by BSSID
36  *
37  *  \see   scanResultTable.h
38  */
39
40
41 #define __FILE_ID__  FILE_ID_81
42 #include "osApi.h"
43 #include "report.h"
44 #include "scanResultTable.h"
45 #include "siteMgrApi.h"
46 #include "freq.h"
47
48
49 //#define TABLE_ENTRIES_NUMBER    32
50
51 #define MILISECONDS(seconds)                            (seconds * 1000)
52 #define UPDATE_LOCAL_TIMESTAMP(pSite, hOs)              pSite->localTimeStamp = os_timeStampMs(hOs);
53
54 #define UPDATE_BSSID(pSite, pFrame)                     MAC_COPY((pSite)->bssid, *((pFrame)->bssId))
55 #define UPDATE_BAND(pSite, pFrame)                      (pSite)->eBand = (pFrame)->band
56 #define UPDATE_BEACON_INTERVAL(pSite, pFrame)           pSite->beaconInterval = (pFrame)->parsedIEs->content.iePacket.beaconInerval
57 #define UPDATE_CAPABILITIES(pSite, pFrame)              pSite->capabilities = (pFrame)->parsedIEs->content.iePacket.capabilities
58 #define UPDATE_PRIVACY(pSite, pFrame)                   pSite->privacy = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TI_TRUE : TI_FALSE
59 #define UPDATE_AGILITY(pSite, pFrame)                   pSite->agility = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_AGILE_SHIFT) & CAP_AGILE_MASK) ? TI_TRUE : TI_FALSE
60 #define UPDATE_SLOT_TIME(pSite, pFrame)                 pSite->newSlotTime = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_SLOT_TIME_SHIFT) & CAP_SLOT_TIME_MASK) ? PHY_SLOT_TIME_SHORT : PHY_SLOT_TIME_LONG
61 #define UPDATE_PROTECTION(pSite, pFrame)                pSite->useProtection = ((pFrame)->parsedIEs->content.iePacket.useProtection)
62 #define UPDATE_CHANNEL(pSite, pFrame, rxChannel)        if ((pFrame)->parsedIEs->content.iePacket.pDSParamsSet == NULL) \
63                                                             pSite->channel = rxChannel; \
64                                                         else \
65                                                             pSite->channel = (pFrame)->parsedIEs->content.iePacket.pDSParamsSet->currChannel;
66 #define UPDATE_DTIM_PERIOD(pSite, pFrame)               if ((pFrame)->parsedIEs->content.iePacket.pTIM != NULL) \
67                                                             pSite->dtimPeriod = (pFrame)->parsedIEs->content.iePacket.pTIM->dtimPeriod
68 #define UPDATE_ATIM_WINDOW(pSite, pFrame)               if ((pFrame)->parsedIEs->content.iePacket.pIBSSParamsSet != NULL) \
69                                                             pSite->atimWindow = (pFrame)->parsedIEs->content.iePacket.pIBSSParamsSet->atimWindow
70 #define UPDATE_AP_TX_POWER(pSite, pFrame)               if ((pFrame)->parsedIEs->content.iePacket.TPCReport != NULL) \
71                                                             pSite->APTxPower = (pFrame)->parsedIEs->content.iePacket.TPCReport->transmitPower
72 #define UPDATE_BSS_TYPE(pSite, pFrame)                  pSite->bssType = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_ESS_SHIFT) & CAP_ESS_MASK) ? BSS_INFRASTRUCTURE : BSS_INDEPENDENT
73 #define UPDATE_RSN_IE(pScanResultTable, pSite, pNewRsnIe, newRsnIeLen) if ((pNewRsnIe) != NULL) { \
74                                                             TI_UINT8 length=0, index=0;\
75                                                             dot11_RSN_t *pTempRsnIe = (pNewRsnIe); \
76                                                             (pSite)->rsnIeLen = (newRsnIeLen);\
77                                                             while ((length < (pSite)->rsnIeLen) && (index < MAX_RSN_IE)) {\
78                                                                 (pSite)->pRsnIe[index].hdr[0] = pTempRsnIe->hdr[0];\
79                                                                 (pSite)->pRsnIe[index].hdr[1] = pTempRsnIe->hdr[1];\
80                                                                 os_memoryCopy(pScanResultTable->hOS, (void *)(pSite)->pRsnIe[index].rsnIeData, (void *)pTempRsnIe->rsnIeData, pTempRsnIe->hdr[1]);\
81                                                                 length += (pTempRsnIe->hdr[1]+2); \
82                                                                 pTempRsnIe += 1; \
83                                                                 index++;}\
84                                                         } \
85                                                         else {pSite->rsnIeLen = 0;}
86 #define UPDATE_BEACON_TIMESTAMP(pScanResultTable, pSite, pFrame)    os_memoryCopy(pScanResultTable->hOS, pSite->tsfTimeStamp, (void *)(pFrame)->parsedIEs->content.iePacket.timestamp, TIME_STAMP_LEN)
87
88 /* Updated from beacons */
89 #define UPDATE_BEACON_MODULATION(pSite, pFrame)         pSite->beaconModulation = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_PBCC_SHIFT) & CAP_PBCC_MASK) ? DRV_MODULATION_PBCC : DRV_MODULATION_CCK
90 #define UPDATE_BEACON_RECV(pSite)                       pSite->beaconRecv = TI_TRUE
91
92 /* Updated from probes */
93 #define UPDATE_PROBE_MODULATION(pSite, pFrame)          pSite->probeModulation = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_PBCC_SHIFT) & CAP_PBCC_MASK) ? DRV_MODULATION_PBCC : DRV_MODULATION_CCK
94 #define UPDATE_PROBE_RECV(pSite)                        pSite->probeRecv = TI_TRUE
95 #define UPDATE_APSD(pSite, pFrame)                      if ((pFrame)->parsedIEs->content.iePacket.WMEParams == NULL) \
96                                                                 (pSite)->APSDSupport = ((((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_APSD_SHIFT) & CAP_APSD_MASK) ? TI_TRUE : TI_FALSE); \
97                                                         else \
98                                                             pSite->APSDSupport = (((((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_APSD_SHIFT) & CAP_APSD_MASK) ? TI_TRUE : TI_FALSE) || \
99                                                                                   ((((pFrame)->parsedIEs->content.iePacket.WMEParams->ACInfoField >> AP_QOS_INFO_UAPSD_SHIFT) & AP_QOS_INFO_UAPSD_MASK) ? TI_TRUE : TI_FALSE));
100 #define UPDATE_PREAMBLE(pSite, pFrame)                  { (pSite)->currentPreambleType = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_PREAMBLE_SHIFT) & CAP_PREAMBLE_MASK) ? PREAMBLE_SHORT : PREAMBLE_LONG; \
101                                                           (pSite)->barkerPreambleType = (pFrame)->parsedIEs->content.iePacket.barkerPreambleMode; }
102 #define UPDATE_QOS(pSite, pFrame)                       if ( ((pFrame)->parsedIEs->content.iePacket.WMEParams  != NULL) && \
103                                                              (((((pFrame)->parsedIEs->content.iePacket.WMEParams->ACInfoField) & dot11_WME_ACINFO_MASK) != pSite->lastWMEParameterCnt) || (!pSite->WMESupported)) ) \
104                                                             pSite->WMESupported = TI_TRUE; \
105                                                         else \
106                                                             pSite->WMESupported = TI_FALSE;
107 #define UPDATE_FRAME_BUFFER(pScanResultTable, pBuffer, uLength, pFrame)  if (pFrame->bufferLength < MAX_BEACON_BODY_LENGTH) \
108                                                         { \
109                                                            os_memoryCopy (pScanResultTable->hOS, pBuffer, pFrame->buffer, pFrame->bufferLength); \
110                                                            uLength = pFrame->bufferLength; \
111                                                         }
112 #define UPDATE_RSSI(pSite, pFrame)                      (pSite)->rssi = (pFrame)->rssi;
113 #define UPDATE_SNR(pSite, pFrame)                       (pSite)->snr = (pFrame)->snr;
114 #define UPDATE_RATE(pSite, pFrame)                      if ((DRV_RATE_1M <= (pFrame)->rate) && (DRV_RATE_54M <= (pFrame)->rate)) \
115                                                             (pSite)->rxRate = (pFrame)->rate;
116 #define UPDATE_UNKOWN_IE(pScanResultTable, pSite, pNewUnknwonIe, newUnknwonIeLen) if ((pNewUnknwonIe) != NULL) { \
117                                                                                     pSite->unknownIeLen = newUnknwonIeLen; \
118                                                                                     os_memoryCopy(pScanResultTable->hOS, \
119                                                                                                   (void *)(pSite->pUnknownIe), \
120                                                                                                   pNewUnknwonIe, \
121                                                                                                   newUnknwonIeLen);     \
122                                                                                   } else { \
123                                                                                         pSite->unknownIeLen = 0; \
124                                                                                   }
125
126
127 typedef struct
128 {
129     TI_HANDLE       hOS;                    /**< Handle to the OS object */
130     TI_HANDLE       hReport;                /**< handle to the report object */
131     TI_HANDLE       hSiteMgr;               /**< Handle to the site manager object */
132     TSiteEntry      *pTable;                /**< site table */
133     TI_UINT32       uCurrentSiteNumber;     /**< number of sites currently in the table */
134     TI_UINT32       uEntriesNumber;         /**< max size of the table */
135     TI_UINT32       uIterator;              /**< table iterator used for getFirst / getNext */
136     TI_UINT32       uSraThreshold;          /**< Rssi threshold for frame filtering */
137     TI_BOOL         bStable;                /**< table status (updating / stable) */
138     EScanResultTableClear  eClearTable;     /** inicates if table should be cleared at scan */
139 } TScanResultTable;
140
141 static TSiteEntry  *scanResultTbale_AllocateNewEntry (TI_HANDLE hScanResultTable);
142 static void         scanResultTable_UpdateSiteData (TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame);
143 static void         scanResultTable_updateRates(TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame);
144 static void         scanResultTable_UpdateWSCParams (TSiteEntry *pSite, TScanFrameInfo *pFrame);
145 static TI_STATUS    scanResultTable_CheckRxSignalValidity(TScanResultTable *pScanResultTable, siteEntry_t *pSite, TI_INT8 rxLevel, TI_UINT8 channel);
146 static void         scanResultTable_RemoveEntry(TI_HANDLE hScanResultTable, TI_UINT32 uIndex);
147
148
149 /** 
150  * \fn     scanResultTable_Create 
151  * \brief  Create a scan result table object.
152  * 
153  * Create a scan result table object. Allocate system resources.
154  * 
155  * \note   
156  * \param  hOS - handle to the OS object
157  * \return Handle to the newly created scan result table object, NULL if an error occured.
158  * \sa     scanResultTable_Init, scanResultTable_Destroy
159  */ 
160 TI_HANDLE scanResultTable_Create (TI_HANDLE hOS, TI_UINT32 uEntriesNumber)
161 {
162     TScanResultTable    *pScanResultTable = NULL;
163
164     /* Allocate object storage */
165     pScanResultTable = (TScanResultTable*)os_memoryAlloc (hOS, sizeof(TScanResultTable));
166     if (NULL == pScanResultTable)
167     {
168         /* because the malloc failure here the TRACEx can not be used (no pointer for the 1st parameter to TRACEx) */
169         WLAN_OS_REPORT(("scanResultTable_Create: Unable to allocate memory for pScanResultTable of %d bytes\n", 
170                           sizeof (TScanResultTable)));
171         return NULL;  /* this is done similarly to the next error case */
172     }
173
174     pScanResultTable->hOS = hOS;
175     /* allocate memory for sites' data */
176     pScanResultTable->pTable = 
177         (TSiteEntry *)os_memoryAlloc (pScanResultTable->hOS, sizeof (TSiteEntry) * uEntriesNumber);
178     if (NULL == pScanResultTable->pTable)
179     {
180         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , 
181                            "scanResultTable_Create: Unable to allocate memory for %d entries of %d bytes\n", 
182                            uEntriesNumber , sizeof (TSiteEntry));
183         os_memoryFree(pScanResultTable->hOS, pScanResultTable, sizeof(TScanResultTable));
184         return NULL;
185     }
186     pScanResultTable->uEntriesNumber = uEntriesNumber;
187     os_memoryZero(pScanResultTable->hOS, pScanResultTable->pTable, sizeof(TSiteEntry) * uEntriesNumber);
188     return (TI_HANDLE)pScanResultTable;
189 }
190
191 /** 
192  * \fn     scanResultTable_Init 
193  * \brief  Initializes the scan result table object 
194  * 
195  * Initializes the scan result table object. Set handles to other objects.
196  * 
197  * \param  hScanResultTable - handle to the scan result table object
198  * \param  pStadHandles - modules handles table
199  * \param  eClearTable - indicates if the table should be cleared, used when a frame arrives 
200  *                       or setStable is called and the table is in stable state
201  * \return None
202  * \sa     scanResultTable_Create
203  */ 
204 void        scanResultTable_Init (TI_HANDLE hScanResultTable, TStadHandlesList *pStadHandles, EScanResultTableClear eClearTable)
205 {
206     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
207
208     /* set handles to other modules */
209     pScanResultTable->hReport = pStadHandles->hReport;
210     pScanResultTable->hSiteMgr = pStadHandles->hSiteMgr;
211
212     /* initialize other parameters */
213     pScanResultTable->uCurrentSiteNumber = 0;
214     pScanResultTable->bStable = TI_TRUE;
215     pScanResultTable->uIterator = 0;
216     pScanResultTable->eClearTable = eClearTable;
217     /* default Scan Result Aging threshold is 60 second */
218     pScanResultTable->uSraThreshold = 60;
219 }
220
221
222 /** 
223  * \fn     scanResultTable_Destroy 
224  * \brief  Destroys the scan result table object
225  * 
226  * Destroys the scan result table object. Release system resources
227  * 
228  * \param  hScanResultTable - handle to the scan result table object
229  * \return None
230  * \sa     scanResultTable_Create 
231  */ 
232 void        scanResultTable_Destroy (TI_HANDLE hScanResultTable)
233 {
234     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
235
236     /* if the table memory has already been allocated */
237     if (NULL != pScanResultTable->pTable)
238     {
239         /* free table memory */
240         os_memoryFree (pScanResultTable->hOS, (void*)pScanResultTable->pTable, 
241                        sizeof (TSiteEntry) * pScanResultTable->uEntriesNumber);
242     }
243
244     /* free scan result table object memeory */
245     os_memoryFree (pScanResultTable->hOS, (void*)hScanResultTable, sizeof (TScanResultTable));
246 }
247
248 /** 
249  * \fn     scanResultTable_SetSraThreshold
250  * \brief  set Scan Result Aging threshold 
251  *  
252  * \param  hScanResultTable - handle to the scan result table object
253  * \param  uSraThreshold - Scan Result Aging threshold
254  * \return None
255  * \sa     scanResultTable_performAging
256  */ 
257 void scanResultTable_SetSraThreshold(TI_HANDLE hScanResultTable, TI_UINT32 uSraThreshold)
258 {
259     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
260     pScanResultTable->uSraThreshold = uSraThreshold;
261 }
262
263 /** 
264  * \fn     scanResultTable_UpdateEntry
265  * \brief  Update or insert a site data. 
266  * 
267  * Update a site's data in the table if it already exists, or create an entry if the site doesn't exist.
268  * If the table is in stable state, will move it to updating state and clear its contents if bClearTable
269  * is eClearTable.
270  * 
271  * \param  hScanResultTable - handle to the scan result table object
272  * \param  pBssid - a pointer to the site BSSID
273  * \param  pframe - a pointer to the received frame data
274  * \return TI_OK if entry was inseretd or updated successfuly, TI_NOK if table is full
275  * \sa     scanResultTable_SetStableState
276  */ 
277 TI_STATUS scanResultTable_UpdateEntry (TI_HANDLE hScanResultTable, TMacAddr *pBssid, TScanFrameInfo* pFrame)
278 {
279     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
280     TSiteEntry          *pSite;
281     TSsid               tTempSsid;
282
283     TRACE6(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_UpdateEntry: Adding or updating BBSID: %02x:%02x:%02x:%02x:%02x:%02x\n", (*pBssid)[ 0 ], (*pBssid)[ 1 ], (*pBssid)[ 2 ], (*pBssid)[ 3 ], (*pBssid)[ 4 ], (*pBssid)[ 5 ]);
284
285     /* check if the table is in stable state */
286     if (TI_TRUE == pScanResultTable->bStable)
287     {
288         TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_UpdateEntry: table is stable, clearing table and moving to updating state\n");
289         /* move the table to updating state */
290         pScanResultTable->bStable = TI_FALSE;
291
292         if (SCAN_RESULT_TABLE_CLEAR == pScanResultTable->eClearTable) 
293         {
294             /* clear table contents */
295             pScanResultTable->uCurrentSiteNumber = 0;
296         }
297     }
298
299     /* Verify that the SSID IE is available (if not return NOK) */
300     if (NULL == pFrame->parsedIEs->content.iePacket.pSsid) 
301     {
302         TRACE6(pScanResultTable->hReport, REPORT_SEVERITY_WARNING, "scanResultTable_UpdateEntry: can't add site %02d:%02d:%02d:%02d:%02d:%02d"                                  " because SSID IE is NULL\n", pBssid[ 0 ], pBssid[ 1 ], pBssid[ 2 ], pBssid[ 3 ], pBssid[ 4 ], pBssid[ 5 ]);
303         return TI_NOK;
304     }
305
306     /* use temporary SSID structure, and verify SSID length */
307     tTempSsid.len = pFrame->parsedIEs->content.iePacket.pSsid->hdr[1];
308     if (tTempSsid.len > MAX_SSID_LEN)
309     {
310         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_WARNING, "scanResultTable_UpdateEntry: SSID len=%d out of range. replaced by %d\n", tTempSsid.len, MAX_SSID_LEN);
311         return TI_NOK;
312     }
313     os_memoryCopy(pScanResultTable->hOS, 
314                   (void *)&(tTempSsid.str[ 0 ]), 
315                   (void *)&(pFrame->parsedIEs->content.iePacket.pSsid->serviceSetId[ 0 ]),
316                   tTempSsid.len);
317     if (MAX_SSID_LEN > tTempSsid.len)
318         tTempSsid.str[ tTempSsid.len ] ='\0';
319
320     /* check if the SSID:BSSID pair already exists in the table */
321     pSite = scanResultTable_GetBySsidBssidPair (hScanResultTable, &tTempSsid ,pBssid);
322     if (NULL != pSite)
323     {
324         if (TI_NOK != scanResultTable_CheckRxSignalValidity(pScanResultTable, pSite, pFrame->rssi, pFrame->channel))
325         {
326             TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_UpdateEntry: entry already exists, updating\n");
327             /* BSSID exists: update its data */
328             scanResultTable_UpdateSiteData (hScanResultTable, pSite, pFrame);
329         }
330     }
331     else
332     {
333         TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_UpdateEntry: entry doesn't exist, allocating a new entry\n");
334         /* BSSID doesn't exist: allocate a new entry for it */
335         pSite = scanResultTbale_AllocateNewEntry (hScanResultTable);
336         if (NULL == pSite)
337         {
338             TRACE6(pScanResultTable->hReport, REPORT_SEVERITY_WARNING , "scanResultTable_UpdateEntry: can't add site %02d:%02d:%02d:%02d:%02d:%02d"                                  " because table is full\n", pBssid[ 0 ], pBssid[ 1 ], pBssid[ 2 ], pBssid[ 3 ], pBssid[ 4 ], pBssid[ 5 ]);
339             return TI_NOK;
340         }
341
342         /* and update its data */
343         scanResultTable_UpdateSiteData (hScanResultTable, 
344                                         pSite,
345                                         pFrame);
346     }
347
348     return TI_OK;
349 }
350
351 /** 
352  * \fn     scanResultTable_SetStableState 
353  * \brief  Moves the table to stable state 
354  * 
355  * Moves the table to stable state. Also clears the tabel contents if required.
356  * 
357  * \param  hScanResultTable - handle to the scan result table object
358  * \param  eClearTable - indicates if the table should be cleared in case the table
359  *                       is in stable state (no result where received in last scan).
360  * \return None
361  * \sa     scanResultTable_UpdateEntry 
362  */ 
363 void    scanResultTable_SetStableState (TI_HANDLE hScanResultTable)
364 {
365     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
366
367     TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_SetStableState: setting stable state\n");
368
369     /* if also asked to clear the table, if it is at Stable mode means that no results were received, clear it! */
370     if ((TI_TRUE == pScanResultTable->bStable) && (SCAN_RESULT_TABLE_CLEAR == pScanResultTable->eClearTable))
371     {
372         TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_SetStableState: also clearing table contents\n");
373
374         pScanResultTable->uCurrentSiteNumber = 0;
375     }
376
377     /* set stable state */
378     pScanResultTable->bStable = TI_TRUE;
379
380 }
381
382 /** 
383  * \fn     scanResultTable_GetFirst 
384  * \brief  Retrieves the first entry in the table 
385  * 
386  * Retrieves the first entry in the table
387  * 
388  * \param  hScanResultTable - handle to the scan result table object
389  * \return A pointer to the first entry in the table, NULL if the table is empty
390  * \sa     scanResultTable_GetNext
391  */ 
392 TSiteEntry  *scanResultTable_GetFirst (TI_HANDLE hScanResultTable)
393 {
394     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
395
396     /* initialize the iterator to point at the first site */
397     pScanResultTable->uIterator = 0;
398
399     /* and return the next entry... */
400     return scanResultTable_GetNext (hScanResultTable);
401 }
402
403 /** 
404  * \fn     scanResultTable_GetNext
405  * \brief  Retreives the next entry in the table
406  * 
407  * Retreives the next entry in the table, until table is exhusted. A call to scanResultTable_GetFirst
408  * must preceed a sequence of calls to this function.
409  * 
410  * \param  hScanResultTable - handle to the scan result table object
411  * \return A pointer to the next entry in the table, NULL if the table is exhsuted
412  * \sa     scanResultTable_GetFirst
413  */ 
414 TSiteEntry  *scanResultTable_GetNext (TI_HANDLE hScanResultTable)
415 {
416     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
417
418     /* if the iterator points to a site behind current table storage, return error */
419     if (pScanResultTable->uCurrentSiteNumber <= pScanResultTable->uIterator)
420     {
421         return NULL;
422     }
423
424     return &(pScanResultTable->pTable[ pScanResultTable->uIterator++ ]);
425 }
426
427 /** 
428  * \fn     scanResultTable_GetByBssid
429  * \brief  retreives an entry according to its SSID and BSSID
430  * 
431  * retreives an entry according to its BSSID
432  * 
433  * \param  hScanResultTable - handle to the scan result table object
434  * \param  pSsid - SSID to search for
435  * \param  pBssid - BSSID to search for
436  * \return A pointer to the entry with macthing BSSID, NULL if no such entry was found. 
437  */ 
438 TSiteEntry  *scanResultTable_GetBySsidBssidPair (TI_HANDLE hScanResultTable, TSsid *pSsid, TMacAddr *pBssid)
439 {
440     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
441     TI_UINT32           uIndex;
442
443     TRACE6(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBySsidBssidPair: Searching for SSID  BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pBssid)[ 0 ], (*pBssid)[ 1 ], (*pBssid)[ 2 ], (*pBssid)[ 3 ], (*pBssid)[ 4 ], (*pBssid)[ 5 ]);
444     
445     /* check all entries in the table */
446     for (uIndex = 0; uIndex < pScanResultTable->uCurrentSiteNumber; uIndex++)
447     {
448         /* if the BSSID and SSID match */
449         if (MAC_EQUAL (*pBssid, pScanResultTable->pTable[ uIndex ].bssid) &&
450             ((pSsid->len == pScanResultTable->pTable[ uIndex ].ssid.len) &&
451              (0 == os_memoryCompare (pScanResultTable->hOS, (TI_UINT8 *)(&(pSsid->str[ 0 ])),
452                                      (TI_UINT8 *)(&(pScanResultTable->pTable[ uIndex ].ssid.str[ 0 ])),
453                                      pSsid->len))))
454         {
455             TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "Entry found at index %d\n", uIndex);
456             return &(pScanResultTable->pTable[ uIndex ]);
457         }
458     }
459
460     /* site wasn't found: return NULL */
461     TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBySsidBssidPair: Entry was not found\n");
462     return NULL;
463 }
464
465 /** 
466  * \fn     scanResultTable_FindHidden
467  * \brief  find entry with hidden SSID anfd return it's index
468  * 
469  * \param  hScanResultTable - handle to the scan result table object
470  * \param  uHiddenSsidIndex - entry index to return
471  * \return TI_OK if found, TI_NOT if not. 
472  */ 
473 static TI_STATUS scanResultTable_FindHidden (TScanResultTable *pScanResultTable, TI_UINT32 *uHiddenSsidIndex)
474 {
475     TI_UINT32 uIndex;
476
477     TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_FindHidden: Searching for hidden SSID\n");
478     
479     /* check all entries in the table */
480     for (uIndex = 0; uIndex < pScanResultTable->uCurrentSiteNumber; uIndex++)
481     {
482         /* check if entry is with hidden SSID */
483         if ( (pScanResultTable->pTable[ uIndex ].ssid.len == 0) ||
484             ((pScanResultTable->pTable[ uIndex ].ssid.len == 1) && (pScanResultTable->pTable[ uIndex ].ssid.str[0] == 0)))
485         {
486             TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_FindHidden: Entry found at index %d\n", uIndex);
487             *uHiddenSsidIndex = uIndex;
488             return TI_OK;
489         }
490     }
491
492     /* site wasn't found: return NULL */
493     TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_FindHidden: Entry was not found\n");
494     return TI_NOK;
495 }
496
497 /** 
498  * \fn     scanResultTable_performAging 
499  * \brief  Deletes from table all entries which are older than the Sra threshold
500  * 
501  * \param  hScanResultTable - handle to the scan result table object
502  * \return None
503  * \sa     scanResultTable_SetSraThreshold
504  */ 
505 void   scanResultTable_PerformAging(TI_HANDLE hScanResultTable)
506 {
507     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
508     TI_UINT32           uIndex = 0;
509
510     /* check all entries in the table */
511     while (uIndex < pScanResultTable->uCurrentSiteNumber)
512     {
513         /* check if the entry's age is old if it remove it */
514         if (pScanResultTable->pTable[uIndex].localTimeStamp < 
515             os_timeStampMs(pScanResultTable->hOS) - MILISECONDS(pScanResultTable->uSraThreshold))
516         {
517             /* The removeEntry places the last entry instead of the deleted entry
518              * in order to preserve the table's continuity. For this reason the
519              * uIndex is not incremented because we want to check the entry that 
520              * was placed instead of the entry deleted */
521             scanResultTable_RemoveEntry(hScanResultTable, uIndex);
522         }
523         else
524         {
525             /* If the entry was not deleted check the next entry */
526             uIndex++;
527         }
528     }
529 }
530
531 /** 
532  * \fn     scanResultTable_removeEntry 
533  * \brief  Deletes entry from table
534  *         the function keeps a continuty in the table by copying the last
535  *         entry in the table to the place the entry was deleted from
536  * 
537  * \param  hScanResultTable - handle to the scan result table object
538  * \param  uIndex           - index of the entry to be deleted
539  * \return TI_OK if entry deleted successfully TI_NOK otherwise
540  */ 
541 void   scanResultTable_RemoveEntry(TI_HANDLE hScanResultTable, TI_UINT32 uIndex)
542 {
543     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
544
545     if (uIndex >= pScanResultTable->uCurrentSiteNumber) 
546     {
547         TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_removeEntry: %d out of bound entry index\n", uIndex);
548         return;
549     }
550
551     /* if uIndex is not the last entry, then copy the last entry in the table to the uIndex entry */
552     if (uIndex < (pScanResultTable->uCurrentSiteNumber - 1))
553     {
554         os_memoryCopy(pScanResultTable->hOS, 
555                       &(pScanResultTable->pTable[uIndex]), 
556                       &(pScanResultTable->pTable[pScanResultTable->uCurrentSiteNumber - 1]),
557                       sizeof(TSiteEntry));
558     }
559
560     /* clear the last entry */
561     os_memoryZero(pScanResultTable->hOS, &(pScanResultTable->pTable[pScanResultTable->uCurrentSiteNumber - 1]), sizeof(TSiteEntry));
562     /* decrease the current table size */
563     pScanResultTable->uCurrentSiteNumber--;
564 }
565
566 /** 
567  * \fn     scanresultTbale_AllocateNewEntry 
568  * \brief  Allocates an empty entry for a new site
569  * 
570  * Function Allocates an empty entry for a new site (and nullfiies required entry fields)
571  * 
572  * \param  hScanResultTable - handle to the scan result table object
573  * \return Pointer to the site entry (NULL if the table is full)
574  */ 
575 TSiteEntry *scanResultTbale_AllocateNewEntry (TI_HANDLE hScanResultTable)
576 {
577     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
578     TI_UINT32 uHiddenSsidIndex;
579
580     /* if the table is full */
581     if (pScanResultTable->uCurrentSiteNumber >= pScanResultTable->uEntriesNumber)
582     {
583         /* replace hidden SSID entry with the new result */
584         if (scanResultTable_FindHidden(pScanResultTable, &uHiddenSsidIndex) == TI_OK)
585         {
586             TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTbale_AllocateNewEntry: Table is full, found hidden SSID at index %d to replace with\n", uHiddenSsidIndex);
587             
588             /* Nullify new site data */
589             os_memoryZero(pScanResultTable->hOS, &(pScanResultTable->pTable[ uHiddenSsidIndex ]), sizeof (TSiteEntry));
590
591             /* return the site */
592             return &(pScanResultTable->pTable[ uHiddenSsidIndex ]);
593         }
594
595         TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTbale_AllocateNewEntry: Table is full, no Hidden SSDI to replace, can't allocate new entry\n");
596         return NULL;
597     }
598
599     TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTbale_AllocateNewEntry: New entry allocated at index %d\n", pScanResultTable->uCurrentSiteNumber);
600
601     /* Nullify new site data */
602     os_memoryZero(pScanResultTable->hOS, &(pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ]), sizeof (TSiteEntry));
603
604     /* return the site (and update site count) */
605     pScanResultTable->uCurrentSiteNumber++;
606     return &(pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber - 1 ]);
607 }
608
609 /** 
610  * \fn     scanResultTable_UpdateSiteData 
611  * \brief  Update a site entry data from a received frame (beacon or probe response)
612  * 
613  * Update a site entry data from a received frame (beacon or probe response)
614  * 
615  * \param  hScanResultTable - handle to the scan result table object
616  * \param  pSite - the site entry to update
617  * \param  pFrame - the received frame information
618  * \return None
619  */ 
620 void scanResultTable_UpdateSiteData (TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame)
621 {
622     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
623     paramInfo_t         param;
624
625     /* Update SSID */
626     if (pFrame->parsedIEs->content.iePacket.pSsid != NULL) 
627     {
628         pSite->ssid.len = pFrame->parsedIEs->content.iePacket.pSsid->hdr[1];
629         if (pSite->ssid.len > MAX_SSID_LEN) 
630         {
631            TRACE2( pScanResultTable->hReport, REPORT_SEVERITY_ERROR, "scanResultTable_UpdateSiteData: pSite->ssid.len=%d exceeds the limit. Set to limit value %d\n", pSite->ssid.len, MAX_SSID_LEN);
632            pSite->ssid.len = MAX_SSID_LEN;
633         }
634         os_memoryCopy(pScanResultTable->hOS,
635             (void *)pSite->ssid.str,
636             (void *)pFrame->parsedIEs->content.iePacket.pSsid->serviceSetId,
637             pSite->ssid.len);
638         if (pSite->ssid.len < MAX_SSID_LEN) 
639         {
640             pSite->ssid.str[pSite->ssid.len] = '\0';
641         }
642     }
643
644         /* Since a new scan was initiated the entry can be selected again */
645         pSite->bConsideredForSelect = TI_FALSE;
646     UPDATE_LOCAL_TIMESTAMP(pSite, pScanResultTable->hOS);
647
648     UPDATE_BSSID (pSite, pFrame);
649     UPDATE_BAND (pSite, pFrame);
650     UPDATE_BEACON_INTERVAL (pSite, pFrame);
651     UPDATE_CAPABILITIES (pSite, pFrame);
652     UPDATE_PRIVACY (pSite, pFrame);
653     UPDATE_RSN_IE (pScanResultTable, pSite, pFrame->parsedIEs->content.iePacket.pRsnIe, pFrame->parsedIEs->content.iePacket.rsnIeLen);
654     UPDATE_APSD (pSite, pFrame);
655     UPDATE_PREAMBLE (pSite, pFrame);
656     UPDATE_AGILITY (pSite, pFrame);
657     UPDATE_RSSI (pSite, pFrame);
658     UPDATE_SNR (pSite, pFrame);
659     UPDATE_RATE (pSite, pFrame);
660         UPDATE_UNKOWN_IE(pScanResultTable, pSite, pFrame->parsedIEs->content.iePacket.pUnknownIe, pFrame->parsedIEs->content.iePacket.unknownIeLen );
661
662     param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
663     siteMgr_getParam (pScanResultTable->hSiteMgr, &param);
664     if (param.content.siteMgrDot11OperationalMode == DOT11_G_MODE)
665     {
666         UPDATE_SLOT_TIME (pSite, pFrame);
667         UPDATE_PROTECTION (pSite, pFrame);
668     }
669
670     scanResultTable_updateRates (hScanResultTable, pSite, pFrame);
671
672     if ((pFrame->parsedIEs->content.iePacket.pDSParamsSet != NULL)  &&
673         (pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel != pFrame->channel))
674     {
675         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_UpdateSiteData: wrong channels, radio channel=%d, frame channel=%d\n", pFrame->channel, pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel);
676     }
677     else
678         UPDATE_CHANNEL (pSite, pFrame , pFrame->channel);
679
680     UPDATE_BSS_TYPE (pSite, pFrame);
681     UPDATE_ATIM_WINDOW (pSite, pFrame);
682     UPDATE_AP_TX_POWER (pSite, pFrame);
683     UPDATE_QOS (pSite, pFrame);
684     UPDATE_BEACON_TIMESTAMP (pScanResultTable, pSite, pFrame);
685     scanResultTable_UpdateWSCParams (pSite, pFrame);
686     siteMgr_UpdatHtParams (pScanResultTable->hSiteMgr, pSite, pFrame->parsedIEs);
687
688     if (BEACON == pFrame->parsedIEs->subType)
689     {
690         /* DTIM is only available in beacons */
691         if (pSite->bssType == BSS_INFRASTRUCTURE)
692         {
693             UPDATE_DTIM_PERIOD (pSite, pFrame);
694         }
695
696         UPDATE_BEACON_MODULATION (pSite, pFrame);
697
698         /* If the BSS type is independent, the beacon & probe modulation are equal,
699             It is important to update this field here for dynamic PBCC algorithm compatibility */
700         if (pSite->bssType == BSS_INDEPENDENT)
701         {
702             UPDATE_PROBE_MODULATION (pSite, pFrame);
703         }
704
705         pSite->bChannelSwitchAnnoncIEFound = (pFrame->parsedIEs->content.iePacket.channelSwitch != NULL)?TI_TRUE:TI_FALSE;
706
707         UPDATE_BEACON_RECV (pSite);
708         UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->beaconBuffer), (pSite->beaconLength), pFrame); 
709     }
710     else if (PROBE_RESPONSE == pFrame->parsedIEs->subType)
711     {
712         UPDATE_PROBE_MODULATION (pSite, pFrame);
713
714         /* If the BSS type is independent, the beacon & probe modulation are equal,
715             It is important to update this field here for dynamic PBCC algorithm compatibility */
716         if (pSite->bssType == BSS_INDEPENDENT)
717             UPDATE_BEACON_MODULATION (pSite, pFrame);
718
719         UPDATE_PROBE_RECV (pSite);
720         UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->probeRespBuffer), (pSite->probeRespLength), pFrame);
721
722         pSite->bChannelSwitchAnnoncIEFound = TI_FALSE;
723     }
724     else
725     {
726         TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_UpdateSiteData: unknown frame sub type %d\n", pFrame->parsedIEs->subType);
727     }
728 }
729
730 /** 
731  * \fn     scanResultTable_updateRates 
732  * \brief  Update a scan result table entry with rates information 
733  * 
734  * Called by the function 'updateSiteInfo()' in order to translate the rates received
735  * in the beacon or probe response to rate used by the driver. Perfoms the following:
736  *    -   Check the rates. validity. If rates are invalid, return
737  *    -   Get the max active rate & max basic rate, if invalid, return
738  *    -   Translate the max active rate and max basic rate from network rates to host rates.
739  *        The max active & max basic rate are used by the driver from now on in all the processes:
740  *        (selection, join, transmission, etc....)
741  * 
742  * \param  hScanResultTable - handle to the scan result table object
743  * \param  pSite - a pointer to the site entry to update 
744  * \param  pFrame - a pointer to the received frame
745  * \return None
746  * \sa     scanResultTable_UpdateSiteData 
747  */ 
748 void scanResultTable_updateRates(TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame)
749 {
750     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
751     TI_UINT8            maxBasicRate = 0, maxActiveRate = 0;
752     TI_UINT32           bitMapExtSupp = 0;
753         TI_UINT32           uMcsSupportedRateMask = 0, uMcsbasicRateMask = 0;
754
755     if (pFrame->parsedIEs->content.iePacket.pRates == NULL)
756     {
757         TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_ERROR, "scanResultTable_updateRates, pRates=NULL, beacon & probeResp are:\n");
758         TRACE_INFO_HEX(pScanResultTable->hReport, (TI_UINT8*)pFrame->parsedIEs->content.iePacket.pRates, pFrame->parsedIEs->content.iePacket.pRates->hdr[1]+2);
759         TRACE_INFO_HEX(pScanResultTable->hReport, (TI_UINT8*)pFrame->parsedIEs->content.iePacket.pRates, pFrame->parsedIEs->content.iePacket.pRates->hdr[1]+2);
760         return;
761     }
762
763     /* Update the rate elements */
764     maxBasicRate = (TI_UINT8)rate_GetMaxBasicFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pRates->rates, 
765                                             pFrame->parsedIEs->content.iePacket.pRates->hdr[1], (ENetRate)maxBasicRate);
766     maxActiveRate = (TI_UINT8)rate_GetMaxActiveFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pRates->rates,
767                                               pFrame->parsedIEs->content.iePacket.pRates->hdr[1], (ENetRate)maxActiveRate);
768
769     if (pFrame->parsedIEs->content.iePacket.pExtRates)
770     {
771         maxBasicRate = (TI_UINT8)rate_GetMaxBasicFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pExtRates->rates,
772                                                 pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1], (ENetRate)maxBasicRate);
773         maxActiveRate = (TI_UINT8)rate_GetMaxActiveFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pExtRates->rates,
774                                                   pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1], (ENetRate)maxActiveRate);
775     }
776
777     if (maxActiveRate == 0)
778     {
779         maxActiveRate = maxBasicRate;
780     }
781
782     /* Now update it from network to host rates */
783     pSite->maxBasicRate = rate_NetToDrv (maxBasicRate);
784     pSite->maxActiveRate = rate_NetToDrv (maxActiveRate);
785     if (pSite->maxActiveRate == DRV_RATE_INVALID)
786             TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_ERROR, "scanResultTable_updateRates: Network To Host Rate failure, no active network rate\n");
787
788     if (pSite->maxBasicRate != DRV_RATE_INVALID)
789     {
790         if (pSite->maxActiveRate != DRV_RATE_INVALID)
791         {
792             pSite->maxActiveRate = TI_MAX (pSite->maxActiveRate, pSite->maxBasicRate);
793         }
794     } else { /* in case some vendors don't specify basic rates */
795         TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_WARNING, "scanResultTable_updateRates: Network To Host Rate failure, no basic network rate");
796         pSite->maxBasicRate = pSite->maxActiveRate;
797     }
798
799     /* build rates bit map */
800     rate_NetStrToDrvBitmap (&pSite->rateMask.supportedRateMask,
801                             pFrame->parsedIEs->content.iePacket.pRates->rates,
802                             pFrame->parsedIEs->content.iePacket.pRates->hdr[1]);
803     rate_NetBasicStrToDrvBitmap (&pSite->rateMask.basicRateMask,
804                                  pFrame->parsedIEs->content.iePacket.pRates->rates,
805                                  pFrame->parsedIEs->content.iePacket.pRates->hdr[1]);
806
807     if (pFrame->parsedIEs->content.iePacket.pExtRates)
808     {
809         rate_NetStrToDrvBitmap (&bitMapExtSupp, 
810                                 pFrame->parsedIEs->content.iePacket.pExtRates->rates,
811                                 pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1]);
812
813         pSite->rateMask.supportedRateMask |= bitMapExtSupp;
814
815         rate_NetBasicStrToDrvBitmap (&bitMapExtSupp, 
816                                      pFrame->parsedIEs->content.iePacket.pExtRates->rates,
817                                      pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1]);
818
819         pSite->rateMask.basicRateMask |= bitMapExtSupp;
820     }
821
822         if (pFrame->parsedIEs->content.iePacket.pHtCapabilities != NULL)
823     {
824         /* MCS build rates bit map */
825         rate_McsNetStrToDrvBitmap (&uMcsSupportedRateMask,
826                                    (pFrame->parsedIEs->content.iePacket.pHtCapabilities->aHtCapabilitiesIe + DOT11_HT_CAPABILITIES_MCS_RATE_OFFSET));
827
828         pSite->rateMask.supportedRateMask |= uMcsSupportedRateMask;
829     }
830
831     if (pFrame->parsedIEs->content.iePacket.pHtInformation != NULL)
832     {
833         /* MCS build rates bit map */
834         rate_McsNetStrToDrvBitmap (&uMcsbasicRateMask,
835                                    (pFrame->parsedIEs->content.iePacket.pHtInformation->aHtInformationIe + DOT11_HT_INFORMATION_MCS_RATE_OFFSET));
836
837         pSite->rateMask.basicRateMask |= uMcsbasicRateMask;
838     }
839 }
840
841 /** 
842  * \fn     scanResultTable_UpdateWSCParams 
843  * \brief  Update a scan result table entry with WSC information 
844  * 
845  * Update a scan result table entry with WSC information
846  * 
847  * \param  pSite - a pointer to the site entry to update 
848  * \param  pFrame - a pointer to the received frame
849  * \return None
850  * \sa     scanResultTable_UpdateSiteData 
851  */ 
852 void scanResultTable_UpdateWSCParams (TSiteEntry *pSite, TScanFrameInfo *pFrame)
853 {
854     /* if the IE is not null => the WSC is on - check which method is supported */
855     if (pFrame->parsedIEs->content.iePacket.WSCParams != NULL)
856     {
857         TI_UINT8    *tlvPtr,*endPtr;
858         TI_UINT16   tlvPtrType,tlvPtrLen,selectedMethod=0;
859     
860         tlvPtr = (TI_UINT8*)pFrame->parsedIEs->content.iePacket.WSCParams->WSCBeaconOrProbIE;
861         endPtr = tlvPtr + pFrame->parsedIEs->content.iePacket.WSCParams->hdr[1] - DOT11_OUI_LEN;
862     
863         do
864         {
865             tlvPtrType = WLANTOHS (WLAN_WORD(tlvPtr));
866     
867             if (tlvPtrType == DOT11_WSC_DEVICE_PASSWORD_ID)
868             {
869                 tlvPtr+=2;
870                 tlvPtr+=2;
871                 selectedMethod = WLANTOHS (WLAN_WORD(tlvPtr));
872                 break;
873             }
874             else
875             {
876                 tlvPtr+=2;
877                 tlvPtrLen = WLANTOHS (WLAN_WORD(tlvPtr));
878                 tlvPtr+=tlvPtrLen+2;
879             }
880         } while ((tlvPtr < endPtr) && (selectedMethod == 0));
881        
882         if (tlvPtr > endPtr)
883         {
884             pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_OFF;
885             return;
886         }
887     
888         if (selectedMethod == DOT11_WSC_DEVICE_PASSWORD_ID_PIN)
889             pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_PIN_METHOD;
890         else if (selectedMethod == DOT11_WSC_DEVICE_PASSWORD_ID_PBC)
891             pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_PBC_METHOD;
892         else 
893             pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_OFF;
894     }
895     else
896     {
897         pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_OFF;
898     }
899 }
900
901 /** 
902  * \fn     scanResultTable_GetNumOfBSSIDInTheList
903  * \brief  Returns the number of BSSID's in the scan result list
904  * 
905  * \param  hScanResultTable - handle to the scan result table
906  * \return The number of BSSID's in the list
907  * \sa scanResultTable_GetBssidSupportedRatesList
908  */ 
909 TI_UINT32 scanResultTable_GetNumOfBSSIDInTheList (TI_HANDLE hScanResultTable)
910 {
911         return ((TScanResultTable*)hScanResultTable)->uCurrentSiteNumber;
912 }
913
914 /** 
915  * \fn     scanResultTable_CalculateBssidListSize
916  * \brief  Calculates the size required for BSSID list storage
917  * 
918  * Calculates the size required for BSSID list storage
919  * 
920  * \param  hScanResultTable - handle to the scan result table object
921  * \param  bAllVarIes - whether to include all variable size IEs
922  * \return The total length required
923  * \sa     scanResultTable_GetBssidList
924  */ 
925 TI_UINT32 scanResultTable_CalculateBssidListSize (TI_HANDLE hScanResultTable, TI_BOOL bAllVarIes)
926 {
927     TScanResultTable    *pScanResultTable = (TScanResultTable*)hScanResultTable;
928     TI_UINT32           uSiteIndex, uSiteLength, uLength = 0;
929     TSiteEntry          *pSiteEntry;
930
931     /* set the length of the list header (sites count) */
932     uLength = sizeof(OS_802_11_BSSID_LIST_EX) - sizeof(OS_802_11_BSSID_EX);
933
934     /* check lengthes of all sites in the table */
935     for (uSiteIndex = 0; uSiteIndex < pScanResultTable->uCurrentSiteNumber; uSiteIndex++)
936     {
937         pSiteEntry = &(pScanResultTable->pTable[ uSiteIndex ]);
938         /* if full list is requested */
939         if (bAllVarIes)
940         {
941             /* set length of all IEs for this site */
942             uSiteLength = sizeof(OS_802_11_BSSID_EX) + sizeof(OS_802_11_FIXED_IEs);
943             /* and add beacon or probe response length */
944             if (TI_TRUE == pSiteEntry->probeRecv)
945             {
946                 uSiteLength += pSiteEntry->probeRespLength;
947             }
948             else
949             {
950                 uSiteLength += pSiteEntry->beaconLength;
951             }
952                      
953         }
954         /* partial list is requested */
955         else
956         {
957             uSiteLength = (sizeof(OS_802_11_BSSID_EX) + sizeof(OS_802_11_FIXED_IEs) +
958                            (pSiteEntry->ssid.len + 2) + (DOT11_MAX_SUPPORTED_RATES + 2) +
959                            + (DOT11_DS_PARAMS_ELE_LEN +2) + pSiteEntry->rsnIeLen + pSiteEntry->unknownIeLen);
960
961             /* QOS_WME information element */
962             if (pSiteEntry->WMESupported)
963             {
964                 /* length of element + header */
965                 uSiteLength += (DOT11_WME_PARAM_ELE_LEN + 2);
966             }
967         }
968
969         /* make sure length is 4 bytes aligned */
970         if (uSiteLength % 4)
971         {
972             uSiteLength += (4 - (uSiteLength % 4));
973         }
974
975         /* add this site length to the total length */
976         uLength += uSiteLength;
977
978         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_calculateBssidListSize: BSSID length=%d on site index %d\n", uSiteLength, uSiteIndex);
979     }
980
981     TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_calculateBssidListSize: total length=%d \n", uLength);
982
983     return uLength;
984 }
985
986 /** 
987  * \fn     scanResultTable_GetBssidList
988  * \brief  Retrieves the site table content
989  * 
990  * Retrieves the site table content
991  * 
992  * \param  hScanResultTable - handle to the scan result table object
993  * \param  pBssidList - pointer to a buffer large enough to hols the BSSID list
994  * \param  plength - length of the supplied buffer, will be overwritten with the actual list length
995  * \param  bAllVarIes - whether to include all variable size IEs
996  * \return None
997  * \sa     scanResultTable_CalculateBssidListSize
998  */ 
999 TI_STATUS scanResultTable_GetBssidList (TI_HANDLE hScanResultTable, 
1000                                         OS_802_11_BSSID_LIST_EX *pBssidList, 
1001                                         TI_UINT32 *pLength, 
1002                                         TI_BOOL bAllVarIes)
1003 {
1004     TScanResultTable        *pScanResultTable = (TScanResultTable*)hScanResultTable;
1005     TI_UINT32                uLength, uSiteIndex, rsnIndex, rsnIeLength, len, firstOFDMloc = 0;
1006     TSiteEntry              *pSiteEntry;
1007     OS_802_11_BSSID_EX      *pBssid;
1008     OS_802_11_FIXED_IEs     *pFixedIes;
1009     OS_802_11_VARIABLE_IEs  *pVarIes;
1010     TI_UINT8                *pData;
1011
1012     TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList called, pBssidList= 0x%p, pLength=%d\n", pBssidList, *pLength);
1013
1014     /* verify the supplied length is enough */
1015     uLength = scanResultTable_CalculateBssidListSize (hScanResultTable, bAllVarIes);
1016     if (uLength > *pLength)
1017     {
1018         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_GetBssidList: received length %d, insufficient to hold list of size %d\n", *pLength, uLength);
1019         *pLength = uLength;
1020         return TI_NOK;
1021     }
1022 #ifdef TI_DBG
1023     else
1024     {
1025         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: supplied length: %d, required length: %d\n", *pLength, uLength);
1026     }
1027 #endif
1028
1029     /* Nullify number of items in the BSSID list */
1030     pBssidList->NumberOfItems = 0;
1031
1032     /* set length to list header size (only list count) */
1033     uLength = sizeof(OS_802_11_BSSID_LIST_EX) - sizeof(OS_802_11_BSSID_EX);
1034
1035     /* set data pointer to first item in list */
1036     pData = (TI_UINT8*)&(pBssidList->Bssid[0]);
1037
1038     for (uSiteIndex = 0; uSiteIndex < pScanResultTable->uCurrentSiteNumber; uSiteIndex++)
1039     {
1040         /* set BSSID entry pointer to current location in buffer */
1041         pBssid = (OS_802_11_BSSID_EX*)pData;
1042
1043         /* set pointer to site entry */
1044         pSiteEntry = &(pScanResultTable->pTable[ uSiteIndex ]);
1045
1046         TRACE7(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: copying entry at index %d, BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", uSiteIndex, pSiteEntry->bssid[ 0 ], pSiteEntry->bssid[ 1 ], pSiteEntry->bssid[ 2 ], pSiteEntry->bssid[ 3 ], pSiteEntry->bssid[ 4 ], pSiteEntry->bssid[ 5 ]);
1047
1048         /* start copy stuff: */
1049         /* MacAddress */
1050         MAC_COPY (pBssid->MacAddress, pSiteEntry->bssid);
1051         
1052         /* Capabilities */
1053         pBssid->Capabilities = pSiteEntry->capabilities;
1054
1055         /* SSID */
1056         os_memoryZero (pScanResultTable->hOS, &(pBssid->Ssid.Ssid), MAX_SSID_LEN);
1057         if (pSiteEntry->ssid.len > MAX_SSID_LEN)
1058         {
1059             pSiteEntry->ssid.len = MAX_SSID_LEN;
1060         }
1061         os_memoryCopy (pScanResultTable->hOS, 
1062                        (void *)pBssid->Ssid.Ssid, 
1063                        (void *)pSiteEntry->ssid.str, 
1064                        pSiteEntry->ssid.len);
1065         pBssid->Ssid.SsidLength = pSiteEntry->ssid.len;
1066
1067         /* privacy */
1068         pBssid->Privacy = pSiteEntry->privacy;
1069
1070         /* RSSI */
1071         pBssid->Rssi = pSiteEntry->rssi;
1072
1073         pBssid->Configuration.Length = sizeof(OS_802_11_CONFIGURATION);
1074         pBssid->Configuration.BeaconPeriod = pSiteEntry->beaconInterval;
1075         pBssid->Configuration.ATIMWindow = pSiteEntry->atimWindow;
1076         pBssid->Configuration.Union.channel = Chan2Freq(pSiteEntry->channel);
1077
1078         if  (pSiteEntry->bssType == BSS_INDEPENDENT)
1079             pBssid->InfrastructureMode = os802_11IBSS;
1080         else
1081             pBssid->InfrastructureMode = os802_11Infrastructure;
1082         /* Supported Rates */
1083         os_memoryZero (pScanResultTable->hOS, (void *)pBssid->SupportedRates, sizeof(OS_802_11_RATES_EX));
1084         rate_DrvBitmapToNetStr (pSiteEntry->rateMask.supportedRateMask,
1085                                 pSiteEntry->rateMask.basicRateMask,
1086                                 (TI_UINT8*)pBssid->SupportedRates,
1087                                 &len, 
1088                                 &firstOFDMloc);
1089
1090         /* set network type acording to band and rates */
1091         if (RADIO_BAND_2_4_GHZ == pSiteEntry->eBand)
1092         {
1093             if (firstOFDMloc == len)
1094             {
1095                 pBssid->NetworkTypeInUse = os802_11DS;
1096             } else {
1097                 pBssid->NetworkTypeInUse = os802_11OFDM24;
1098             }
1099         }
1100         else
1101         {
1102             pBssid->NetworkTypeInUse = os802_11OFDM5;
1103         }
1104
1105         /* start copy IE's: first nullify length */
1106         pBssid->IELength = 0;
1107
1108         /* copy fixed IEs from site entry */
1109         pFixedIes = (OS_802_11_FIXED_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
1110         os_memoryCopy (pScanResultTable->hOS, (void*)pFixedIes->TimeStamp, 
1111                        &(pSiteEntry->tsfTimeStamp[ 0 ]), TIME_STAMP_LEN);
1112         pFixedIes->BeaconInterval = pSiteEntry->beaconInterval;
1113         pFixedIes->Capabilities = pSiteEntry->capabilities;
1114         pBssid->IELength += sizeof(OS_802_11_FIXED_IEs);
1115
1116         /* set pointer for variable length IE's */
1117         pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
1118
1119         if (!bAllVarIes)
1120         {   /* copy only some variable IEs */
1121
1122             /* copy SSID */
1123             pVarIes->ElementID = SSID_IE_ID;
1124             pVarIes->Length = pSiteEntry->ssid.len;
1125             os_memoryCopy (pScanResultTable->hOS, 
1126                            (void *)pVarIes->data, 
1127                            (void *)pSiteEntry->ssid.str, 
1128                            pSiteEntry->ssid.len);
1129             pBssid->IELength += (pVarIes->Length + 2);
1130
1131             /* copy RATES */
1132             pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
1133             pVarIes->ElementID = SUPPORTED_RATES_IE_ID;
1134             rate_DrvBitmapToNetStr (pSiteEntry->rateMask.supportedRateMask, 
1135                                     pSiteEntry->rateMask.basicRateMask,
1136                                     (TI_UINT8 *)pVarIes->data, 
1137                                     &len, 
1138                                     &firstOFDMloc);
1139             pVarIes->Length = len;
1140             pBssid->IELength += (pVarIes->Length + 2);
1141
1142             /* copy DS */
1143             pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
1144             pVarIes->ElementID = DS_PARAMETER_SET_IE_ID;
1145             pVarIes->Length = DOT11_DS_PARAMS_ELE_LEN;
1146             os_memoryCopy (pScanResultTable->hOS, (void *)pVarIes->data, 
1147                            &(pSiteEntry->channel), DOT11_DS_PARAMS_ELE_LEN);
1148             pBssid->IELength += (pVarIes->Length + 2);
1149
1150             /* copy RSN information elements */
1151             if (0 < pSiteEntry->rsnIeLen)
1152             {
1153                 rsnIeLength = 0;
1154                 for (rsnIndex=0; rsnIndex < MAX_RSN_IE && pSiteEntry->pRsnIe[ rsnIndex ].hdr[1] > 0; rsnIndex++)
1155                 {
1156                     pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength + rsnIeLength ]);
1157                     pVarIes->ElementID = pSiteEntry->pRsnIe[ rsnIndex ].hdr[0];
1158                     pVarIes->Length = pSiteEntry->pRsnIe[ rsnIndex ].hdr[1];
1159                     os_memoryCopy (pScanResultTable->hOS, (void *)pVarIes->data, 
1160                                    (void *)pSiteEntry->pRsnIe[ rsnIndex ].rsnIeData, 
1161                                    pSiteEntry->pRsnIe[ rsnIndex ].hdr[1]);
1162                     rsnIeLength += pSiteEntry->pRsnIe[ rsnIndex ].hdr[1] + 2;
1163                 }
1164                 pBssid->IELength += pSiteEntry->rsnIeLen;
1165             }
1166
1167             /* QOS_WME/XCC */
1168             if (TI_TRUE == pSiteEntry->WMESupported)
1169             {
1170                 /* oui */
1171                 TI_UINT8            ouiWME[3] = {0x50, 0xf2, 0x01};
1172                 dot11_WME_PARAM_t   *pWMEParams; 
1173
1174                 /* fill in the general element  parameters */
1175                 pVarIes =  (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
1176                 pVarIes->ElementID = DOT11_WME_ELE_ID;
1177                 pVarIes->Length = DOT11_WME_PARAM_ELE_LEN;
1178
1179                 /* fill in the specific element  parameters */
1180                 pWMEParams = (dot11_WME_PARAM_t*)pVarIes;
1181                 os_memoryCopy (pScanResultTable->hOS, (void *)pWMEParams->OUI, ouiWME, 3);
1182                 pWMEParams->OUIType = dot11_WME_OUI_TYPE;
1183                 pWMEParams->OUISubType = dot11_WME_OUI_SUB_TYPE_PARAMS_IE;
1184                 pWMEParams->version = dot11_WME_VERSION;
1185                 pWMEParams->ACInfoField = dot11_WME_ACINFO_MASK & pSiteEntry->lastWMEParameterCnt;
1186
1187                 /* fill in the data  */
1188                 os_memoryCopy (pScanResultTable->hOS, &(pWMEParams->WME_ACParameteres),
1189                                &(pSiteEntry->WMEParameters), sizeof(dot11_ACParameters_t));
1190
1191
1192                 /* update the general length */
1193                 pBssid->IELength += (pVarIes->Length + 2);
1194             }
1195
1196                         /* Copy the unknown IEs */
1197                         if ( 0 < pSiteEntry->unknownIeLen  ) {
1198                                         os_memoryCopy (pScanResultTable->hOS, (void *)(&pBssid->IEs[ pBssid->IELength ]),
1199                                                                    (void *)pSiteEntry->pUnknownIe,
1200                                                                    pSiteEntry->unknownIeLen );
1201                                         pBssid->IELength += pSiteEntry->unknownIeLen;
1202                         }
1203
1204         }
1205         else
1206         {   /* Copy all variable IEs */
1207             if (pSiteEntry->probeRecv)
1208             {
1209                 /* It looks like it never happens. Anyway decided to check */
1210                 if ( pSiteEntry->probeRespLength > MAX_BEACON_BODY_LENGTH )
1211                    /* it may have sense to check the Len here for 0 or MIN_BEACON_BODY_LENGTH also */
1212                 {
1213                     TRACE2( pScanResultTable->hReport, REPORT_SEVERITY_ERROR,
1214                          "scanResultTable_GetBssidList. pSiteEntry->probeRespLength=%d exceeds the limit %d\n",
1215                          pSiteEntry->probeRespLength, MAX_BEACON_BODY_LENGTH);
1216                     handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
1217                     return TI_NOK;
1218                 }
1219                 os_memoryCopy (pScanResultTable->hOS, pVarIes, 
1220                                pSiteEntry->probeRespBuffer, pSiteEntry->probeRespLength);
1221                 pBssid->IELength += pSiteEntry->probeRespLength;
1222             }
1223             else
1224             {
1225                 /* It looks like it never happens. Anyway decided to check */
1226                 if ( pSiteEntry->beaconLength > MAX_BEACON_BODY_LENGTH )
1227                    /* it may have sense to check the Len here for 0 or MIN_BEACON_BODY_LENGTH also */
1228                 {
1229                     TRACE2( pScanResultTable->hReport, REPORT_SEVERITY_ERROR,
1230                          "scanResultTable_GetBssidList. pSiteEntry->beaconLength=%d exceeds the limit %d\n",
1231                          pSiteEntry->beaconLength, MAX_BEACON_BODY_LENGTH);
1232                     handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
1233                     return TI_NOK;
1234                 }
1235                 os_memoryCopy (pScanResultTable->hOS, pVarIes, 
1236                                pSiteEntry->beaconBuffer, pSiteEntry->beaconLength);
1237                 pBssid->IELength += pSiteEntry->beaconLength;
1238             }
1239         }
1240
1241         /* -1 to remove the IEs[1] placeholder in OS_802_11_BSSID_EX which is taken into account in pBssid->IELength */
1242         pBssid->Length = sizeof(OS_802_11_BSSID_EX) + pBssid->IELength - 1;
1243
1244         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: before alignment fix, IEs length: %d, BSSID length %d\n", pBssid->IELength, pBssid->Length);
1245
1246         /* make sure length is 4 bytes aligned */
1247         if (pBssid->Length % 4)
1248         {
1249             pBssid->Length += (4 - (pBssid->Length % 4));
1250         }
1251
1252         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: after alignment fix, IEs length: %d, BSSID length %d\n", pBssid->IELength, pBssid->Length);
1253
1254         pData += pBssid->Length;
1255         uLength += pBssid->Length;
1256
1257         TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: current length: %d\n", uLength);
1258     }
1259
1260     pBssidList->NumberOfItems = pScanResultTable->uCurrentSiteNumber;
1261     *pLength = uLength;
1262
1263     TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: total length: %d, number of items: %d\n", uLength, pBssidList->NumberOfItems);
1264
1265     return TI_OK;
1266 }
1267
1268
1269 /** 
1270  * \fn     scanResultTable_GetBssidSupportedRatesList
1271  * \brief  Retrieves the Rate table corresponding with the site
1272  * table
1273  * 
1274  * 
1275  * \param  hScanResultTable - handle to the scan result table object
1276  * \param  pRateList - pointer to a buffer large enough to hols
1277  * the rate list
1278  * \param  pLength - length of the supplied buffer,
1279  * \return TI_STATUS
1280  * \sa scanResultTable_GetBssidSupportedRatesList
1281  */ 
1282 TI_STATUS scanResultTable_GetBssidSupportedRatesList (TI_HANDLE hScanResultTable,
1283                                                                                                           OS_802_11_N_RATES *pRateList,
1284                                                                                                           TI_UINT32 *pLength)
1285 {
1286     TScanResultTable        *pScanResultTable = (TScanResultTable*)hScanResultTable;
1287         TSiteEntry              *pSiteEntry;
1288     TI_UINT32                uSiteIndex, firstOFDMloc = 0;
1289         TI_UINT32                requiredLength;
1290         OS_802_11_N_RATES               *pCurrRateString;
1291
1292     TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidSupportedRatesList called");
1293
1294     /* Verify the supplied length is enough*/
1295         requiredLength = pScanResultTable->uCurrentSiteNumber*sizeof(OS_802_11_N_RATES);
1296         if (requiredLength > *pLength)
1297     {
1298         TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_GetBssidSupportedRatesList: received length %d, insufficient to hold list of size %d\n", *pLength, requiredLength);
1299         *pLength = requiredLength;
1300         return TI_NOK;
1301     }
1302
1303     /* Create the rate list*/
1304     for (uSiteIndex = 0; uSiteIndex < pScanResultTable->uCurrentSiteNumber; uSiteIndex++)
1305     {
1306                 pCurrRateString = &(pRateList[uSiteIndex]);
1307         pSiteEntry = &(pScanResultTable->pTable[ uSiteIndex ]);
1308
1309         /* Supported Rates */
1310         os_memoryZero (pScanResultTable->hOS, (void *)pCurrRateString, sizeof(OS_802_11_N_RATES));
1311         rate_DrvBitmapToNetStrIncluding11n (pSiteEntry->rateMask.supportedRateMask,
1312                                                                                                   pSiteEntry->rateMask.basicRateMask,
1313                                                                                                   (TI_UINT8*)pCurrRateString,
1314                                                                                                   &firstOFDMloc);
1315         }
1316
1317     return TI_OK;
1318 }
1319
1320
1321 /***********************************************************************
1322  *                        siteMgr_CheckRxSignalValidity
1323  ***********************************************************************
1324 DESCRIPTION: Called by the scanResultTable_UpdateEntry when receiving managment frame 
1325                 Find the ste in the site table and validate that the 
1326                 RSSI of that site signal is not lower then -80DB + not lower
1327                 then the exising site RSSI
1328
1329
1330 INPUT:      hSiteMgr    -   site mgr handle.
1331             rxLevel     -   Rx level the frame received in
1332             bssid       -   BSSID of the frame
1333
1334 OUTPUT:
1335
1336 RETURN:     TI_OK / TI_NOK
1337
1338 ************************************************************************/
1339 /** 
1340  * \fn     scanResultTable_CheckRxSignalValidity
1341  * \brief  return the state of the table to its state after scan
1342  * 
1343  * Called by the scanResultTable_UpdateEntry when receiving managment frame   
1344  * validate that the RSSI of that site signal is not lower then then the exising site RSSI.
1345  * validate that the channel in correct.                                             
1346  * 
1347  * \param  pScanResultTable - scan result table object
1348  * \param  pSite - entry from the table
1349  * \param  rssi - RSSI level at which frame was received 
1350  * \param  channel - channel on which the frame was received 
1351  * \return None
1352  * \sa
1353  */ 
1354 static TI_STATUS scanResultTable_CheckRxSignalValidity(TScanResultTable *pScanResultTable, TSiteEntry *pSite, TI_INT8 rxLevel, TI_UINT8 channel)
1355 {
1356      if ((channel != pSite->channel) &&
1357          (rxLevel < pSite->rssi))
1358      {   /* Ignore wrong packets with lower RSSI that were detect as
1359          ripples from different channels */
1360          TRACE4(pScanResultTable->hReport, REPORT_SEVERITY_WARNING, "scanResultTable_CheckRxSignalValidity:Rx RSSI =%d, on channel=%d, is lower then given RSSI =%d on channel=%d, dropping it.\n", rxLevel, channel, pSite->rssi, pSite->channel);
1361          return TI_NOK;
1362      }
1363
1364      return TI_OK;
1365 }
1366
1367
1368