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 ************************************************************************
77 DESCRIPTION: reset the following things:
78 - Mgmt parameters structure
79 - Site table
80 - Hash table
81 - Primary site pointer
82 - Number of sites
83
84 INPUT: hSiteMgr - Handle to site mgr
85
86
87 OUTPUT:
88
89 RETURN: TI_OK
90
91 ************************************************************************/
siteMgr_resetSiteTable(TI_HANDLE hSiteMgr,siteTablesParams_t * pSiteTableParams)92 TI_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 ************************************************************************
117 DESCRIPTION: 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
123 INPUT: pSiteMgr - Handle to site mgr
124 mac - The site BSSID
125
126
127 OUTPUT:
128
129 RETURN: Pointer to the site entry if site found, NULL otherwise
130
131 ************************************************************************/
findSiteEntry(siteMgr_t * pSiteMgr,TMacAddr * mac)132 siteEntry_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 {
149 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]);
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
170 TRACE6(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 ************************************************************************
179 DESCRIPTION: 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
187 INPUT: pSiteMgr - Handle to site mgr
188 mac - The site BSSID
189 band - The site band
190
191
192 OUTPUT:
193
194 RETURN: Pointer to the site entry if site found/inserted, NULL otherwise
195
196 ************************************************************************/
findAndInsertSiteEntry(siteMgr_t * pSiteMgr,TMacAddr * mac,ERadioBand band)197 siteEntry_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
288 TRACE8(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 ************************************************************************
297 DESCRIPTION: Removes the site entry from the site table
298
299 INPUT: pSiteMgr - Handle to site mgr
300 pCurrSiteTblParams - Pointer to current site table parameters
301 hashPtr - Pointer to the site entry
302
303
304 OUTPUT:
305
306 RETURN:
307
308 ************************************************************************/
removeSiteEntry(siteMgr_t * pSiteMgr,siteTablesParams_t * pCurrSiteTblParams,siteEntry_t * pSiteEntry)309 void removeSiteEntry(siteMgr_t *pSiteMgr,
310 siteTablesParams_t *pCurrSiteTblParams,
311 siteEntry_t *pSiteEntry)
312 {
313 TI_UINT8 index;
314
315 if (pSiteEntry == NULL)
316 {
317 TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "REMOVAL failure, site is NULL\n\n");
318 return;
319 }
320
321 if (pCurrSiteTblParams->numOfSites == 0)
322 {
323 TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "REMOVAL failure, site table is empty\n\n");
324 return;
325 }
326
327 TRACE6(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
333 TRACE6(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]);
334 TRACE1(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