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