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