1/* 2 * siteHash.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 siteHash.c 35 * \brief Site Hash implementation 36 * 37 * \see siteHash.h 38 */ 39 40/****************************************************************************/ 41/* */ 42/* MODULE: siteHash.c */ 43/* PURPOSE: Site Hash implementation */ 44/* */ 45/***************************************************************************/ 46 47#define __FILE_ID__ FILE_ID_84 48#include "tidef.h" 49#include "report.h" 50#include "osApi.h" 51#include "siteMgrApi.h" 52#include "siteHash.h" 53#include "smeApi.h" 54 55 56/**************************************************************************************************************** 57 58 This file implements the site hash mechanism. This mechanism is used for faster access to the sites information. 59 It is compound of the following: 60 1. hash function - which maps the 4 last bits of the BSSID to an entry in the hash table. 61 2. hash table - each entry in the table points to a linked list of site entries 62 3. site table - each entry holds a site information 63 64 In order to find a site in the site table, we operate the hash function on the site's BSSID. 65 We receive a hash entry. We go over the linked list pointed by this hash entry until we find the site entry. 66*****************************************************************************************************************/ 67 68#define WLAN_NUM_OF_MISSED_SACNS_BEFORE_AGING 2 69 70 71/********************************************/ 72/* Functions Implementations */ 73/********************************************/ 74/************************************************************************ 75 * siteMgr_resetSiteTable * 76 ************************************************************************ 77DESCRIPTION: reset the following things: 78 - Mgmt parameters structure 79 - Site table 80 - Hash table 81 - Primary site pointer 82 - Number of sites 83 84INPUT: hSiteMgr - Handle to site mgr 85 86 87OUTPUT: 88 89RETURN: TI_OK 90 91************************************************************************/ 92TI_STATUS siteMgr_resetSiteTable(TI_HANDLE hSiteMgr, siteTablesParams_t *pSiteTableParams) 93{ 94 int i; 95 siteMgr_t *pSiteMgr = (siteMgr_t *)hSiteMgr; 96 97 os_memoryZero(pSiteMgr->hOs, &pSiteTableParams->siteTable[0], sizeof(siteEntry_t)*pSiteTableParams->maxNumOfSites); 98 99 for (i = 0; i < pSiteTableParams->maxNumOfSites; i++) 100 { 101 pSiteTableParams->siteTable[i].index = i; 102 pSiteTableParams->siteTable[i].siteType = SITE_NULL; 103 pSiteTableParams->siteTable[i].beaconRecv = TI_FALSE; 104 pSiteTableParams->siteTable[i].dtimPeriod = 1; 105 } 106 107 pSiteTableParams->numOfSites = 0; 108 109 pSiteMgr->pSitesMgmtParams->pPrimarySite = NULL; 110 111 return TI_OK; 112} 113 114/************************************************************************ 115 * findSiteEntry * 116 ************************************************************************ 117DESCRIPTION: Perform the following things: 118 - Compute the site's hash entry based on the site BSSID and hash function 119 - Look fotr the site entry in the linked list pointed by the hash entry 120 - If the site is found in the site table, returns a pointer to the site entry 121 - If the site is not found, return NULL. 122 123INPUT: pSiteMgr - Handle to site mgr 124 mac - The site BSSID 125 126 127OUTPUT: 128 129RETURN: Pointer to the site entry if site found, NULL otherwise 130 131************************************************************************/ 132siteEntry_t *findSiteEntry(siteMgr_t *pSiteMgr, 133 TMacAddr *mac) 134{ 135 siteTablesParams_t *pCurrentSiteTable = pSiteMgr->pSitesMgmtParams->pCurrentSiteTable; 136 siteEntry_t *pSiteEntry; 137 TI_UINT8 tableIndex=2, i; 138 139 140 do 141 { 142 tableIndex--; 143 for (i = 0; i < pCurrentSiteTable->maxNumOfSites; i++) 144 { 145 pSiteEntry = &(pCurrentSiteTable->siteTable[i]); 146 147 if (MAC_EQUAL (pSiteEntry->bssid, *mac)) 148 { 149TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "FIND success, bssid: %X-%X-%X-%X-%X-%X\n\n", (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]); 150 return pSiteEntry; 151 } 152 153 } 154 if ((pSiteMgr->pDesiredParams->siteMgrDesiredDot11Mode == DOT11_DUAL_MODE) && (tableIndex==1)) 155 { /* change site table */ 156 if (pCurrentSiteTable == &pSiteMgr->pSitesMgmtParams->dot11BG_sitesTables) 157 { 158 pCurrentSiteTable = (siteTablesParams_t *)&pSiteMgr->pSitesMgmtParams->dot11A_sitesTables; 159 } 160 else 161 { 162 pCurrentSiteTable = &pSiteMgr->pSitesMgmtParams->dot11BG_sitesTables; 163 } 164 } 165 166 } while (tableIndex>0); 167 168 169 170TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "FIND failure, bssid: %X-%X-%X-%X-%X-%X\n\n", (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]); 171 172 173 return NULL; 174} 175 176/************************************************************************ 177 * findAndInsertSiteEntry * 178 ************************************************************************ 179DESCRIPTION: Perform the following things: 180 - Compute the site's hash entry based on the site BSSID and hash function 181 - Look for the site entry in the linked list pointed by the hash entry 182 - If the site is found in the site table, returns a pointer to the site entry 183 - If the site is not found in the site table, tries to add the site 184 - If succeeds, returns a pointer to the site entry 185 - Otherwise, returns NULL 186 187INPUT: pSiteMgr - Handle to site mgr 188 mac - The site BSSID 189 band - The site band 190 191 192OUTPUT: 193 194RETURN: Pointer to the site entry if site found/inserted, NULL otherwise 195 196************************************************************************/ 197siteEntry_t *findAndInsertSiteEntry(siteMgr_t *pSiteMgr, 198 TMacAddr *mac, 199 ERadioBand band) 200{ 201 TI_UINT8 i, emptySiteIndex=0, nextSite2Remove=0; 202 siteEntry_t *pSiteEntry, *pPrimarySite=pSiteMgr->pSitesMgmtParams->pPrimarySite; 203 sitesMgmtParams_t *pSitesMgmtParams = pSiteMgr->pSitesMgmtParams; 204 siteTablesParams_t *pCurrentSiteTable; 205 TI_BOOL firstEmptySiteFound = TI_FALSE; 206 TI_UINT32 oldestTS; 207 208 209 /* choose site table according to AP's band */ 210 if ( RADIO_BAND_2_4_GHZ == band ) 211 { 212 pCurrentSiteTable = &(pSitesMgmtParams->dot11BG_sitesTables); 213 } 214 else if (RADIO_BAND_5_0_GHZ == band) 215 { 216 pCurrentSiteTable = (siteTablesParams_t*) &(pSitesMgmtParams->dot11A_sitesTables); 217 } 218 else 219 { 220 TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "Bad band: %d\n\n", band); 221 pCurrentSiteTable = &(pSitesMgmtParams->dot11BG_sitesTables); 222 } 223 224 /* Set the first TS to a site which is not the Primary site */ 225 if (pPrimarySite != &(pCurrentSiteTable->siteTable[0])) 226 { 227 oldestTS = pCurrentSiteTable->siteTable[0].localTimeStamp; 228 } 229 else 230 { 231 oldestTS = pCurrentSiteTable->siteTable[1].localTimeStamp; 232 } 233 234 /* Loop all the sites till the desired MAC is found */ 235 for (i = 0; i < pCurrentSiteTable->maxNumOfSites; i++) 236 { 237 pSiteEntry = &(pCurrentSiteTable->siteTable[i]); 238 239 if (MAC_EQUAL (pSiteEntry->bssid, *mac)) 240 { 241 242 TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "FIND success, bssid: %X-%X-%X-%X-%X-%X\n\n", (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]); 243 244 return pSiteEntry; 245 } 246 else if (pSiteEntry->siteType == SITE_NULL) 247 { /* Save the first empty site, in case the 248 desired MAC is not found */ 249 if (!firstEmptySiteFound) 250 { 251 emptySiteIndex = i; 252 firstEmptySiteFound=TI_TRUE; 253 } 254 255 } 256 if ((oldestTS > pSiteEntry->localTimeStamp) && 257 (pSiteEntry != pPrimarySite)) 258 { /* Save the oldest site's index, according to TS */ 259 oldestTS = pSiteEntry->localTimeStamp; 260 nextSite2Remove = i; 261 } 262 } 263 264 265 if ((!firstEmptySiteFound) || (pCurrentSiteTable->numOfSites>=pCurrentSiteTable->maxNumOfSites)) 266 { 267 /* No NULL entry has been found. Remove the oldest site */ 268 pSiteEntry = &(pCurrentSiteTable->siteTable[nextSite2Remove]); 269 TRACE9(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "INSERT failure, no free entry!, numOfSites=%d, removing site index=%d,\n bssid: %X-%X-%X-%X-%X-%X, ts=%d \n", pCurrentSiteTable->numOfSites, nextSite2Remove, pSiteEntry->bssid[0], pSiteEntry->bssid[1], pSiteEntry->bssid[2], pSiteEntry->bssid[3], pSiteEntry->bssid[4], pSiteEntry->bssid[5], pSiteEntry->localTimeStamp); 270 removeSiteEntry(pSiteMgr, pCurrentSiteTable, pSiteEntry); 271 emptySiteIndex = nextSite2Remove; 272 273 } 274 275 276 pCurrentSiteTable->numOfSites++; 277 278 pSiteEntry = &(pCurrentSiteTable->siteTable[emptySiteIndex]); 279 280 /* fill the entry with the station mac */ 281 MAC_COPY (pSiteEntry->bssid, *mac); 282 283 /* Some parameters have to be initialized immediately after entry allocation */ 284 285 if(pSiteMgr->siteMgrOperationalMode == DOT11_G_MODE) 286 pSiteEntry->currentSlotTime = pSiteMgr->pDesiredParams->siteMgrDesiredSlotTime; 287 288TRACE8(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "INSERT success, bssid: %X-%X-%X-%X-%X-%X, band=%d, index=%d\n\n", (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5], band, emptySiteIndex); 289 290 291 return pSiteEntry; 292} 293 294/************************************************************************ 295 * removeSiteEntry * 296 ************************************************************************ 297DESCRIPTION: Removes the site entry from the site table 298 299INPUT: pSiteMgr - Handle to site mgr 300 pCurrSiteTblParams - Pointer to current site table parameters 301 hashPtr - Pointer to the site entry 302 303 304OUTPUT: 305 306RETURN: 307 308************************************************************************/ 309void removeSiteEntry(siteMgr_t *pSiteMgr, 310 siteTablesParams_t *pCurrSiteTblParams, 311 siteEntry_t *pSiteEntry) 312{ 313 TI_UINT8 index; 314 315 if (pSiteEntry == NULL) 316 { 317TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "REMOVAL failure, site is NULL\n\n"); 318 return; 319 } 320 321 if (pCurrSiteTblParams->numOfSites == 0) 322 { 323TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "REMOVAL failure, site table is empty\n\n"); 324 return; 325 } 326 327TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "removeSiteEntry REMOVE ssid=, bssid= 0x%x-0x%x-0x%x-0x%x-0x%x-0x%x\n\n", pSiteEntry->bssid[0], pSiteEntry->bssid[1], pSiteEntry->bssid[2], pSiteEntry->bssid[3], pSiteEntry->bssid[4], pSiteEntry->bssid[5] ); 328 329 pCurrSiteTblParams->numOfSites--; 330 331 /* Now remove (exclude) hashPtr entry from the linked list */ 332 333TRACE6(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "REMOVAL success, bssid: %X-%X-%X-%X-%X-%X\n\n", pSiteEntry->bssid[0], pSiteEntry->bssid[1], pSiteEntry->bssid[2], pSiteEntry->bssid[3], pSiteEntry->bssid[4], pSiteEntry->bssid[5]); 334TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, " SITE TABLE remaining entries number %d \n", pCurrSiteTblParams->numOfSites); 335 336 /* Clean the rest of the entry structure */ 337 index = pSiteEntry->index; /* keep the index of the siteTable entry */ 338 os_memoryZero(pSiteMgr->hOs, pSiteEntry, sizeof(siteEntry_t)); 339 340 /* This is not required!!!! - Remove!!*/ 341 pSiteEntry->dtimPeriod = 1; 342 pSiteEntry->siteType = SITE_NULL; 343 pSiteEntry->index = index; /* restore the index of the siteTable */ 344 345 /* if removing previous primary site - update the link */ 346 if (pSiteEntry == pSiteMgr->pSitesMgmtParams->pPrevPrimarySite) 347 { 348 pSiteMgr->pSitesMgmtParams->pPrevPrimarySite = NULL; 349 } 350 351 return; 352} 353 354