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, ¶m); 664 if (param.content.siteMgrDot11OperationalMode == DOT11_G_MODE) 665 { 666 UPDATE_SLOT_TIME (pSite, pFrame); 667 UPDATE_PROTECTION (pSite, pFrame); 668 } 669 670 scanResultTable_updateRates (hScanResultTable, pSite, pFrame); 671 672 if ((pFrame->parsedIEs->content.iePacket.pDSParamsSet != NULL) && 673 (pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel != pFrame->channel)) 674 { 675 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_UpdateSiteData: wrong channels, radio channel=%d, frame channel=%d\n", pFrame->channel, pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel); 676 } 677 else 678 UPDATE_CHANNEL (pSite, pFrame , pFrame->channel); 679 680 UPDATE_BSS_TYPE (pSite, pFrame); 681 UPDATE_ATIM_WINDOW (pSite, pFrame); 682 UPDATE_AP_TX_POWER (pSite, pFrame); 683 UPDATE_QOS (pSite, pFrame); 684 UPDATE_BEACON_TIMESTAMP (pScanResultTable, pSite, pFrame); 685 scanResultTable_UpdateWSCParams (pSite, pFrame); 686 siteMgr_UpdatHtParams (pScanResultTable->hSiteMgr, pSite, pFrame->parsedIEs); 687 688 if (BEACON == pFrame->parsedIEs->subType) 689 { 690 /* DTIM is only available in beacons */ 691 if (pSite->bssType == BSS_INFRASTRUCTURE) 692 { 693 UPDATE_DTIM_PERIOD (pSite, pFrame); 694 } 695 696 UPDATE_BEACON_MODULATION (pSite, pFrame); 697 698 /* If the BSS type is independent, the beacon & probe modulation are equal, 699 It is important to update this field here for dynamic PBCC algorithm compatibility */ 700 if (pSite->bssType == BSS_INDEPENDENT) 701 { 702 UPDATE_PROBE_MODULATION (pSite, pFrame); 703 } 704 705 pSite->bChannelSwitchAnnoncIEFound = (pFrame->parsedIEs->content.iePacket.channelSwitch != NULL)?TI_TRUE:TI_FALSE; 706 707 UPDATE_BEACON_RECV (pSite); 708 UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->beaconBuffer), (pSite->beaconLength), pFrame); 709 } 710 else if (PROBE_RESPONSE == pFrame->parsedIEs->subType) 711 { 712 UPDATE_PROBE_MODULATION (pSite, pFrame); 713 714 /* If the BSS type is independent, the beacon & probe modulation are equal, 715 It is important to update this field here for dynamic PBCC algorithm compatibility */ 716 if (pSite->bssType == BSS_INDEPENDENT) 717 UPDATE_BEACON_MODULATION (pSite, pFrame); 718 719 UPDATE_PROBE_RECV (pSite); 720 UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->probeRespBuffer), (pSite->probeRespLength), pFrame); 721 722 pSite->bChannelSwitchAnnoncIEFound = TI_FALSE; 723 } 724 else 725 { 726 TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_UpdateSiteData: unknown frame sub type %d\n", pFrame->parsedIEs->subType); 727 } 728 } 729 730 /** 731 * \fn scanResultTable_updateRates 732 * \brief Update a scan result table entry with rates information 733 * 734 * Called by the function 'updateSiteInfo()' in order to translate the rates received 735 * in the beacon or probe response to rate used by the driver. Perfoms the following: 736 * - Check the rates. validity. If rates are invalid, return 737 * - Get the max active rate & max basic rate, if invalid, return 738 * - Translate the max active rate and max basic rate from network rates to host rates. 739 * The max active & max basic rate are used by the driver from now on in all the processes: 740 * (selection, join, transmission, etc....) 741 * 742 * \param hScanResultTable - handle to the scan result table object 743 * \param pSite - a pointer to the site entry to update 744 * \param pFrame - a pointer to the received frame 745 * \return None 746 * \sa scanResultTable_UpdateSiteData 747 */ 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