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 */
scanResultTable_Create(TI_HANDLE hOS,TI_UINT32 uEntriesNumber)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 */
scanResultTable_Init(TI_HANDLE hScanResultTable,TStadHandlesList * pStadHandles,EScanResultTableClear eClearTable)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 */
scanResultTable_Destroy(TI_HANDLE hScanResultTable)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 */
scanResultTable_SetSraThreshold(TI_HANDLE hScanResultTable,TI_UINT32 uSraThreshold)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 */
scanResultTable_UpdateEntry(TI_HANDLE hScanResultTable,TMacAddr * pBssid,TScanFrameInfo * pFrame)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 */
scanResultTable_SetStableState(TI_HANDLE hScanResultTable)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 */
scanResultTable_GetFirst(TI_HANDLE hScanResultTable)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 */
scanResultTable_GetNext(TI_HANDLE hScanResultTable)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 */
scanResultTable_GetBySsidBssidPair(TI_HANDLE hScanResultTable,TSsid * pSsid,TMacAddr * pBssid)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 */
scanResultTable_FindHidden(TScanResultTable * pScanResultTable,TI_UINT32 * uHiddenSsidIndex)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 */
scanResultTable_PerformAging(TI_HANDLE hScanResultTable)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 */
scanResultTable_RemoveEntry(TI_HANDLE hScanResultTable,TI_UINT32 uIndex)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 */
scanResultTbale_AllocateNewEntry(TI_HANDLE hScanResultTable)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 */
scanResultTable_UpdateSiteData(TI_HANDLE hScanResultTable,TSiteEntry * pSite,TScanFrameInfo * pFrame)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, ¶m);
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 */
scanResultTable_updateRates(TI_HANDLE hScanResultTable,TSiteEntry * pSite,TScanFrameInfo * pFrame)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 */
scanResultTable_UpdateWSCParams(TSiteEntry * pSite,TScanFrameInfo * pFrame)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 */
scanResultTable_GetNumOfBSSIDInTheList(TI_HANDLE hScanResultTable)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 */
scanResultTable_CalculateBssidListSize(TI_HANDLE hScanResultTable,TI_BOOL bAllVarIes)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 */
scanResultTable_GetBssidList(TI_HANDLE hScanResultTable,OS_802_11_BSSID_LIST_EX * pBssidList,TI_UINT32 * pLength,TI_BOOL bAllVarIes)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 */
scanResultTable_GetBssidSupportedRatesList(TI_HANDLE hScanResultTable,OS_802_11_N_RATES * pRateList,TI_UINT32 * pLength)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 */
scanResultTable_CheckRxSignalValidity(TScanResultTable * pScanResultTable,TSiteEntry * pSite,TI_INT8 rxLevel,TI_UINT8 channel)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
1369