1 /*
2 * scanResultTable.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /** \file 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 UPDATE_BSSID(pSite, pFrame) MAC_COPY((pSite)->bssid, *((pFrame)->bssId))
52 #define UPDATE_BAND(pSite, pFrame) (pSite)->eBand = (pFrame)->band
53 #define UPDATE_BEACON_INTERVAL(pSite, pFrame) pSite->beaconInterval = (pFrame)->parsedIEs->content.iePacket.beaconInerval
54 #define UPDATE_CAPABILITIES(pSite, pFrame) pSite->capabilities = (pFrame)->parsedIEs->content.iePacket.capabilities
55 #define UPDATE_PRIVACY(pSite, pFrame) pSite->privacy = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TI_TRUE : TI_FALSE
56 #define UPDATE_AGILITY(pSite, pFrame) pSite->agility = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_AGILE_SHIFT) & CAP_AGILE_MASK) ? TI_TRUE : TI_FALSE
57 #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
58 #define UPDATE_PROTECTION(pSite, pFrame) pSite->useProtection = ((pFrame)->parsedIEs->content.iePacket.useProtection)
59
60 #define UPDATE_SSID(pScanResultTable, pSite, pFrame) if ((pFrame)->parsedIEs->content.iePacket.pSsid != NULL) { \
61 pSite->ssid.len = (pFrame)->parsedIEs->content.iePacket.pSsid->hdr[1]; \
62 os_memoryCopy(pScanResultTable->hOS, \
63 (void *)pSite->ssid.str, \
64 (void *)(pFrame)->parsedIEs->content.iePacket.pSsid->serviceSetId, \
65 (pFrame)->parsedIEs->content.iePacket.pSsid->hdr[1]); \
66 if (pSite->ssid.len < MAX_SSID_LEN) \
67 pSite->ssid.str[pSite->ssid.len] = '\0';}
68
69 #define UPDATE_CHANNEL(pSite, pFrame, rxChannel) if ((pFrame)->parsedIEs->content.iePacket.pDSParamsSet == NULL) \
70 pSite->channel = rxChannel; \
71 else \
72 pSite->channel = (pFrame)->parsedIEs->content.iePacket.pDSParamsSet->currChannel;
73 #define UPDATE_DTIM_PERIOD(pSite, pFrame) if ((pFrame)->parsedIEs->content.iePacket.pTIM != NULL) \
74 pSite->dtimPeriod = (pFrame)->parsedIEs->content.iePacket.pTIM->dtimPeriod
75 #define UPDATE_ATIM_WINDOW(pSite, pFrame) if ((pFrame)->parsedIEs->content.iePacket.pIBSSParamsSet != NULL) \
76 pSite->atimWindow = (pFrame)->parsedIEs->content.iePacket.pIBSSParamsSet->atimWindow
77 #define UPDATE_AP_TX_POWER(pSite, pFrame) if ((pFrame)->parsedIEs->content.iePacket.TPCReport != NULL) \
78 pSite->APTxPower = (pFrame)->parsedIEs->content.iePacket.TPCReport->transmitPower
79 #define UPDATE_BSS_TYPE(pSite, pFrame) pSite->bssType = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_ESS_SHIFT) & CAP_ESS_MASK) ? BSS_INFRASTRUCTURE : BSS_INDEPENDENT
80 #define UPDATE_RSN_IE(pScanResultTable, pSite, pNewRsnIe, newRsnIeLen) if ((pNewRsnIe) != NULL) { \
81 TI_UINT8 length=0, index=0;\
82 dot11_RSN_t *pTempRsnIe = (pNewRsnIe); \
83 (pSite)->rsnIeLen = (newRsnIeLen);\
84 while ((length < (pSite)->rsnIeLen) && (index < MAX_RSN_IE)) {\
85 (pSite)->pRsnIe[index].hdr[0] = pTempRsnIe->hdr[0];\
86 (pSite)->pRsnIe[index].hdr[1] = pTempRsnIe->hdr[1];\
87 os_memoryCopy(pScanResultTable->hOS, (void *)(pSite)->pRsnIe[index].rsnIeData, (void *)pTempRsnIe->rsnIeData, pTempRsnIe->hdr[1]);\
88 length += (pTempRsnIe->hdr[1]+2); \
89 pTempRsnIe += 1; \
90 index++;}\
91 } \
92 else {pSite->rsnIeLen = 0;}
93 #define UPDATE_BEACON_TIMESTAMP(pScanResultTable, pSite, pFrame) os_memoryCopy(pScanResultTable->hOS, pSite->tsfTimeStamp, (void *)(pFrame)->parsedIEs->content.iePacket.timestamp, TIME_STAMP_LEN)
94
95 /* Updated from beacons */
96 #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
97 #define UPDATE_BEACON_RECV(pSite) pSite->beaconRecv = TI_TRUE
98
99 /* Updated from probes */
100 #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
101 #define UPDATE_PROBE_RECV(pSite) pSite->probeRecv = TI_TRUE
102 #define UPDATE_APSD(pSite, pFrame) if ((pFrame)->parsedIEs->content.iePacket.WMEParams == NULL) \
103 (pSite)->APSDSupport = ((((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_APSD_SHIFT) & CAP_APSD_MASK) ? TI_TRUE : TI_FALSE); \
104 else \
105 pSite->APSDSupport = (((((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_APSD_SHIFT) & CAP_APSD_MASK) ? TI_TRUE : TI_FALSE) || \
106 ((((pFrame)->parsedIEs->content.iePacket.WMEParams->ACInfoField >> AP_QOS_INFO_UAPSD_SHIFT) & AP_QOS_INFO_UAPSD_MASK) ? TI_TRUE : TI_FALSE));
107 #define UPDATE_PREAMBLE(pSite, pFrame) { (pSite)->currentPreambleType = (((pFrame)->parsedIEs->content.iePacket.capabilities >> CAP_PREAMBLE_SHIFT) & CAP_PREAMBLE_MASK) ? PREAMBLE_SHORT : PREAMBLE_LONG; \
108 (pSite)->barkerPreambleType = (pFrame)->parsedIEs->content.iePacket.barkerPreambleMode; }
109 #define UPDATE_QOS(pSite, pFrame) if ( ((pFrame)->parsedIEs->content.iePacket.WMEParams != NULL) && \
110 (((((pFrame)->parsedIEs->content.iePacket.WMEParams->ACInfoField) & dot11_WME_ACINFO_MASK) != pSite->lastWMEParameterCnt) || (!pSite->WMESupported)) ) \
111 pSite->WMESupported = TI_TRUE; \
112 else \
113 pSite->WMESupported = TI_FALSE;
114 #define UPDATE_FRAME_BUFFER(pScanResultTable, pBuffer, uLength, pFrame) if (pFrame->bufferLength < MAX_BEACON_BODY_LENGTH) \
115 { \
116 os_memoryCopy (pScanResultTable->hOS, pBuffer, pFrame->buffer, pFrame->bufferLength); \
117 uLength = pFrame->bufferLength; \
118 }
119 #define UPDATE_RSSI(pSite, pFrame) (pSite)->rssi = (pFrame)->rssi;
120 #define UPDATE_SNR(pSite, pFrame) (pSite)->snr = (pFrame)->snr;
121 #define UPDATE_RATE(pSite, pFrame) if ((DRV_RATE_1M <= (pFrame)->rate) && (DRV_RATE_54M <= (pFrame)->rate)) \
122 (pSite)->rxRate = (pFrame)->rate;
123
124
125 typedef struct
126 {
127 TI_HANDLE hOS; /**< Handle to the OS object */
128 TI_HANDLE hReport; /**< handle to the report object */
129 TI_HANDLE hSiteMgr; /**< Handle to the site manager object */
130 TSiteEntry *pTable; /**< site table */
131 TI_UINT32 uCurrentSiteNumber; /**< number of sites currently in the table */
132 TI_UINT32 uIterator; /**< table iterator used for getFirst / getNext */
133 TI_BOOL bStable; /**< table status (updating / stable) */
134 } TScanResultTable;
135
136 static TSiteEntry *scanResultTbale_AllocateNewEntry (TI_HANDLE hScanResultTable);
137 static void scanResultTable_UpdateSiteData (TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame);
138 static void scanResultTable_updateRates(TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame);
139 static void scanResultTable_UpdateWSCParams (TSiteEntry *pSite, TScanFrameInfo *pFrame);
140 static TI_STATUS scanResultTable_CheckRxSignalValidity(TScanResultTable *pScanResultTable, siteEntry_t *pSite, TI_INT8 rxLevel, TI_UINT8 channel);
141
142
143 /**
144 * \fn scanResultTable_Create
145 * \brief Create a scan result table object.
146 *
147 * Create a scan result table object. Allocate system resources.
148 *
149 * \note
150 * \param hOS - handle to the OS object
151 * \return Handle to the newly created scan result table object, NULL if an error occured.
152 * \sa scanResultTable_Init, scanResultTable_Destroy
153 */
scanResultTable_Create(TI_HANDLE hOS)154 TI_HANDLE scanResultTable_Create (TI_HANDLE hOS)
155 {
156 TScanResultTable *pScanResultTable = NULL;
157
158 /* Allocate object storage */
159 pScanResultTable = (TScanResultTable*)os_memoryAlloc (hOS, sizeof(TScanResultTable));
160 if (NULL != pScanResultTable)
161 {
162 pScanResultTable->hOS = hOS;
163 }
164
165 /* allocate memory for sites' data */
166 pScanResultTable->pTable =
167 (TSiteEntry *)os_memoryAlloc (pScanResultTable->hOS, sizeof (TSiteEntry) * TABLE_ENTRIES_NUMBER);
168 if (NULL == pScanResultTable->pTable)
169 {
170 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_ERROR ,
171 "scanResultTable_Create: Unable to allocate memory for %d entries of %d bytes\n",
172 TABLE_ENTRIES_NUMBER, sizeof (TSiteEntry));
173 return NULL;
174 }
175
176 return (TI_HANDLE)pScanResultTable;
177 }
178
179 /**
180 * \fn scanResultTable_Init
181 * \brief Initializes the scan result table object
182 *
183 * Initializes the scan result table object. Set handles to other objects.
184 *
185 * \param hScanResultTable - handle to the scan result table object
186 * \param pStadHandles - modules handles table
187 * \return None
188 * \sa scanResultTable_Create
189 */
scanResultTable_Init(TI_HANDLE hScanResultTable,TStadHandlesList * pStadHandles)190 void scanResultTable_Init (TI_HANDLE hScanResultTable, TStadHandlesList *pStadHandles)
191 {
192 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
193
194 /* set handles to other modules */
195 pScanResultTable->hReport = pStadHandles->hReport;
196 pScanResultTable->hSiteMgr = pStadHandles->hSiteMgr;
197
198 /* initialize other parameters */
199 pScanResultTable->uCurrentSiteNumber = 0;
200 pScanResultTable->bStable = TI_TRUE;
201 pScanResultTable->uIterator = 0;
202 }
203
204
205 /**
206 * \fn scanResultTable_Destroy
207 * \brief Destroys the scan result table object
208 *
209 * Destroys the scan result table object. Release system resources
210 *
211 * \param hScanResultTable - handle to the scan result table object
212 * \return None
213 * \sa scanResultTable_Create
214 */
scanResultTable_Destroy(TI_HANDLE hScanResultTable)215 void scanResultTable_Destroy (TI_HANDLE hScanResultTable)
216 {
217 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
218
219 /* if the table memory has already been allocated */
220 if (NULL != pScanResultTable->pTable)
221 {
222 /* free table memory */
223 os_memoryFree (pScanResultTable->hOS, (void*)pScanResultTable->pTable,
224 sizeof (TSiteEntry) * TABLE_ENTRIES_NUMBER);
225 }
226
227 /* free scan result table object memeory */
228 os_memoryFree (pScanResultTable->hOS, (void*)hScanResultTable, sizeof (TScanResultTable));
229 }
230
231 /**
232 * \fn scanResultTable_UpdateEntry
233 * \brief Update or insert a site data.
234 *
235 * Update a site's data in the table if it already exists, or create an antry if the site doesn't exist.
236 * If the table is in stable state, will move it to updating state and clear its contents.
237 *
238 * \param hScanResultTable - handle to the scan result table object
239 * \param pBssid - a pointer to the site BSSID
240 * \param pframe - a pointer to the received frame data
241 * \return TI_OK if entry was inseretd or updated successfuly, TI_NOK if table is full
242 * \sa scanResultTable_SetStableState
243 */
scanResultTable_UpdateEntry(TI_HANDLE hScanResultTable,TMacAddr * pBssid,TScanFrameInfo * pFrame)244 TI_STATUS scanResultTable_UpdateEntry (TI_HANDLE hScanResultTable, TMacAddr *pBssid, TScanFrameInfo* pFrame)
245 {
246 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
247 TSiteEntry *pSite;
248 TSsid tTempSsid;
249
250 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 ]);
251
252 /* check if the table is in stable state */
253 if (TI_TRUE == pScanResultTable->bStable)
254 {
255 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_UpdateEntry: table is stable, clearing table and moving to updating state\n");
256 /* move the table to updating state */
257 pScanResultTable->bStable = TI_FALSE;
258 /* and clear its contents */
259 pScanResultTable->uCurrentSiteNumber = 0;
260 }
261
262 /* use temporary SSID structure */
263 if (NULL == pFrame->parsedIEs->content.iePacket.pSsid)
264 return TI_NOK;
265 tTempSsid.len = pFrame->parsedIEs->content.iePacket.pSsid->hdr[1];
266 os_memoryCopy(pScanResultTable->hOS, (void *)&(tTempSsid.str[ 0 ]),
267 (void *)&(pFrame->parsedIEs->content.iePacket.pSsid->serviceSetId[ 0 ]),
268 tTempSsid.len);
269 if (MAX_SSID_LEN > tTempSsid.len)
270 {
271 tTempSsid.str[ tTempSsid.len ] ='\0';
272 }
273
274 /* check if the SSID:BSSID pair already exists in the table */
275 pSite = scanResultTable_GetBySsidBssidPair (hScanResultTable, &tTempSsid ,pBssid);
276 if (NULL != pSite)
277 {
278 if (TI_NOK != scanResultTable_CheckRxSignalValidity(pScanResultTable, pSite, pFrame->rssi, pFrame->channel))
279 {
280 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_UpdateEntry: entry already exists, updating\n");
281 /* BSSID exists: update its data */
282 scanResultTable_UpdateSiteData (hScanResultTable, pSite, pFrame);
283 }
284 }
285 else
286 {
287 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_UpdateEntry: entry doesn't exist, allocating a new entry\n");
288 /* BSSID doesn't exist: allocate a new entry for it */
289 pSite = scanResultTbale_AllocateNewEntry (hScanResultTable);
290 if (NULL == pSite)
291 {
292 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 ]);
293 return TI_NOK;
294 }
295
296 /* and update its data */
297 scanResultTable_UpdateSiteData (hScanResultTable,
298 pSite,
299 pFrame);
300 }
301
302 return TI_OK;
303 }
304
305 /**
306 * \fn scanResultTable_SetStableState
307 * \brief Moves the table to stable state
308 *
309 * Moves the table to stable state. Also clears the tabel contents if required.
310 *
311 * \param hScanResultTable - handle to the scan result table object
312 * \return None
313 * \sa scanResultTable_UpdateEntry
314 */
scanResultTable_SetStableState(TI_HANDLE hScanResultTable)315 void scanResultTable_SetStableState (TI_HANDLE hScanResultTable)
316 {
317 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
318
319 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_SetStableState: setting stable state\n");
320
321 /* if also asked to clear the table, if it is at Stable mode means that no results were received, clear it! */
322 if (TI_TRUE == pScanResultTable->bStable)
323 {
324 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_SetStableState: also clearing table contents\n");
325
326 pScanResultTable->uCurrentSiteNumber = 0;
327 }
328
329 /* set stable state */
330 pScanResultTable->bStable = TI_TRUE;
331
332 }
333
334 /**
335 * \fn scanResultTable_GetFirst
336 * \brief Retrieves the first entry in the table
337 *
338 * Retrieves the first entry in the table
339 *
340 * \param hScanResultTable - handle to the scan result table object
341 * \return A pointer to the first entry in the table, NULL if the table is empty
342 * \sa scanResultTable_GetNext
343 */
scanResultTable_GetFirst(TI_HANDLE hScanResultTable)344 TSiteEntry *scanResultTable_GetFirst (TI_HANDLE hScanResultTable)
345 {
346 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
347
348 /* initialize the iterator to point at the first site */
349 pScanResultTable->uIterator = 0;
350
351 /* and return the next entry... */
352 return scanResultTable_GetNext (hScanResultTable);
353 }
354
355 /**
356 * \fn scanResultTable_GetNext
357 * \brief Retreives the next entry in the table
358 *
359 * Retreives the next entry in the table, until table is exhusted. A call to scanResultTable_GetFirst
360 * must preceed a sequence of calls to this function.
361 *
362 * \param hScanResultTable - handle to the scan result table object
363 * \return A pointer to the next entry in the table, NULL if the table is exhsuted
364 * \sa scanResultTable_GetFirst
365 */
scanResultTable_GetNext(TI_HANDLE hScanResultTable)366 TSiteEntry *scanResultTable_GetNext (TI_HANDLE hScanResultTable)
367 {
368 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
369
370 /* if the iterator points to a site behind current table storage, return error */
371 if (pScanResultTable->uCurrentSiteNumber <= pScanResultTable->uIterator)
372 {
373 return NULL;
374 }
375
376 return &(pScanResultTable->pTable[ pScanResultTable->uIterator++ ]);
377 }
378
379 /**
380 * \fn scanResultTable_GetByBssid
381 * \brief retreives an entry according to its SSID and BSSID
382 *
383 * retreives an entry according to its BSSID
384 *
385 * \param hScanResultTable - handle to the scan result table object
386 * \param pSsid - SSID to search for
387 * \param pBssid - BSSID to search for
388 * \return A pointer to the entry with macthing BSSID, NULL if no such entry was found.
389 */
scanResultTable_GetBySsidBssidPair(TI_HANDLE hScanResultTable,TSsid * pSsid,TMacAddr * pBssid)390 TSiteEntry *scanResultTable_GetBySsidBssidPair (TI_HANDLE hScanResultTable, TSsid *pSsid, TMacAddr *pBssid)
391 {
392 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
393 TI_UINT32 uIndex;
394
395 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 ]);
396
397 /* check all entries in the table */
398 for (uIndex = 0; uIndex < pScanResultTable->uCurrentSiteNumber; uIndex++)
399 {
400 /* if the BSSID and SSID match */
401 if (MAC_EQUAL (*pBssid, pScanResultTable->pTable[ uIndex ].bssid) &&
402 ((pSsid->len == pScanResultTable->pTable[ uIndex ].ssid.len) &&
403 (0 == os_memoryCompare (pScanResultTable->hOS, &(pSsid->str[ 0 ]),
404 &(pScanResultTable->pTable[ uIndex ].ssid.str[ 0 ]),
405 pSsid->len))))
406 {
407 TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "Entry found at index %d\n", uIndex);
408 return &(pScanResultTable->pTable[ uIndex ]);
409 }
410 }
411
412 /* site wasn't found: return NULL */
413 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBySsidBssidPair: Entry was not found\n");
414 return NULL;
415 }
416
417 /**
418 * \fn scanresultTbale_AllocateNewEntry
419 * \brief Allocates an empty entry for a new site
420 *
421 * Function Allocates an empty entry for a new site (and nullfiies required entry fields)
422 *
423 * \param hScanResultTable - handle to the scan result table object
424 * \return Pointer to the site entry (NULL if the table is full)
425 */
scanResultTbale_AllocateNewEntry(TI_HANDLE hScanResultTable)426 TSiteEntry *scanResultTbale_AllocateNewEntry (TI_HANDLE hScanResultTable)
427 {
428 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
429 TI_UINT32 uRsnIndex;
430
431 /* if the table is full */
432 if (pScanResultTable->uCurrentSiteNumber >= TABLE_ENTRIES_NUMBER)
433 {
434 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTbale_AllocateNewEntry: Table is full, can't allocate new entry\n");
435 return NULL;
436 }
437
438 TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTbale_AllocateNewEntry: New entry allocated at index %d\n", pScanResultTable->uCurrentSiteNumber);
439
440 /* Nullify new site data */
441 pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ].ssid.len = 0;
442 pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ].tHtCapabilities.tHdr[0] = 0;
443 pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ].tHtInformation.tHdr[0] = 0;
444 for (uRsnIndex = 0; uRsnIndex < MAX_RSN_IE; uRsnIndex++)
445 {
446 pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ].pRsnIe[ uRsnIndex ].hdr[ 1 ] = 0;
447 }
448
449 pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ].bConsideredForSelect = TI_FALSE;
450 pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ].probeRecv = TI_FALSE;
451 pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber ].beaconRecv = TI_FALSE;
452
453 /* return the site (and update site count) */
454 pScanResultTable->uCurrentSiteNumber++;
455 return &(pScanResultTable->pTable[ pScanResultTable->uCurrentSiteNumber - 1 ]);
456 }
457
458 /**
459 * \fn scanResultTable_UpdateSiteData
460 * \brief Update a site entry data from a received frame (beacon or probe response)
461 *
462 * Update a site entry data from a received frame (beacon or probe response)
463 *
464 * \param hScanResultTable - handle to the scan result table object
465 * \param pSite - the site entry to update
466 * \param pFrame - the received frame information
467 * \return None
468 */
scanResultTable_UpdateSiteData(TI_HANDLE hScanResultTable,TSiteEntry * pSite,TScanFrameInfo * pFrame)469 void scanResultTable_UpdateSiteData (TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame)
470 {
471 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
472 paramInfo_t param;
473
474 UPDATE_BSSID (pSite, pFrame);
475 UPDATE_BAND (pSite, pFrame);
476 UPDATE_BEACON_INTERVAL (pSite, pFrame);
477 UPDATE_CAPABILITIES (pSite, pFrame);
478 UPDATE_SSID (pScanResultTable, pSite, pFrame);
479 UPDATE_PRIVACY (pSite, pFrame);
480 UPDATE_RSN_IE (pScanResultTable, pSite, pFrame->parsedIEs->content.iePacket.pRsnIe, pFrame->parsedIEs->content.iePacket.rsnIeLen);
481 UPDATE_APSD (pSite, pFrame);
482 UPDATE_PREAMBLE (pSite, pFrame);
483 UPDATE_AGILITY (pSite, pFrame);
484 UPDATE_RSSI (pSite, pFrame);
485 UPDATE_SNR (pSite, pFrame);
486 UPDATE_RATE (pSite, pFrame);
487
488 param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
489 siteMgr_getParam (pScanResultTable->hSiteMgr, ¶m);
490 if (param.content.siteMgrDot11OperationalMode == DOT11_G_MODE)
491 {
492 UPDATE_SLOT_TIME (pSite, pFrame);
493 UPDATE_PROTECTION (pSite, pFrame);
494 }
495
496 scanResultTable_updateRates (hScanResultTable, pSite, pFrame);
497
498 if ((pFrame->parsedIEs->content.iePacket.pDSParamsSet != NULL) &&
499 (pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel != pFrame->channel))
500 {
501 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_WARNING, "scanResultTable_UpdateSiteData: wrong channels, radio channel=%d, frame channel=%d\n", pFrame->channel, pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel);
502 }
503 else
504 UPDATE_CHANNEL (pSite, pFrame , pFrame->channel);
505
506 UPDATE_BSS_TYPE (pSite, pFrame);
507 UPDATE_ATIM_WINDOW (pSite, pFrame);
508 UPDATE_AP_TX_POWER (pSite, pFrame);
509 UPDATE_QOS (pSite, pFrame);
510 UPDATE_BEACON_TIMESTAMP (pScanResultTable, pSite, pFrame);
511 scanResultTable_UpdateWSCParams (pSite, pFrame);
512
513 if (BEACON == pFrame->parsedIEs->subType)
514 {
515 /* DTIM is only available in beacons */
516 if (pSite->bssType == BSS_INFRASTRUCTURE)
517 {
518 UPDATE_DTIM_PERIOD (pSite, pFrame);
519 }
520
521 UPDATE_BEACON_MODULATION (pSite, pFrame);
522
523 /* If the BSS type is independent, the beacon & probe modulation are equal,
524 It is important to update this field here for dynamic PBCC algorithm compatibility */
525 if (pSite->bssType == BSS_INDEPENDENT)
526 {
527 UPDATE_PROBE_MODULATION (pSite, pFrame);
528 }
529
530 UPDATE_BEACON_RECV (pSite);
531 UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->beaconBuffer), (pSite->beaconLength), pFrame);
532 }
533 else if (PROBE_RESPONSE == pFrame->parsedIEs->subType)
534 {
535 UPDATE_PROBE_MODULATION (pSite, pFrame);
536
537 /* If the BSS type is independent, the beacon & probe modulation are equal,
538 It is important to update this field here for dynamic PBCC algorithm compatibility */
539 if (pSite->bssType == BSS_INDEPENDENT)
540 UPDATE_BEACON_MODULATION (pSite, pFrame);
541
542 UPDATE_PROBE_RECV (pSite);
543 UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->probeRespBuffer), (pSite->probeRespLength), pFrame);
544 }
545 else
546 {
547 TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_UpdateSiteData: unknown frame sub type %d\n", pFrame->parsedIEs->subType);
548 }
549 }
550
551 /**
552 * \fn scanResultTable_updateRates
553 * \brief Update a scan result table entry with rates information
554 *
555 * Called by the function 'updateSiteInfo()' in order to translate the rates received
556 * in the beacon or probe response to rate used by the driver. Perfoms the following:
557 * - Check the rates. validity. If rates are invalid, return
558 * - Get the max active rate & max basic rate, if invalid, return
559 * - Translate the max active rate and max basic rate from network rates to host rates.
560 * The max active & max basic rate are used by the driver from now on in all the processes:
561 * (selection, join, transmission, etc....)
562 *
563 * \param hScanResultTable - handle to the scan result table object
564 * \param pSite - a pointer to the site entry to update
565 * \param pFrame - a pointer to the received frame
566 * \return None
567 * \sa scanResultTable_UpdateSiteData
568 */
scanResultTable_updateRates(TI_HANDLE hScanResultTable,TSiteEntry * pSite,TScanFrameInfo * pFrame)569 void scanResultTable_updateRates(TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame)
570 {
571 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
572 TI_UINT8 maxBasicRate = 0, maxActiveRate = 0;
573 TI_UINT32 bitMapExtSupp = 0;
574
575 if (pFrame->parsedIEs->content.iePacket.pRates == NULL)
576 {
577 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_ERROR, "scanResultTable_updateRates, pRates=NULL, beacon & probeResp are:\n");
578 TRACE_INFO_HEX(pScanResultTable->hReport, (TI_UINT8*)pFrame->parsedIEs->content.iePacket.pRates, pFrame->parsedIEs->content.iePacket.pRates->hdr[1]+2);
579 TRACE_INFO_HEX(pScanResultTable->hReport, (TI_UINT8*)pFrame->parsedIEs->content.iePacket.pRates, pFrame->parsedIEs->content.iePacket.pRates->hdr[1]+2);
580 return;
581 }
582
583 /* Update the rate elements */
584 maxBasicRate = rate_GetMaxBasicFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pRates->rates,
585 pFrame->parsedIEs->content.iePacket.pRates->hdr[1], maxBasicRate);
586 maxActiveRate = rate_GetMaxActiveFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pRates->rates,
587 pFrame->parsedIEs->content.iePacket.pRates->hdr[1], maxActiveRate);
588
589 if (pFrame->parsedIEs->content.iePacket.pExtRates)
590 {
591 maxBasicRate = rate_GetMaxBasicFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pExtRates->rates,
592 pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1], maxBasicRate);
593 maxActiveRate = rate_GetMaxActiveFromStr ((TI_UINT8 *)pFrame->parsedIEs->content.iePacket.pExtRates->rates,
594 pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1], maxActiveRate);
595 }
596
597 if (maxActiveRate == 0)
598 {
599 maxActiveRate = maxBasicRate;
600 }
601
602 /* Now update it from network to host rates */
603 pSite->maxBasicRate = rate_NetToDrv (maxBasicRate);
604 pSite->maxActiveRate = rate_NetToDrv (maxActiveRate);
605 if (pSite->maxActiveRate == DRV_RATE_INVALID)
606 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_ERROR, "scanResultTable_updateRates: Network To Host Rate failure, no active network rate\n");
607
608 if (pSite->maxBasicRate != DRV_RATE_INVALID)
609 {
610 if (pSite->maxActiveRate != DRV_RATE_INVALID)
611 {
612 pSite->maxActiveRate = TI_MAX (pSite->maxActiveRate, pSite->maxBasicRate);
613 }
614 } else { /* in case some vendors don't specify basic rates */
615 TRACE0(pScanResultTable->hReport, REPORT_SEVERITY_WARNING, "scanResultTable_updateRates: Network To Host Rate failure, no basic network rate");
616 pSite->maxBasicRate = pSite->maxActiveRate;
617 }
618
619 /* build rates bit map */
620 rate_NetStrToDrvBitmap (&pSite->rateMask.supportedRateMask,
621 pFrame->parsedIEs->content.iePacket.pRates->rates,
622 pFrame->parsedIEs->content.iePacket.pRates->hdr[1]);
623 rate_NetBasicStrToDrvBitmap (&pSite->rateMask.basicRateMask,
624 pFrame->parsedIEs->content.iePacket.pRates->rates,
625 pFrame->parsedIEs->content.iePacket.pRates->hdr[1]);
626
627 if (pFrame->parsedIEs->content.iePacket.pExtRates)
628 {
629 rate_NetStrToDrvBitmap (&bitMapExtSupp,
630 pFrame->parsedIEs->content.iePacket.pExtRates->rates,
631 pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1]);
632
633 pSite->rateMask.supportedRateMask |= bitMapExtSupp;
634
635 rate_NetBasicStrToDrvBitmap (&bitMapExtSupp,
636 pFrame->parsedIEs->content.iePacket.pExtRates->rates,
637 pFrame->parsedIEs->content.iePacket.pExtRates->hdr[1]);
638
639 pSite->rateMask.basicRateMask |= bitMapExtSupp;
640 }
641 }
642
643 /**
644 * \fn scanResultTable_UpdateWSCParams
645 * \brief Update a scan result table entry with WSC information
646 *
647 * Update a scan result table entry with WSC information
648 *
649 * \param pSite - a pointer to the site entry to update
650 * \param pFrame - a pointer to the received frame
651 * \return None
652 * \sa scanResultTable_UpdateSiteData
653 */
scanResultTable_UpdateWSCParams(TSiteEntry * pSite,TScanFrameInfo * pFrame)654 void scanResultTable_UpdateWSCParams (TSiteEntry *pSite, TScanFrameInfo *pFrame)
655 {
656 /* if the IE is not null => the WSC is on - check which method is supported */
657 if (pFrame->parsedIEs->content.iePacket.WSCParams != NULL)
658 {
659 TI_UINT8 *tlvPtr,*endPtr;
660 TI_UINT16 tlvPtrType,tlvPtrLen,selectedMethod=0;
661
662 tlvPtr = (TI_UINT8*)pFrame->parsedIEs->content.iePacket.WSCParams->WSCBeaconOrProbIE;
663 endPtr = tlvPtr + pFrame->parsedIEs->content.iePacket.WSCParams->hdr[1] - (DOT11_OUI_LEN + 1);
664
665 do
666 {
667 tlvPtrType = WLANTOHS (WLAN_WORD(tlvPtr));
668
669 if (tlvPtrType == DOT11_WSC_DEVICE_PASSWORD_ID)
670 {
671 tlvPtr+=2;
672 tlvPtr+=2;
673 selectedMethod = WLANTOHS (WLAN_WORD(tlvPtr));
674 break;
675 }
676 else
677 {
678 tlvPtr+=2;
679 tlvPtrLen = WLANTOHS (WLAN_WORD(tlvPtr));
680 tlvPtr+=tlvPtrLen+2;
681 }
682 } while ((tlvPtr < endPtr) && (selectedMethod == 0));
683
684 if (tlvPtr > endPtr)
685 {
686 pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_OFF;
687 return;
688 }
689
690 if (selectedMethod == DOT11_WSC_DEVICE_PASSWORD_ID_PIN)
691 pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_PIN_METHOD;
692 else if (selectedMethod == DOT11_WSC_DEVICE_PASSWORD_ID_PBC)
693 pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_PBC_METHOD;
694 else
695 pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_OFF;
696 }
697 else
698 {
699 pSite->WSCSiteMode = TIWLN_SIMPLE_CONFIG_OFF;
700 }
701 }
702
703 /**
704 * \fn scanResultTable_CalculateBssidListSize
705 * \brief Calculates the size required for BSSID list storage
706 *
707 * Calculates the size required for BSSID list storage
708 *
709 * \param hScanResultTable - handle to the scan result table object
710 * \param bAllVarIes - whether to include all variable size IEs
711 * \return The total length required
712 * \sa scanResultTable_GetBssidList
713 */
scanResultTable_CalculateBssidListSize(TI_HANDLE hScanResultTable,TI_BOOL bAllVarIes)714 TI_UINT32 scanResultTable_CalculateBssidListSize (TI_HANDLE hScanResultTable, TI_BOOL bAllVarIes)
715 {
716 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
717 TI_UINT32 uSiteIndex, uSiteLength, uLength = 0;
718 TSiteEntry *pSiteEntry;
719
720 /* set the length of the list header (sites count) */
721 uLength = sizeof(OS_802_11_BSSID_LIST_EX) - sizeof(OS_802_11_BSSID_EX);
722
723 /* check lengthes of all sites in the table */
724 for (uSiteIndex = 0; uSiteIndex < pScanResultTable->uCurrentSiteNumber; uSiteIndex++)
725 {
726 pSiteEntry = &(pScanResultTable->pTable[ uSiteIndex ]);
727 /* if full list is requested */
728 if (bAllVarIes)
729 {
730 /* set length of all IEs for this site */
731 uSiteLength = sizeof(OS_802_11_BSSID_EX) + sizeof(OS_802_11_FIXED_IEs);
732 /* and add beacon or probe response length */
733 if (TI_TRUE == pSiteEntry->probeRecv)
734 {
735 uSiteLength += pSiteEntry->probeRespLength;
736 }
737 else
738 {
739 uSiteLength += pSiteEntry->beaconLength;
740 }
741
742 }
743 /* partial list is requested */
744 else
745 {
746 uSiteLength = (sizeof(OS_802_11_BSSID_EX) + sizeof(OS_802_11_FIXED_IEs) +
747 (pSiteEntry->ssid.len + 2) + (DOT11_MAX_SUPPORTED_RATES + 2) +
748 + (DOT11_DS_PARAMS_ELE_LEN +2) + pSiteEntry->rsnIeLen);
749
750 /* QOS_WME information element */
751 if (pSiteEntry->WMESupported)
752 {
753 /* length of element + header */
754 uSiteLength += (DOT11_WME_PARAM_ELE_LEN + 2);
755 }
756 }
757
758 /* make sure length is 4 bytes aligned */
759 if (uSiteLength % 4)
760 {
761 uSiteLength += (4 - (uSiteLength % 4));
762 }
763
764 /* add this site length to the total length */
765 uLength += uSiteLength;
766
767 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_calculateBssidListSize: BSSID length=%d on site index %d\n", uSiteLength, uSiteIndex);
768 }
769
770 TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_calculateBssidListSize: total length=%d \n", uLength);
771
772 return uLength;
773 }
774
775 /**
776 * \fn scanResultTable_GetBssidList
777 * \brief Retrieves the site table content
778 *
779 * Retrieves the site table content
780 *
781 * \param hScanResultTable - handle to the scan result table object
782 * \param pBssidList - pointer to a buffer large enough to hols the BSSID list
783 * \param plength - length of the supplied buffer, will be overwritten with the actual list length
784 * \param bAllVarIes - whether to include all variable size IEs
785 * \return None
786 * \sa scanResultTable_CalculateBssidListSize
787 */
scanResultTable_GetBssidList(TI_HANDLE hScanResultTable,OS_802_11_BSSID_LIST_EX * pBssidList,TI_UINT32 * pLength,TI_BOOL bAllVarIes)788 TI_STATUS scanResultTable_GetBssidList (TI_HANDLE hScanResultTable,
789 OS_802_11_BSSID_LIST_EX *pBssidList,
790 TI_UINT32 *pLength,
791 TI_BOOL bAllVarIes)
792 {
793 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable;
794 TI_UINT32 uLength, uSiteIndex, rsnIndex, rsnIeLength, len, firstOFDMloc = 0;
795 TSiteEntry *pSiteEntry;
796 OS_802_11_BSSID_EX *pBssid;
797 OS_802_11_FIXED_IEs *pFixedIes;
798 OS_802_11_VARIABLE_IEs *pVarIes;
799 TI_UINT8 *pData;
800
801 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList called, pBssidList= 0x%p, pLength=%d\n", pBssidList, *pLength);
802
803 /* verify the supplied length is enough */
804 uLength = scanResultTable_CalculateBssidListSize (hScanResultTable, bAllVarIes);
805 if (uLength > *pLength)
806 {
807 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_GetBssidList: received length %d, insufficient to hold list of size %d\n", *pLength, uLength);
808 *pLength = uLength;
809 return TI_NOK;
810 }
811 #ifdef TI_DBG
812 else
813 {
814 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: supplied length: %d, required length: %d\n", *pLength, uLength);
815 }
816 #endif
817
818 /* Nullify number of items in the BSSID list */
819 pBssidList->NumberOfItems = 0;
820
821 /* set length to list header size (only list count) */
822 uLength = sizeof(OS_802_11_BSSID_LIST_EX) - sizeof(OS_802_11_BSSID_EX);
823
824 /* set data pointer to first item in list */
825 pData = (TI_UINT8*)&(pBssidList->Bssid[0]);
826
827 for (uSiteIndex = 0; uSiteIndex < pScanResultTable->uCurrentSiteNumber; uSiteIndex++)
828 {
829 /* set BSSID entry pointer to current location in buffer */
830 pBssid = (OS_802_11_BSSID_EX*)pData;
831
832 /* set pointer to site entry */
833 pSiteEntry = &(pScanResultTable->pTable[ uSiteIndex ]);
834
835 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 ]);
836
837 /* start copy stuff: */
838 /* MacAddress */
839 MAC_COPY (pBssid->MacAddress, pSiteEntry->bssid);
840
841 /* Capabilities */
842 pBssid->Capabilities = pSiteEntry->capabilities;
843
844 /* SSID */
845 os_memoryZero (pScanResultTable->hOS, &(pBssid->Ssid.Ssid), MAX_SSID_LEN);
846 if (pSiteEntry->ssid.len > MAX_SSID_LEN)
847 {
848 pSiteEntry->ssid.len = MAX_SSID_LEN;
849 }
850 os_memoryCopy (pScanResultTable->hOS,
851 (void *)pBssid->Ssid.Ssid,
852 (void *)pSiteEntry->ssid.str,
853 pSiteEntry->ssid.len);
854 pBssid->Ssid.SsidLength = pSiteEntry->ssid.len;
855
856 /* privacy */
857 pBssid->Privacy = pSiteEntry->privacy;
858
859 /* RSSI */
860 pBssid->Rssi = pSiteEntry->rssi;
861
862 pBssid->Configuration.Length = sizeof(OS_802_11_CONFIGURATION);
863 pBssid->Configuration.BeaconPeriod = pSiteEntry->beaconInterval;
864 pBssid->Configuration.ATIMWindow = pSiteEntry->atimWindow;
865 pBssid->Configuration.Union.channel = Chan2Freq(pSiteEntry->channel);
866
867 if (pSiteEntry->bssType == BSS_INDEPENDENT)
868 pBssid->InfrastructureMode = os802_11IBSS;
869 else
870 pBssid->InfrastructureMode = os802_11Infrastructure;
871 /* Supported Rates */
872 os_memoryZero (pScanResultTable->hOS, (void *)pBssid->SupportedRates, sizeof(OS_802_11_RATES_EX));
873 rate_DrvBitmapToNetStr (pSiteEntry->rateMask.supportedRateMask,
874 pSiteEntry->rateMask.basicRateMask,
875 (TI_UINT8*)pBssid->SupportedRates,
876 &len,
877 &firstOFDMloc);
878
879 /* set network type acording to band and rates */
880 if (RADIO_BAND_2_4_GHZ == pSiteEntry->eBand)
881 {
882 if (firstOFDMloc == len)
883 {
884 pBssid->NetworkTypeInUse = os802_11DS;
885 } else {
886 pBssid->NetworkTypeInUse = os802_11OFDM24;
887 }
888 }
889 else
890 {
891 pBssid->NetworkTypeInUse = os802_11OFDM5;
892 }
893
894 /* start copy IE's: first nullify length */
895 pBssid->IELength = 0;
896
897 /* copy fixed IEs from site entry */
898 pFixedIes = (OS_802_11_FIXED_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
899 os_memoryCopy (pScanResultTable->hOS, (void*)pFixedIes->TimeStamp,
900 &(pSiteEntry->tsfTimeStamp[ 0 ]), TIME_STAMP_LEN);
901 pFixedIes->BeaconInterval = pSiteEntry->beaconInterval;
902 pFixedIes->Capabilities = pSiteEntry->capabilities;
903 pBssid->IELength += sizeof(OS_802_11_FIXED_IEs);
904
905 /* set pointer for variable length IE's */
906 pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
907
908 if (!bAllVarIes)
909 { /* copy only some variable IEs */
910
911 /* copy SSID */
912 pVarIes->ElementID = SSID_IE_ID;
913 pVarIes->Length = pSiteEntry->ssid.len;
914 os_memoryCopy (pScanResultTable->hOS,
915 (void *)pVarIes->data,
916 (void *)pSiteEntry->ssid.str,
917 pSiteEntry->ssid.len);
918 pBssid->IELength += (pVarIes->Length + 2);
919
920 /* copy RATES */
921 pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
922 pVarIes->ElementID = SUPPORTED_RATES_IE_ID;
923 rate_DrvBitmapToNetStr (pSiteEntry->rateMask.supportedRateMask,
924 pSiteEntry->rateMask.basicRateMask,
925 (TI_UINT8 *)pVarIes->data,
926 &len,
927 &firstOFDMloc);
928 pVarIes->Length = len;
929 pBssid->IELength += (pVarIes->Length + 2);
930
931 /* copy DS */
932 pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
933 pVarIes->ElementID = DS_PARAMETER_SET_IE_ID;
934 pVarIes->Length = DOT11_DS_PARAMS_ELE_LEN;
935 os_memoryCopy (pScanResultTable->hOS, (void *)pVarIes->data,
936 &(pSiteEntry->channel), DOT11_DS_PARAMS_ELE_LEN);
937 pBssid->IELength += (pVarIes->Length + 2);
938
939 /* copy RSN information elements */
940 if (0 < pSiteEntry->rsnIeLen)
941 {
942 rsnIeLength = 0;
943 for (rsnIndex=0; rsnIndex < MAX_RSN_IE && pSiteEntry->pRsnIe[ rsnIndex ].hdr[1] > 0; rsnIndex++)
944 {
945 pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength + rsnIeLength ]);
946 pVarIes->ElementID = pSiteEntry->pRsnIe[ rsnIndex ].hdr[0];
947 pVarIes->Length = pSiteEntry->pRsnIe[ rsnIndex ].hdr[1];
948 os_memoryCopy (pScanResultTable->hOS, (void *)pVarIes->data,
949 (void *)pSiteEntry->pRsnIe[ rsnIndex ].rsnIeData,
950 pSiteEntry->pRsnIe[ rsnIndex ].hdr[1]);
951 rsnIeLength += pSiteEntry->pRsnIe[ rsnIndex ].hdr[1] + 2;
952 }
953 pBssid->IELength += pSiteEntry->rsnIeLen;
954 }
955
956 /* QOS_WME/XCC */
957 if (TI_TRUE == pSiteEntry->WMESupported)
958 {
959 /* oui */
960 TI_UINT8 ouiWME[3] = {0x50, 0xf2, 0x01};
961 dot11_WME_PARAM_t *pWMEParams;
962
963 /* fill in the general element parameters */
964 pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]);
965 pVarIes->ElementID = DOT11_WME_ELE_ID;
966 pVarIes->Length = DOT11_WME_PARAM_ELE_LEN;
967
968 /* fill in the specific element parameters */
969 pWMEParams = (dot11_WME_PARAM_t*)pVarIes;
970 os_memoryCopy (pScanResultTable->hOS, (void *)pWMEParams->OUI, ouiWME, 3);
971 pWMEParams->OUIType = dot11_WME_OUI_TYPE;
972 pWMEParams->OUISubType = dot11_WME_OUI_SUB_TYPE_PARAMS_IE;
973 pWMEParams->version = dot11_WME_VERSION;
974 pWMEParams->ACInfoField = dot11_WME_ACINFO_MASK & pSiteEntry->lastWMEParameterCnt;
975
976 /* fill in the data */
977 os_memoryCopy (pScanResultTable->hOS, &(pWMEParams->WME_ACParameteres),
978 &(pSiteEntry->WMEParameters), sizeof(dot11_ACParameters_t));
979
980
981 /* update the general length */
982 pBssid->IELength += (pVarIes->Length + 2);
983 }
984 }
985 else
986 { /* Copy all variable IEs */
987 if (pSiteEntry->probeRecv)
988 {
989 os_memoryCopy (pScanResultTable->hOS, pVarIes,
990 pSiteEntry->probeRespBuffer, pSiteEntry->probeRespLength);
991 pBssid->IELength += pSiteEntry->probeRespLength;
992 }
993 else
994 {
995 os_memoryCopy (pScanResultTable->hOS, pVarIes,
996 pSiteEntry->beaconBuffer, pSiteEntry->beaconLength);
997 pBssid->IELength += pSiteEntry->beaconLength;
998 }
999 }
1000
1001 /* -1 to remove the IEs[1] placeholder in OS_802_11_BSSID_EX which is taken into account in pBssid->IELength */
1002 pBssid->Length = sizeof(OS_802_11_BSSID_EX) + pBssid->IELength - 1;
1003
1004 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: before alignment fix, IEs length: %d, BSSID length %d\n", pBssid->IELength, pBssid->Length);
1005
1006 /* make sure length is 4 bytes aligned */
1007 if (pBssid->Length % 4)
1008 {
1009 pBssid->Length += (4 - (pBssid->Length % 4));
1010 }
1011
1012 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: after alignment fix, IEs length: %d, BSSID length %d\n", pBssid->IELength, pBssid->Length);
1013
1014 pData += pBssid->Length;
1015 uLength += pBssid->Length;
1016
1017 TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: current length: %d\n", uLength);
1018 }
1019
1020 pBssidList->NumberOfItems = pScanResultTable->uCurrentSiteNumber;
1021 *pLength = uLength;
1022
1023 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_INFORMATION , "scanResultTable_GetBssidList: total length: %d, number of items: %d\n", uLength, pBssidList->NumberOfItems);
1024
1025 return TI_OK;
1026 }
1027
1028
1029 /***********************************************************************
1030 * siteMgr_CheckRxSignalValidity
1031 ***********************************************************************
1032 DESCRIPTION: Called by the scanResultTable_UpdateEntry when receiving managment frame
1033 Find the ste in the site table and validate that the
1034 RSSI of that site signal is not lower then -80DB + not lower
1035 then the exising site RSSI
1036
1037
1038 INPUT: hSiteMgr - site mgr handle.
1039 rxLevel - Rx level the frame received in
1040 bssid - BSSID of the frame
1041
1042 OUTPUT:
1043
1044 RETURN: TI_OK / TI_NOK
1045
1046 ************************************************************************/
1047 /**
1048 * \fn scanResultTable_CheckRxSignalValidity
1049 * \brief return the state of the table to its state after scan
1050 *
1051 * Called by the scanResultTable_UpdateEntry when receiving managment frame
1052 * validate that the RSSI of that site signal is not lower then then the exising site RSSI.
1053 * validate that the channel in correct.
1054 *
1055 * \param pScanResultTable - scan result table object
1056 * \param pSite - entry from the table
1057 * \param rssi - RSSI level at which frame was received
1058 * \param channel - channel on which the frame was received
1059 * \return None
1060 * \sa
1061 */
scanResultTable_CheckRxSignalValidity(TScanResultTable * pScanResultTable,TSiteEntry * pSite,TI_INT8 rxLevel,TI_UINT8 channel)1062 static TI_STATUS scanResultTable_CheckRxSignalValidity(TScanResultTable *pScanResultTable, TSiteEntry *pSite, TI_INT8 rxLevel, TI_UINT8 channel)
1063 {
1064 if ((channel != pSite->channel) &&
1065 (rxLevel < pSite->rssi))
1066 { /* Ignore wrong packets with lower RSSI that were detect as
1067 ripples from different channels */
1068 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);
1069 return TI_NOK;
1070 }
1071
1072 return TI_OK;
1073 }
1074
1075
1076
1077