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 125typedef 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 136static TSiteEntry *scanResultTbale_AllocateNewEntry (TI_HANDLE hScanResultTable); 137static void scanResultTable_UpdateSiteData (TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame); 138static void scanResultTable_updateRates(TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame); 139static void scanResultTable_UpdateWSCParams (TSiteEntry *pSite, TScanFrameInfo *pFrame); 140static 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 */ 154TI_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 */ 190void 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 */ 215void 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 */ 244TI_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 */ 315void 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 */ 344TSiteEntry *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 */ 366TSiteEntry *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 */ 390TSiteEntry *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 */ 426TSiteEntry *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 */ 469void scanResultTable_UpdateSiteData (TI_HANDLE hScanResultTable, TSiteEntry *pSite, TScanFrameInfo *pFrame) 470{ 471 TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable; 472 paramInfo_t param; 473 474 UPDATE_BSSID (pSite, pFrame); 475 UPDATE_BAND (pSite, pFrame); 476 UPDATE_BEACON_INTERVAL (pSite, pFrame); 477 UPDATE_CAPABILITIES (pSite, pFrame); 478 UPDATE_SSID (pScanResultTable, pSite, pFrame); 479 UPDATE_PRIVACY (pSite, pFrame); 480 UPDATE_RSN_IE (pScanResultTable, pSite, pFrame->parsedIEs->content.iePacket.pRsnIe, pFrame->parsedIEs->content.iePacket.rsnIeLen); 481 UPDATE_APSD (pSite, pFrame); 482 UPDATE_PREAMBLE (pSite, pFrame); 483 UPDATE_AGILITY (pSite, pFrame); 484 UPDATE_RSSI (pSite, pFrame); 485 UPDATE_SNR (pSite, pFrame); 486 UPDATE_RATE (pSite, pFrame); 487 488 param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM; 489 siteMgr_getParam (pScanResultTable->hSiteMgr, ¶m); 490 if (param.content.siteMgrDot11OperationalMode == DOT11_G_MODE) 491 { 492 UPDATE_SLOT_TIME (pSite, pFrame); 493 UPDATE_PROTECTION (pSite, pFrame); 494 } 495 496 scanResultTable_updateRates (hScanResultTable, pSite, pFrame); 497 498 if ((pFrame->parsedIEs->content.iePacket.pDSParamsSet != NULL) && 499 (pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel != pFrame->channel)) 500 { 501 TRACE2(pScanResultTable->hReport, REPORT_SEVERITY_WARNING, "scanResultTable_UpdateSiteData: wrong channels, radio channel=%d, frame channel=%d\n", pFrame->channel, pFrame->parsedIEs->content.iePacket.pDSParamsSet->currChannel); 502 } 503 else 504 UPDATE_CHANNEL (pSite, pFrame , pFrame->channel); 505 506 UPDATE_BSS_TYPE (pSite, pFrame); 507 UPDATE_ATIM_WINDOW (pSite, pFrame); 508 UPDATE_AP_TX_POWER (pSite, pFrame); 509 UPDATE_QOS (pSite, pFrame); 510 UPDATE_BEACON_TIMESTAMP (pScanResultTable, pSite, pFrame); 511 scanResultTable_UpdateWSCParams (pSite, pFrame); 512 513 if (BEACON == pFrame->parsedIEs->subType) 514 { 515 /* DTIM is only available in beacons */ 516 if (pSite->bssType == BSS_INFRASTRUCTURE) 517 { 518 UPDATE_DTIM_PERIOD (pSite, pFrame); 519 } 520 521 UPDATE_BEACON_MODULATION (pSite, pFrame); 522 523 /* If the BSS type is independent, the beacon & probe modulation are equal, 524 It is important to update this field here for dynamic PBCC algorithm compatibility */ 525 if (pSite->bssType == BSS_INDEPENDENT) 526 { 527 UPDATE_PROBE_MODULATION (pSite, pFrame); 528 } 529 530 UPDATE_BEACON_RECV (pSite); 531 UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->beaconBuffer), (pSite->beaconLength), pFrame); 532 } 533 else if (PROBE_RESPONSE == pFrame->parsedIEs->subType) 534 { 535 UPDATE_PROBE_MODULATION (pSite, pFrame); 536 537 /* If the BSS type is independent, the beacon & probe modulation are equal, 538 It is important to update this field here for dynamic PBCC algorithm compatibility */ 539 if (pSite->bssType == BSS_INDEPENDENT) 540 UPDATE_BEACON_MODULATION (pSite, pFrame); 541 542 UPDATE_PROBE_RECV (pSite); 543 UPDATE_FRAME_BUFFER (pScanResultTable, (pSite->probeRespBuffer), (pSite->probeRespLength), pFrame); 544 } 545 else 546 { 547 TRACE1(pScanResultTable->hReport, REPORT_SEVERITY_ERROR , "scanResultTable_UpdateSiteData: unknown frame sub type %d\n", pFrame->parsedIEs->subType); 548 } 549} 550 551/** 552 * \fn scanResultTable_updateRates 553 * \brief Update a scan result table entry with rates information 554 * 555 * Called by the function 'updateSiteInfo()' in order to translate the rates received 556 * in the beacon or probe response to rate used by the driver. Perfoms the following: 557 * - Check the rates. validity. If rates are invalid, return 558 * - Get the max active rate & max basic rate, if invalid, return 559 * - Translate the max active rate and max basic rate from network rates to host rates. 560 * The max active & max basic rate are used by the driver from now on in all the processes: 561 * (selection, join, transmission, etc....) 562 * 563 * \param hScanResultTable - handle to the scan result table object 564 * \param pSite - a pointer to the site entry to update 565 * \param pFrame - a pointer to the received frame 566 * \return None 567 * \sa scanResultTable_UpdateSiteData 568 */ 569void 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 */ 654void 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 */ 714TI_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 */ 788TI_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 *********************************************************************** 1032DESCRIPTION: 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 1038INPUT: hSiteMgr - site mgr handle. 1039 rxLevel - Rx level the frame received in 1040 bssid - BSSID of the frame 1041 1042OUTPUT: 1043 1044RETURN: 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 */ 1062static 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