• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param);
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