Home | History | Annotate | Download | only in Sta_Management
      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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
   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