assocSM.c revision 45544f73189f4649d4afb21a0dab72cd70971e2f
1/** \file assocSM.c
2 *  \brief 802.11 association SM source
3 *
4 *  \see assocSM.h
5 */
6
7/****************************************************************************
8**+-----------------------------------------------------------------------+**
9**|                                                                       |**
10**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
11**| All rights reserved.                                                  |**
12**|                                                                       |**
13**| Redistribution and use in source and binary forms, with or without    |**
14**| modification, are permitted provided that the following conditions    |**
15**| are met:                                                              |**
16**|                                                                       |**
17**|  * Redistributions of source code must retain the above copyright     |**
18**|    notice, this list of conditions and the following disclaimer.      |**
19**|  * Redistributions in binary form must reproduce the above copyright  |**
20**|    notice, this list of conditions and the following disclaimer in    |**
21**|    the documentation and/or other materials provided with the         |**
22**|    distribution.                                                      |**
23**|  * Neither the name Texas Instruments nor the names of its            |**
24**|    contributors may be used to endorse or promote products derived    |**
25**|    from this software without specific prior written permission.      |**
26**|                                                                       |**
27**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
28**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
29**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
30**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
31**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
32**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
33**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
34**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
35**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
36**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
37**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
38**|                                                                       |**
39**+-----------------------------------------------------------------------+**
40****************************************************************************/
41
42/***************************************************************************/
43/*																		   */
44/*		MODULE:	assocSM.c												   */
45/*    PURPOSE:	802.11 association SM source							   */
46/*																	 	   */
47/***************************************************************************/
48
49#include "osApi.h"
50
51#include "paramOut.h"
52#include "paramIn.h"
53
54#include "utils.h"
55#include "fsm.h"
56#include "report.h"
57
58#include "DataCtrl_Api.h"
59#include "siteMgrApi.h"
60#include "rsnApi.h"
61#include "regulatoryDomainApi.h"
62
63#include "mlmeBuilder.h"
64
65#include "mlmeApi.h"
66
67#include "AssocSM.h"
68#include "qosMngr_API.h"
69#ifdef EXC_MODULE_INCLUDED
70#include "excRMMngr.h"
71#include "excMngr.h"
72#endif
73#include "apConn.h"
74
75/* Constants */
76
77/** number of states in the state machine */
78#define	ASSOC_SM_NUM_STATES		3
79
80/** number of events in the state machine */
81#define	ASSOC_SM_NUM_EVENTS		6
82
83/* Enumerations */
84
85/* Typedefs */
86
87/* Structures */
88
89/* External data definitions */
90
91/* External functions definitions */
92
93/* Global variables */
94
95/* Local function prototypes */
96
97/* functions */
98
99
100/* state machine functions */
101
102
103TI_STATUS assoc_smEvent(assoc_t *pAssoc, UINT8 event, void *pData);
104
105void assoc_smTimeout(TI_HANDLE hAssoc);
106
107TI_STATUS assoc_smStartIdle(assoc_t *pAssoc);
108TI_STATUS assoc_smStopWait(assoc_t *pAssoc);
109TI_STATUS assoc_smSuccessWait(assoc_t *pAssoc);
110TI_STATUS assoc_smFailureWait(assoc_t *pAssoc);
111TI_STATUS assoc_smTimeoutWait(assoc_t *pAssoc);
112TI_STATUS assoc_smMaxRetryWait(assoc_t *pAssoc);
113TI_STATUS assoc_smStopAssoc(assoc_t *pAssoc);
114TI_STATUS assoc_smActionUnexpected(assoc_t *pAssoc);
115
116TI_STATUS assoc_smResetRetry(assoc_t *pAssoc);
117TI_STATUS assoc_smIncRetry(assoc_t *pAssoc);
118TI_STATUS assoc_smReportSuccess(assoc_t *pAssoc);
119TI_STATUS assoc_smReportFailure(assoc_t *pAssoc, UINT16 uStatusCode);
120TI_STATUS assoc_smSendAssocReq(assoc_t *pAssoc);
121TI_STATUS assoc_smStartTimer(assoc_t *pAssoc);
122TI_STATUS assoc_smStopTimer(assoc_t *pAssoc);
123
124TI_STATUS assoc_smCapBuild(assoc_t *pCtx, UINT16 *cap);
125TI_STATUS assoc_smSSIDBuild(assoc_t *pCtx, UINT8 *pSSID, UINT32 *ssidLen);
126TI_STATUS assoc_smRatesBuild(assoc_t *pCtx, UINT8 *pRates, UINT32 *ratesLen);
127TI_STATUS assoc_smRequestBuild(assoc_t *pCtx, UINT8* reqBuf, UINT32* reqLen);
128#ifdef SUPPORT_4X
129TI_STATUS assoc_4xBuild(assoc_t *pCtx, UINT8 *fourX, UINT32 *fourXLen);
130#endif
131
132TI_STATUS assoc_saveAssocReqMessage(assoc_t *pAssocSm, UINT8 *pAssocBuffer, UINT32 length);
133TI_STATUS assoc_sendDisAssoc(assoc_t *pAssocSm, mgmtStatus_e reason);
134
135/**
136*
137* assoc_create - allocate memory for association SM
138*
139* \b Description:
140*
141* Allocate memory for association SM. \n
142* 		Allocates memory for Association context. \n
143* 		Allocates memory for association timer. \n
144* 		Allocates memory for association SM matrix. \n
145*
146* \b ARGS:
147*
148*  I   - hOs - OS context  \n
149*
150* \b RETURNS:
151*
152*  OK if successful, NOK otherwise.
153*
154* \sa rsn_mainSecSmKeysOnlyStop()
155*/
156TI_HANDLE assoc_create(TI_HANDLE hOs)
157{
158	assoc_t 	*pHandle;
159	TI_STATUS		status;
160
161	/* allocate association context memory */
162	pHandle = (assoc_t*)os_memoryAlloc(hOs, sizeof(assoc_t));
163	if (pHandle == NULL)
164	{
165		return NULL;
166	}
167
168	os_memoryZero(hOs, pHandle, sizeof(assoc_t));
169
170	pHandle->hOs = hOs;
171
172	/* allocate memory for association state machine */
173	status = fsm_Create(hOs, &pHandle->pAssocSm, ASSOC_SM_NUM_STATES, ASSOC_SM_NUM_EVENTS);
174	if (status != OK)
175	{
176		os_memoryFree(hOs, pHandle, sizeof(assoc_t));
177		return NULL;
178	}
179
180	/* allocate OS timer memory */
181	pHandle->timer = os_timerCreate(hOs, assoc_smTimeout, pHandle);
182	if (pHandle->timer == NULL)
183	{
184		fsm_Unload(hOs, pHandle->pAssocSm);
185		os_memoryFree(hOs, pHandle, sizeof(assoc_t));
186		return NULL;
187	}
188
189	return pHandle;
190}
191
192
193/**
194*
195* assocunload - unload association SM from memory
196*
197* \b Description:
198*
199* Unload association SM from memory
200*
201* \b ARGS:
202*
203*  I   - hAssoc - association SM context  \n
204*
205* \b RETURNS:
206*
207*  OK if successful, NOK otherwise.
208*
209* \sa rsn_mainSecSmKeysOnlyStop()
210*/
211TI_STATUS assoc_unload(TI_HANDLE hAssoc)
212{
213    TI_STATUS 		status;
214	assoc_t		*pHandle;
215
216	pHandle = (assoc_t*)hAssoc;
217
218	status = fsm_Unload(pHandle->hOs, pHandle->pAssocSm);
219    if (status != OK)
220	{
221		/* report failure but don't stop... */
222		WLAN_REPORT_ERROR(pHandle->hReport, ASSOC_MODULE_LOG,
223				  ("ASSOC_SM: Error releasing FSM memory \n"));
224	}
225
226	os_timerDestroy(pHandle->hOs, pHandle->timer);
227
228	os_memoryFree(pHandle->hOs, hAssoc, sizeof(assoc_t));
229
230	return OK;
231}
232
233/**
234*
235* assoc_config - configure a new association SM
236*
237* \b Description:
238*
239* Configure a new association SM.
240*
241* \b ARGS:
242*
243*  I   - hAssoc - Association SM context  \n
244*  I   - hMlme - MLME SM context  \n
245*  I   - hSiteMgr - Site manager context  \n
246*  I   - hCtrlData - Control data context  \n
247*  I   - hTxData - TX data context  \n
248*  I   - hHalCtrl - Hal control context  \n
249*  I   - hReport - Report context  \n
250*  I   - hOs - OS context  \n
251*  I   - assocTimeout - Association SM timeout \n
252*  I   - assocMaxCount - Max number of association requests to send  \n
253*
254* \b RETURNS:
255*
256*  OK if successful, NOK otherwise.
257*
258* \sa assoc_Create, assoc_Unload
259*/
260TI_STATUS assoc_config(TI_HANDLE hAssoc,
261					TI_HANDLE hMlme,
262					TI_HANDLE hRegulatoryDomain,
263					TI_HANDLE hSiteMgr,
264					TI_HANDLE hCtrlData,
265					TI_HANDLE hTxData,
266					TI_HANDLE hHalCtrl,
267					TI_HANDLE hRsn,
268					TI_HANDLE hReport,
269					TI_HANDLE hOs,
270					TI_HANDLE hExcMngr,
271					TI_HANDLE hQosMngr,
272					TI_HANDLE hMeasurementMgr,
273					TI_HANDLE hApConn,
274					assocInitParams_t	*pAssocInitParams)
275{
276	assoc_t		*pHandle;
277	TI_STATUS		status;
278	/** Main 802.1X State Machine matrix */
279	fsm_actionCell_t	assoc_smMatrix[ASSOC_SM_NUM_STATES][ASSOC_SM_NUM_EVENTS] =
280	{
281		/* next state and actions for IDLE state */
282		{{ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smStartIdle},
283		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
284		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
285		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
286		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
287		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected}
288		},
289		/* next state and actions for WAIT state */
290		{{ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smActionUnexpected},
291		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smStopWait},
292		 {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smSuccessWait},
293		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smFailureWait},
294		 {ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smTimeoutWait},
295		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smMaxRetryWait}
296		},
297		/* next state and actions for ASSOC state */
298		{{ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
299		 {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smStopAssoc},
300		 {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
301		 {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
302		 {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
303		 {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected}
304		}};
305
306
307	if (hAssoc == NULL)
308	{
309		return NOK;
310	}
311
312	pHandle = (assoc_t*)hAssoc;
313
314	/* configure state machine */
315	status = fsm_Config(pHandle->pAssocSm, &assoc_smMatrix[0][0],
316						ASSOC_SM_NUM_STATES, ASSOC_SM_NUM_EVENTS, NULL, hOs);
317	if (status != OK)
318	{
319		return NOK;
320	}
321
322	pHandle->assocRejectCount = 0;
323	pHandle->assocTimeoutCount = 0;
324
325	pHandle->currentState = ASSOC_SM_STATE_IDLE;
326
327	pHandle->hMlme = hMlme;
328	pHandle->hRegulatoryDomain = hRegulatoryDomain;
329	pHandle->hSiteMgr = hSiteMgr;
330	pHandle->hCtrlData = hCtrlData;
331	pHandle->hTxData = hTxData;
332	pHandle->hHalCtrl = hHalCtrl;
333	pHandle->hRsn = hRsn;
334	pHandle->hReport = hReport;
335	pHandle->hOs = hOs;
336	pHandle->hExcMngr = hExcMngr;
337	pHandle->hQosMngr = hQosMngr;
338    pHandle->hMeasurementMgr = hMeasurementMgr;
339	pHandle->hApConn = hApConn;
340
341	pHandle->timeout = pAssocInitParams->assocResponseTimeout;
342	pHandle->maxCount = pAssocInitParams->assocMaxRetryCount;
343
344	return OK;
345}
346
347
348/**
349*
350* assoc_start - Start event for the association SM
351*
352* \b Description:
353*
354* Start event for the association SM
355*
356* \b ARGS:
357*
358*  I   - hAssoc - Association SM context  \n
359*
360* \b RETURNS:
361*
362*  OK if successful, NOK otherwise.
363*
364* \sa assoc_Stop, assoc_Recv
365*/
366TI_STATUS assoc_start(TI_HANDLE hAssoc)
367{
368	TI_STATUS 		status;
369	assoc_t		*pHandle;
370
371	pHandle = (assoc_t*)hAssoc;
372
373	if (pHandle == NULL)
374	{
375		return NOK;
376	}
377
378	pHandle->reAssoc = FALSE;
379
380	pHandle->disAssoc = FALSE;
381
382	status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_START, hAssoc);
383
384	return status;
385}
386
387
388/**
389*
390* assoc_start - Start event for the association SM
391*
392* \b Description:
393*
394* Start event for the association SM - for Re-assoc request
395*
396* \b ARGS:
397*
398*  I   - hAssoc - Association SM context  \n
399*
400* \b RETURNS:
401*
402*  OK if successful, NOK otherwise.
403*
404* \sa assoc_Stop, assoc_Recv
405*/
406TI_STATUS reassoc_start(TI_HANDLE hAssoc)
407{
408	TI_STATUS 		status;
409	assoc_t		*pHandle;
410
411	pHandle = (assoc_t*)hAssoc;
412
413	if (pHandle == NULL)
414	{
415		return NOK;
416	}
417	pHandle->reAssoc = TRUE;
418
419	status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_START, hAssoc);
420
421	return status;
422}
423
424/**
425*
426* assoc_stop - Stop event for the association SM
427*
428* \b Description:
429*
430* Stop event for the association SM
431*
432* \b ARGS:
433*
434*  I   - hAssoc - Association SM context  \n
435*
436* \b RETURNS:
437*
438*  OK if successful, NOK otherwise.
439*
440* \sa assoc_Start, assoc_Recv
441*/
442TI_STATUS assoc_stop(TI_HANDLE hAssoc)
443{
444	TI_STATUS 		status;
445	assoc_t		*pHandle;
446
447	pHandle = (assoc_t*)hAssoc;
448
449	if (pHandle == NULL)
450	{
451		return NOK;
452	}
453
454	status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_STOP, hAssoc);
455
456	return status;
457}
458
459
460TI_STATUS assoc_setDisAssocFlag(TI_HANDLE hAssoc, BOOL disAsoccFlag)
461{
462	assoc_t		*pHandle;
463	pHandle = (assoc_t*)hAssoc;
464
465	pHandle->disAssoc = disAsoccFlag;
466
467	return OK;
468}
469
470
471
472/**
473*
474* assoc_recv - Recive a message from the AP
475*
476* \b Description:
477*
478* Parse a message form the AP and perform the appropriate event.
479*
480* \b ARGS:
481*
482*  I   - hAssoc - Association SM context  \n
483*  I   - pFrame - Frame recieved  \n
484*
485* \b RETURNS:
486*
487*  OK if successful, NOK otherwise.
488*
489* \sa assoc_Start, assoc_Stop
490*/
491TI_STATUS assoc_recv(TI_HANDLE hAssoc, mlmeFrameInfo_t *pFrame)
492{
493	TI_STATUS 		status;
494	assoc_t			*pHandle;
495	whalParamInfo_t		whalParam;
496	UINT16			rspStatus;
497
498	pHandle = (assoc_t*)hAssoc;
499
500	/* ensure that the SM is waiting for assoc response */
501	if(pHandle->currentState != ASSOC_SM_STATE_WAIT)
502		return OK;
503
504	if (pHandle == NULL)
505	{
506		return NOK;
507	}
508
509	if ((pFrame->subType != ASSOC_RESPONSE) && (pFrame->subType != RE_ASSOC_RESPONSE))
510	{
511		return NOK;
512	}
513
514    /* check response status */
515	rspStatus  = pFrame->content.assocRsp.status;
516
517	if (rspStatus == 0)
518	{
519		rsnData_t	rsnData;
520        dot11_RSN_t *pRsnIe;
521        UINT8       curRsnData[255];
522        UINT8       rsnAssocIeLen;
523        UINT16      length=0;
524
525
526        WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
527				  ("ASSOC_SM: DEBUG Success associating to AP \n"));
528
529		/* set AID to HAL */
530		whalParam.paramType = HAL_CTRL_AID_PARAM;
531		whalParam.content.halCtrlAid  = pFrame->content.assocRsp.aid;
532		whalCtrl_SetParam(pHandle->hHalCtrl, &whalParam);
533
534
535        /* Get the RSN IE data */
536        pRsnIe = pFrame->content.assocRsp.pRsnIe;
537        while ((length < pFrame->content.assocRsp.rsnIeLen) && (pFrame->content.assocRsp.rsnIeLen < 255))
538        {
539            if ((pRsnIe->hdr.eleLen + length + 2) > 255) { /* Dm: Security fix */
540                WLAN_REPORT_ERROR(pHandle->hReport, ASSOC_MODULE_LOG,
541                                  ("%s - Security Error: %u > 255\n", __FUNCTION__,(pRsnIe->hdr.eleLen + length + 2)));
542                break;
543            }
544            curRsnData[0+length] = pRsnIe->hdr.eleId;
545            curRsnData[1+length] = pRsnIe->hdr.eleLen;
546            os_memoryCopy(pHandle->hOs, &curRsnData[2+length], (void *)pRsnIe->rsnIeData, pRsnIe->hdr.eleLen);
547            length += pRsnIe->hdr.eleLen+2;
548            pRsnIe += 1;
549        }
550
551		if (pFrame->content.assocRsp.rsnIeLen != 0)
552		{
553			rsnData.pIe = curRsnData;
554			rsnData.ieLen = pFrame->content.assocRsp.rsnIeLen;
555			rsnData.privacy =  ((pFrame->content.assocRsp.capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TRUE : FALSE;
556			rsn_setSite(pHandle->hRsn, &rsnData, NULL, &rsnAssocIeLen);
557		}
558
559		/* update siteMgr with capabilities and whether we are connected to Cisco AP */
560		siteMgr_assocReport(pHandle->hSiteMgr,
561							pFrame->content.assocRsp.capabilities, pFrame->content.assocRsp.ciscoIEPresent);
562
563		/* update 4x info element */
564		ctrlData_setSite(pHandle->hCtrlData, pFrame->content.assocRsp.fourXParams);
565
566        /* update QoS Manager - it the QOS active protocol is NONE, or no WME IE present, it will return OK */
567		/* if configured by AP, update MSDU lifetime */
568        status = qosMngr_setSite(pHandle->hQosMngr, &pFrame->content.assocRsp);
569
570        if(status != OK)
571        {
572			WLAN_REPORT_ERROR(pHandle->hReport, ASSOC_MODULE_LOG,
573					  ("ASSOC_SM: DEBUG - Association failed : qosMngr_setSite error \n"));
574			/* in case we wanted to work with qosAP and failed to connect to qos AP we want to reassociated again
575			   to another one */
576			status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_FAIL, hAssoc);
577        }
578		else
579		{
580			status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_SUCCESS, hAssoc);
581		}
582	}
583	else
584	{
585		pHandle->assocRejectCount++;
586
587		/* If there was attempt to renegotiate voice settings, update QoS Manager */
588		qosMngr_checkTspecRenegResults(pHandle->hQosMngr, &pFrame->content.assocRsp);
589
590		/* check failure reason */
591		switch (rspStatus)
592		{
593		case 0:
594			break;
595		case 1:
596			/* print debug message */
597			WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
598							  ("ASSOC_SM: DEBUG - Association denied: Unspecified error \n"));
599			break;
600		case 10:
601			/* print debug message */
602			WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
603							  ("ASSOC_SM: DEBUG - Association denied: Cannot support all requested capabilities in the Capability Information field \n"));
604			break;
605		case 11:
606			/* print debug message */
607			WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
608							  ("ASSOC_SM: DEBUG - Association denied: Reassociation denied due to inability to confirm that association exists \n"));
609			break;
610		case 12:
611			/* print debug message */
612			WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
613							  ("ASSOC_SM: DEBUG - Association denied: Association denied due to reason outside the scope of this standard \n"));
614			rsn_reportAuthFailure(pHandle->hRsn, RSN_AUTH_STATUS_INVALID_TYPE);
615            break;
616        case 13:
617			WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
618							  ("ASSOC_SM: DEBUG - Association denied: Association denied due to wrong authentication algorithm \n"));
619			rsn_reportAuthFailure(pHandle->hRsn, RSN_AUTH_STATUS_INVALID_TYPE);
620            break;
621		case 17:
622			/* print debug message */
623			WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
624							  ("ASSOC_SM: DEBUG - Association denied: Association denied because AP is unable to handle additional associated stations \n"));
625			break;
626		case 18:
627			/* print debug message */
628			WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
629							  ("ASSOC_SM: DEBUG - Association denied: Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter \n"));
630			break;
631		default:
632			/* print error message on wrong error code for association response */
633			WLAN_REPORT_ERROR(pHandle->hReport, ASSOC_MODULE_LOG,
634							  ("ASSOC_SM: ERROR - Association denied: error code (%d) irrelevant \n", rspStatus));
635			break;
636		}
637
638		status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_FAIL, hAssoc);
639	}
640
641	return status;
642}
643
644/**
645*
646* assoc_getParam - Get a specific parameter from the association SM
647*
648* \b Description:
649*
650* Get a specific parameter from the association SM.
651*
652* \b ARGS:
653*
654*  I   - hAssoc - Association SM context  \n
655*  I/O - pParam - Parameter \n
656*
657* \b RETURNS:
658*
659*  OK if successful, NOK otherwise.
660*
661* \sa assoc_Start, assoc_Stop
662*/
663TI_STATUS assoc_getParam(TI_HANDLE hAssoc, paramInfo_t *pParam)
664{
665	assoc_t		*pHandle;
666
667	pHandle = (assoc_t*)hAssoc;
668
669	if ((pHandle == NULL) || (pParam == NULL))
670	{
671		return NOK;
672	}
673
674	/* serch parameter type */
675	switch (pParam->paramType)
676	{
677	case ASSOC_RESPONSE_TIMEOUT_PARAM:
678		pParam->content.assocResponseTimeout = pHandle->timeout;
679		break;
680
681	case ASSOC_COUNTERS_PARAM:
682		pParam->content.siteMgrTiWlanCounters.AssocRejects = pHandle->assocRejectCount;
683		pParam->content.siteMgrTiWlanCounters.AssocTimeouts = pHandle->assocTimeoutCount;
684		break;
685
686	case ASSOC_ASSOCIATION_RESP_PARAM:
687		pParam->content.applicationConfigBuffer.buffer = pHandle->assocRespBuffer;
688		pParam->content.applicationConfigBuffer.bufferSize = pHandle->assocRespLen;
689		break;
690
691    case ASSOC_ASSOCIATION_INFORMATION_PARAM:
692       {
693           UINT8  reqBuffIEOffset, respBuffIEOffset;
694           UINT32 RequestIELength = 0;
695           UINT32 ResponseIELength = 0;
696		   paramInfo_t	param;
697
698		   WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
699                              ("ASSOC_SM: DEBUG - Association Information Get:  \n"));
700
701		   /* Assoc exists only in Infrastructure */
702		   param.paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
703		   ctrlData_getParam(pHandle->hCtrlData, &param);
704		   if (param.content.ctrlDataCurrentBssType != BSS_INFRASTRUCTURE)
705		   {
706			   WLAN_REPORT_ERROR(pHandle->hReport, ASSOC_MODULE_LOG,
707									 ("Not in Infrastructure BSS, No ASSOC Info for GET ASSOC_ASSOCIATION_INFORMATION_PARAM\n"));
708			   return NOK;
709		   }
710
711           /* Init the result buffer to 0 */
712           os_memoryZero(pHandle->hOs ,&pParam->content, sizeof(OS_802_11_ASSOCIATION_INFORMATION));
713
714           reqBuffIEOffset  = 4;  /* In Assoc request frame IEs are located from byte 4 */
715           respBuffIEOffset = 6;  /* In Assoc response frame the IEs are located from byte 6 */
716
717            /* If the last associate was re-associciation, the current AP MAC address */
718            /* is placed before the IEs. Copy it to the result parameters.            */
719            if (pHandle->reAssoc)
720    	    {
721                os_memoryCopy(pHandle->hOs,
722                              (void *)pParam->content.assocAssociationInformation.RequestFixedIEs.CurrentAPAddress,
723                              &pHandle->assocReqBuffer[reqBuffIEOffset], MAC_ADDR_LEN);
724                reqBuffIEOffset += MAC_ADDR_LEN;
725            }
726
727            /* Calculate length of Info elements in assoc request and response frames */
728            if(pHandle->assocReqLen > reqBuffIEOffset)
729                RequestIELength = pHandle->assocReqLen - reqBuffIEOffset;
730
731            if(pHandle->assocRespLen > respBuffIEOffset)
732                ResponseIELength = pHandle->assocRespLen - respBuffIEOffset;
733
734            /* Copy the association request information */
735            pParam->content.assocAssociationInformation.Length = sizeof(OS_802_11_ASSOCIATION_INFORMATION);
736            pParam->content.assocAssociationInformation.AvailableRequestFixedIEs = OS_802_11_AI_REQFI_CAPABILITIES | OS_802_11_AI_REQFI_LISTENINTERVAL;
737            pParam->content.assocAssociationInformation.RequestFixedIEs.Capabilities = *(UINT16*)&(pHandle->assocReqBuffer[0]);
738            pParam->content.assocAssociationInformation.RequestFixedIEs.ListenInterval = *(UINT16*)(&pHandle->assocReqBuffer[2]);
739
740            pParam->content.assocAssociationInformation.RequestIELength = RequestIELength;
741            pParam->content.assocAssociationInformation.OffsetRequestIEs = 0;
742            if (RequestIELength > 0)
743            {
744                pParam->content.assocAssociationInformation.OffsetRequestIEs = (UINT32)&pHandle->assocReqBuffer[reqBuffIEOffset];
745            }
746            /* Copy the association response information */
747            pParam->content.assocAssociationInformation.AvailableResponseFixedIEs =
748                OS_802_11_AI_RESFI_CAPABILITIES | OS_802_11_AI_RESFI_STATUSCODE | OS_802_11_AI_RESFI_ASSOCIATIONID;
749            pParam->content.assocAssociationInformation.ResponseFixedIEs.Capabilities = *(UINT16*)&(pHandle->assocRespBuffer[0]);
750            pParam->content.assocAssociationInformation.ResponseFixedIEs.StatusCode = *(UINT16*)&(pHandle->assocRespBuffer[2]);
751            pParam->content.assocAssociationInformation.ResponseFixedIEs.AssociationId = *(UINT16*)&(pHandle->assocRespBuffer[4]);
752            pParam->content.assocAssociationInformation.ResponseIELength = ResponseIELength;
753            pParam->content.assocAssociationInformation.OffsetResponseIEs = 0;
754            if (ResponseIELength > 0)
755            {
756                pParam->content.assocAssociationInformation.OffsetResponseIEs = (UINT32)&pHandle->assocRespBuffer[respBuffIEOffset];
757            }
758
759       }
760        break;
761	default:
762		return NOK;
763	}
764
765	return OK;
766}
767
768/**
769*
770* assoc_getParamPartial - Get a specific parameter from the association SM
771*
772* \b Description:
773*
774* Get a specific parameter from the association SM.
775*
776* \b ARGS:
777*
778*  I   - hAssoc - Association SM context  \n
779*  I/O - pParam - Parameter \n
780*
781* \b RETURNS:
782*
783*  OK if successful, NOK otherwise.
784*
785* \sa assoc_Start, assoc_Stop
786*/
787/* note: assoc_getParamPartial() is part of assoc_getParam() it was implemented to reduce Stack usage */
788TI_STATUS assoc_getParamPartial(TI_HANDLE hAssoc, paramInfoPartial_t *pParam)
789{
790	assoc_t		*pHandle;
791
792	pHandle = (assoc_t*)hAssoc;
793
794	if ((pHandle == NULL) || (pParam == NULL))
795	{
796		return NOK;
797	}
798
799	/* serch parameter type */
800	switch (pParam->paramType)
801	{
802    case ASSOC_ASSOCIATION_RESP_PARAM:
803		pParam->content.applicationConfigBuffer.buffer = pHandle->assocRespBuffer;
804		pParam->content.applicationConfigBuffer.bufferSize = pHandle->assocRespLen;
805		break;
806
807	default:
808		WLAN_REPORT_ERROR(pHandle->hReport, ASSOC_MODULE_LOG,
809							  ("assoc_getParamPartial no such entry %d\n",pParam->paramType));
810        return NOK;
811	}
812
813	return OK;
814}
815
816
817/**
818*
819* assoc_setParam - Set a specific parameter to the association SM
820*
821* \b Description:
822*
823* Set a specific parameter to the association SM.
824*
825* \b ARGS:
826*
827*  I   - hAssoc - Association SM context  \n
828*  I/O - pParam - Parameter \n
829*
830* \b RETURNS:
831*
832*  OK if successful, NOK otherwise.
833*
834* \sa assoc_Start, assoc_Stop
835*/
836TI_STATUS assoc_setParam(TI_HANDLE hAssoc, paramInfo_t *pParam)
837{
838	assoc_t		*pHandle;
839
840	pHandle = (assoc_t*)hAssoc;
841
842	if ((pHandle == NULL) || (pParam == NULL))
843	{
844		return NOK;
845	}
846
847	switch (pParam->paramType)
848	{
849	case ASSOC_RESPONSE_TIMEOUT_PARAM:
850		/* check bounds */
851		if ((pParam->content.assocResponseTimeout >= ASSOC_RESPONSE_TIMEOUT_MIN) &&
852			(pParam->content.assocResponseTimeout <= ASSOC_RESPONSE_TIMEOUT_MAX))
853		{
854			pHandle->timeout = pParam->content.assocResponseTimeout;
855		} else {
856			return NOK;
857		}
858		break;
859	default:
860		return NOK;
861	}
862
863	return OK;
864}
865
866/**
867*
868* assoc_smTimeout - Time out event activation function
869*
870* \b Description:
871*
872* Time out event activation function.
873*
874* \b ARGS:
875*
876*  I   - hAssoc - Association SM context  \n
877*
878* \b RETURNS:
879*
880*  OK if successful, NOK otherwise.
881*
882* \sa assoc_Start, assoc_Stop
883*/
884void assoc_smTimeout(TI_HANDLE hAssoc)
885{
886	assoc_t		*pHandle;
887
888	pHandle = (assoc_t*)hAssoc;
889
890
891	if (pHandle == NULL)
892	{
893		return;
894	}
895
896	pHandle->assocTimeoutCount++;
897
898	assoc_smEvent(pHandle, ASSOC_SM_EVENT_TIMEOUT, hAssoc);
899}
900
901/**
902*
903* assoc_smEvent - Perform an event on the association SM
904*
905* \b Description:
906*
907* Perform an event on the association SM.
908*
909* \b ARGS:
910*
911*  I   - pAssoc - Association SM context  \n
912*  I   - event - Current event \n
913*  I   - pData - event related data
914*
915* \b RETURNS:
916*
917*  OK if successful, NOK otherwise.
918*
919* \sa
920*/
921
922#ifdef REPORT_LOG
923
924static char *assocSMStateDesc[ASSOC_SM_NUM_STATES] = {
925		"ASSOC_SM_STATE_IDLE",
926		"ASSOC_SM_STATE_WAIT",
927		"ASSOC_SM_STATE_ASSOC",
928	};
929
930/* State machine inputs */
931static char *assocSMEventDesc[ASSOC_SM_NUM_EVENTS] = {
932		"ASSOC_SM_EVENT_START",
933		"ASSOC_SM_EVENT_STOP",
934		"ASSOC_SM_EVENT_SUCCESS",
935		"ASSOC_SM_EVENT_FAILURE",
936		"ASSOC_SM_EVENT_TIME_OUT",
937		"ASSOC_SM_EVENT_MAX_RETRY"
938	};
939
940#endif
941
942TI_STATUS assoc_smEvent(assoc_t *pAssoc, UINT8 event, void *pData)
943{
944	TI_STATUS 		status;
945	UINT8		nextState;
946
947	status = fsm_GetNextState(pAssoc->pAssocSm, pAssoc->currentState, event, &nextState);
948	if (status != OK)
949	{
950		WLAN_REPORT_ERROR(pAssoc->hReport, ASSOC_MODULE_LOG,
951						  ("ASSOC_SM: ERROR - failed getting next state \n"));
952
953		return(NOK);
954	}
955
956	WLAN_REPORT_SM(pAssoc->hReport, ASSOC_MODULE_LOG,
957					 ("ASSOC_SM: <%s, %s> --> %s\n",
958					  assocSMStateDesc[pAssoc->currentState],
959					  assocSMEventDesc[event],
960					  assocSMStateDesc[nextState]));
961
962	status = fsm_Event(pAssoc->pAssocSm, &pAssoc->currentState, event, pData);
963
964	return(status);
965}
966
967/* state machine functions */
968
969TI_STATUS assoc_smStartIdle(assoc_t *pAssoc)
970{
971	TI_STATUS		status;
972
973	status = assoc_smResetRetry(pAssoc);
974	status = assoc_smSendAssocReq(pAssoc);
975	status = assoc_smStartTimer(pAssoc);
976	status = assoc_smIncRetry(pAssoc);
977
978	return status;
979}
980
981TI_STATUS assoc_smStopWait(assoc_t *pAssoc)
982{
983	TI_STATUS		status;
984
985	status = assoc_smStopTimer(pAssoc);
986
987	return status;
988}
989
990TI_STATUS assoc_smSuccessWait(assoc_t *pAssoc)
991{
992	TI_STATUS		status;
993
994	status = assoc_smStopTimer(pAssoc);
995	status = assoc_smReportSuccess(pAssoc);
996
997	return status;
998}
999
1000TI_STATUS assoc_smFailureWait(assoc_t *pAssoc)
1001{
1002	TI_STATUS		status;
1003	UINT16			uRspStatus = *(UINT16*)&(pAssoc->assocRespBuffer[2]);
1004
1005	status = assoc_smStopTimer(pAssoc);
1006
1007	/* Sanity check. If the Response status is indeed not 0 */
1008	if (uRspStatus)
1009	{
1010		status = assoc_smReportFailure(pAssoc, uRspStatus);
1011	}
1012	else	/* (uRspStatus == 0) how did we get here ? */
1013	{
1014		WLAN_REPORT_ERROR(pAssoc->hReport, ASSOC_MODULE_LOG,
1015			("assoc_smFailureWait: while Response status is OK (0) !!! \n"));
1016
1017		status = assoc_smReportFailure(pAssoc, (UINT16)NOK);
1018	}
1019	return status;
1020}
1021
1022TI_STATUS assoc_smTimeoutWait(assoc_t *pAssoc)
1023{
1024	TI_STATUS		status;
1025
1026	status = assoc_smSendAssocReq(pAssoc);
1027	status = assoc_smStartTimer(pAssoc);
1028	status = assoc_smIncRetry(pAssoc);
1029
1030	return status;
1031}
1032
1033TI_STATUS assoc_smMaxRetryWait(assoc_t *pAssoc)
1034{
1035	TI_STATUS		status;
1036
1037	status = assoc_smStopTimer(pAssoc);
1038	status = assoc_smReportFailure(pAssoc, STATUS_PACKET_REJ_TIMEOUT);
1039
1040	return status;
1041}
1042
1043TI_STATUS assoc_smSendAssocReq(assoc_t *pAssoc)
1044{
1045	UINT8 				assocMsg[MAX_ASSOC_MSG_LENGTH];
1046	UINT32				msgLen;
1047	TI_STATUS			status;
1048	dot11MgmtSubType_e	assocType=ASSOC_REQUEST;
1049
1050	if (pAssoc->reAssoc)
1051	{
1052		assocType = RE_ASSOC_REQUEST;
1053	}
1054	status = assoc_smRequestBuild(pAssoc, assocMsg, &msgLen);
1055	if (status != OK)
1056		return status;
1057
1058    /* Save the association request message */
1059	assoc_saveAssocReqMessage(pAssoc, assocMsg, msgLen);
1060	status = mlmeBuilder_sendFrame(pAssoc->hMlme, assocType, assocMsg, msgLen, 0);
1061
1062	return status;
1063}
1064
1065TI_STATUS assoc_smStopAssoc(assoc_t *pAssoc)
1066{
1067	if (pAssoc->disAssoc) {
1068		assoc_sendDisAssoc(pAssoc, STATUS_UNSPECIFIED);
1069	}
1070	return OK;
1071}
1072
1073TI_STATUS assoc_smActionUnexpected(assoc_t *pAssoc)
1074{
1075	return OK;
1076}
1077
1078/* local functions */
1079
1080
1081TI_STATUS assoc_smResetRetry(assoc_t *pAssoc)
1082{
1083	if (pAssoc == NULL)
1084	{
1085		return NOK;
1086	}
1087
1088	pAssoc->retryCount = 0;
1089
1090	return OK;
1091}
1092
1093TI_STATUS assoc_smIncRetry(assoc_t *pAssoc)
1094{
1095	TI_STATUS		status;
1096
1097	if (pAssoc == NULL)
1098	{
1099		return NOK;
1100	}
1101
1102	pAssoc->retryCount++;
1103
1104	if (pAssoc->retryCount > pAssoc->maxCount)
1105	{
1106		status = assoc_smEvent(pAssoc, ASSOC_SM_EVENT_MAX_RETRY, pAssoc);
1107
1108		return status;
1109	}
1110
1111	return OK;
1112}
1113
1114TI_STATUS assoc_smReportSuccess(assoc_t *pAssoc)
1115{
1116	TI_STATUS 		status;
1117
1118	if (pAssoc == NULL)
1119	{
1120		return NOK;
1121	}
1122	status = mlme_reportAssocStatus(pAssoc->hMlme, (UINT16)OK);
1123
1124	return status;
1125}
1126
1127TI_STATUS assoc_smReportFailure(assoc_t *pAssoc, UINT16 uStatusCode)
1128{
1129	TI_STATUS 		status;
1130
1131	if (pAssoc == NULL)
1132	{
1133		return NOK;
1134	}
1135
1136	status = mlme_reportAssocStatus(pAssoc->hMlme, uStatusCode);
1137
1138	return status;
1139}
1140
1141TI_STATUS assoc_smStartTimer(assoc_t *pAssoc)
1142{
1143	if (pAssoc == NULL)
1144	{
1145		return NOK;
1146	}
1147
1148	os_timerStart(pAssoc->hOs, pAssoc->timer, pAssoc->timeout, FALSE);
1149
1150	return OK;
1151}
1152
1153TI_STATUS assoc_smStopTimer(assoc_t *pAssoc)
1154{
1155	if (pAssoc == NULL)
1156	{
1157		return NOK;
1158	}
1159
1160	os_timerStop(pAssoc->hOs, pAssoc->timer);
1161
1162	return OK;
1163}
1164
1165/*****************************************************************************
1166**
1167** Association messages builder/Parser
1168**
1169*****************************************************************************/
1170
1171TI_STATUS assoc_smCapBuild(assoc_t *pCtx, UINT16 *cap)
1172{
1173	paramInfo_t			param;
1174	TI_STATUS			status;
1175    dot11mode_e         mode;
1176	UINT32				rateSuppMask, rateBasicMask;
1177	UINT8				ratesBuf[MAX_SUPPORTED_RATES];
1178	UINT32				len = 0, ofdmIndex = 0;
1179
1180	*cap = 0;
1181
1182	/* Bss type */
1183    param.paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
1184	status =  ctrlData_getParam(pCtx->hCtrlData, &param);
1185	if (status == OK)
1186	{
1187		if (param.content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE)
1188		{
1189			*cap |= DOT11_CAPS_ESS;
1190		} else {
1191			*cap |= DOT11_CAPS_IBSS;
1192		}
1193	} else {
1194		return NOK;
1195	}
1196
1197	/* Privacy */
1198    param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
1199	status =  rsn_getParam(pCtx->hRsn, &param);
1200	if (status == OK)
1201	{
1202		if (param.content.rsnEncryptionStatus != RSN_CIPHER_NONE)
1203		{
1204			*cap |= DOT11_CAPS_PRIVACY;
1205		}
1206	} else {
1207		return NOK;
1208	}
1209
1210	/* Preamble */
1211    param.paramType = SITE_MGR_DESIRED_PREAMBLE_TYPE_PARAM;
1212	status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1213	if (status == OK)
1214	{
1215		if (param.content.siteMgrCurrentPreambleType == PREAMBLE_SHORT)
1216			*cap |= DOT11_CAPS_SHORT_PREAMBLE;
1217	} else {
1218		return NOK;
1219	}
1220
1221	/* Pbcc */
1222    param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
1223	status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1224	if (status == OK)
1225	{
1226		if(param.content.siteMgrCurrentRateMask.supportedRateMask & DRV_RATE_MASK_22_PBCC)
1227			*cap |= DOT11_CAPS_PBCC;
1228	} else {
1229		return NOK;
1230	}
1231
1232
1233	/* Checking if the station supports Spectrum Management (802.11h) */
1234	param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
1235	status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
1236	if (status == OK )
1237	{
1238		if( param.content.spectrumManagementEnabled)
1239			*cap |= DOT11_SPECTRUM_MANAGEMENT;
1240	}
1241	else
1242	{
1243		return NOK;
1244	}
1245
1246	/* slot time */
1247    param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
1248    status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1249    if(status == OK)
1250    {
1251        mode = param.content.siteMgrDot11OperationalMode;
1252    }
1253    else
1254        return NOK;
1255
1256    if(mode == DOT11_G_MODE)
1257    {
1258		/* new requirement: the short slot time should be set only
1259		   if the AP's modulation is OFDM (highest rate) */
1260
1261		/* get Rates */
1262		param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
1263		status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1264		if (status == OK)
1265		{
1266			rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask;
1267			rateSuppMask  = param.content.siteMgrCurrentRateMask.supportedRateMask;
1268		} else {
1269			return NOK;
1270		}
1271
1272		/* convert the bit map to the rates array */
1273		bitMapToNetworkStringRates(rateSuppMask, rateBasicMask,
1274								   ratesBuf, &len, &ofdmIndex);
1275
1276		if(ofdmIndex < len)
1277			*cap |= DOT11_CAPS_SHORT_SLOT_TIME;
1278
1279/*
1280		param.paramType = SITE_MGR_CURRENT_MODULATION_TYPE_PARAM;
1281		status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1282		if(param.content.siteMgrCurrentModulationType == DRV_MODULATION_OFDM)
1283			*cap |= DOT11_CAPS_SHORT_SLOT_TIME;
1284*/
1285    }
1286
1287    /* Qos Support - (is WME on?)*/
1288    param.paramType = QOS_MNGR_ACTIVE_PROTOCOL;
1289    status = qosMngr_getParams(pCtx->hQosMngr, &param);
1290    if (status == OK)
1291    {
1292      if (param.content.qosSiteProtocol !=  NONE_QOS)
1293      {
1294         // *cap |= DOT11_CAPS_QOS_SUPPORTED;  /* deleted due to MCS00035798 */
1295      }
1296    }
1297    else
1298      {
1299	     return NOK;
1300	  }
1301
1302	return OK;
1303}
1304
1305#ifdef SUPPORT_4X
1306TI_STATUS assoc_4xBuild(assoc_t *pCtx, UINT8 *fourX, UINT32 *fourXLen)
1307{
1308
1309	TI_STATUS		status;
1310	dot11_4X_t		*pDot11_4X;
1311	paramInfo_t		param;
1312	BOOL			sts, fourXen;
1313
1314	pDot11_4X = (dot11_4X_t*)fourX;
1315
1316	param.paramType = SITE_MGR_4X_PARAM;
1317	sts = siteMgr_getParam(pCtx->hSiteMgr, &param);
1318	fourXen = param.content.siteMgrFourxParam;
1319	if(sts != OK || fourXen == FALSE)
1320	{
1321		pDot11_4X->hdr.eleId = 0;
1322		pDot11_4X->hdr.eleLen = 0;
1323		*fourXLen = 0;
1324		return OK;
1325	}
1326
1327	status = ctrlData_get4xInfoElemnt(pCtx->hCtrlData, pDot11_4X);
1328	if(status != OK)
1329	{
1330		pDot11_4X->hdr.eleId = 0;
1331		pDot11_4X->hdr.eleLen = 0;
1332		*fourXLen = 0;
1333		return OK;
1334	}
1335
1336	*fourXLen = pDot11_4X->hdr.eleLen + sizeof(dot11_eleHdr_t);
1337
1338	return OK;
1339}
1340#endif
1341TI_STATUS assoc_smSSIDBuild(assoc_t *pCtx, UINT8 *pSSID, UINT32 *ssidLen)
1342{
1343	paramInfo_t			param;
1344	TI_STATUS				status;
1345	dot11_SSID_t		*pDot11Ssid;
1346
1347	pDot11Ssid = (dot11_SSID_t*)pSSID;
1348	/* set SSID element id */
1349	pDot11Ssid->hdr.eleId = SSID_IE_ID;
1350
1351	/* get SSID */
1352    param.paramType = SITE_MGR_DESIRED_SSID_PARAM;
1353	status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1354	if (status != OK)
1355	{
1356		return status;
1357    }
1358
1359    /* check for ANY ssid */
1360    if (param.content.siteMgrDesiredSSID.len != 0)
1361    {
1362        pDot11Ssid->hdr.eleLen = param.content.siteMgrDesiredSSID.len;
1363        os_memoryCopy(pCtx->hOs,
1364                      (void *)pDot11Ssid->serviceSetId,
1365                      (void *)param.content.siteMgrDesiredSSID.ssidString,
1366                      param.content.siteMgrDesiredSSID.len);
1367
1368    } else {
1369        /* if ANY ssid is configured, use the current SSID */
1370        param.paramType = SITE_MGR_CURRENT_SSID_PARAM;
1371        status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1372        if (status != OK)
1373        {
1374            return status;
1375        }
1376        pDot11Ssid->hdr.eleLen = param.content.siteMgrCurrentSSID.len;
1377        os_memoryCopy(pCtx->hOs,
1378                      (void *)pDot11Ssid->serviceSetId,
1379                      (void *)param.content.siteMgrCurrentSSID.ssidString,
1380                      param.content.siteMgrCurrentSSID.len);
1381
1382    }
1383
1384	*ssidLen = pDot11Ssid->hdr.eleLen + sizeof(dot11_eleHdr_t);
1385
1386	return OK;
1387}
1388
1389TI_STATUS assoc_smRatesBuild(assoc_t *pCtx, UINT8 *pRates, UINT32 *ratesLen)
1390{
1391	paramInfo_t			param;
1392	TI_STATUS			status;
1393	UINT32				rateSuppMask, rateBasicMask;
1394	dot11_RATES_t		*pDot11Rates;
1395	UINT32				len = 0, ofdmIndex = 0;
1396	UINT8				ratesBuf[MAX_SUPPORTED_RATES];
1397	BOOL				useESRie;
1398	dot11mode_e			mode;
1399	UINT32				suppRatesLen, extSuppRatesLen, i;
1400	pDot11Rates = (dot11_RATES_t*)pRates;
1401
1402
1403	/* get Rates */
1404    param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
1405	status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1406	if (status == OK)
1407	{
1408		rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask;
1409		rateSuppMask  = param.content.siteMgrCurrentRateMask.supportedRateMask;
1410	} else {
1411		return NOK;
1412	}
1413
1414	/* get operational mode */
1415	param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
1416	status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1417	if(status == OK)
1418		mode = param.content.siteMgrDot11OperationalMode;
1419	else
1420		return NOK;
1421
1422	/* get param indicating whether the ESR IE should be used */
1423	param.paramType = SITE_MGR_USE_DRAFT_NUM_PARAM;
1424	status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1425	if(status == OK)
1426	{
1427		if(param.content.siteMgrUseDraftNum == DRAFT_6_AND_LATER)
1428			useESRie = TRUE;
1429		else
1430			useESRie = FALSE;
1431	}
1432	else
1433		return NOK;
1434
1435	/* convert the bit map to the rates array */
1436	bitMapToNetworkStringRates(rateSuppMask, rateBasicMask,
1437							   ratesBuf, &len, &ofdmIndex);
1438
1439	if(mode != DOT11_G_MODE || ofdmIndex == len || useESRie == FALSE)
1440	{
1441		pDot11Rates->hdr.eleId = SUPPORTED_RATES_IE_ID;
1442		pDot11Rates->hdr.eleLen = len;
1443		os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, len);
1444		*ratesLen = pDot11Rates->hdr.eleLen + sizeof(dot11_eleHdr_t);
1445	}
1446	else
1447	{
1448		/* fill in the supported rates */
1449		pDot11Rates->hdr.eleId = SUPPORTED_RATES_IE_ID;
1450		pDot11Rates->hdr.eleLen = ofdmIndex;
1451		os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr.eleLen);
1452		suppRatesLen = pDot11Rates->hdr.eleLen + sizeof(dot11_eleHdr_t);
1453		/* fill in the extended supported rates */
1454		pDot11Rates = (dot11_RATES_t*)(pRates + suppRatesLen);
1455		pDot11Rates->hdr.eleId = EXT_SUPPORTED_RATES_IE_ID;
1456		pDot11Rates->hdr.eleLen = len - ofdmIndex;
1457		os_memoryCopy(NULL, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr.eleLen);
1458		extSuppRatesLen = pDot11Rates->hdr.eleLen + sizeof(dot11_eleHdr_t);
1459		*ratesLen = suppRatesLen + extSuppRatesLen;
1460	}
1461
1462	WLAN_REPORT_INFORMATION(pCtx->hReport, ASSOC_MODULE_LOG,
1463							("ASSOC_SM: ASSOC_REQ - bitmapSupp= 0x%X,bitMapBasic = 0x%X, len = %d\n",
1464							rateSuppMask,rateBasicMask,len));
1465	for(i=0; i<len; i++)
1466	{
1467		WLAN_REPORT_INFORMATION(pCtx->hReport, ASSOC_MODULE_LOG,("ASSOC_SM: ASSOC_REQ - ratesBuf[%d] = 0x%X\n",
1468								i, ratesBuf[i]));
1469	}
1470
1471	return OK;
1472}
1473
1474TI_STATUS assoc_powerCapabilityBuild(assoc_t *pCtx, UINT8 *pPowerCapability, UINT32 *powerCapabilityLen)
1475{
1476	paramInfo_t			param;
1477	TI_STATUS				status;
1478	dot11_CAPABILITY_t		*pDot11PowerCapability;
1479
1480	pDot11PowerCapability = (dot11_CAPABILITY_t*)pPowerCapability;
1481
1482	/* set Power Capability element id */
1483	pDot11PowerCapability->hdr.eleId = DOT11_CAPABILITY_ELE_ID;
1484	pDot11PowerCapability->hdr.eleLen = DOT11_CAPABILITY_ELE_LEN;
1485
1486	/* get power capability */
1487    param.paramType = REGULATORY_DOMAIN_POWER_CAPABILITY_PARAM;
1488	status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
1489
1490	if (status == OK)
1491	{
1492		pDot11PowerCapability->minTxPower = param.content.powerCapability.minTxPower;
1493		pDot11PowerCapability->maxTxPower = param.content.powerCapability.maxTxPower;
1494		*powerCapabilityLen = pDot11PowerCapability->hdr.eleLen + sizeof(dot11_eleHdr_t);
1495	}
1496	else
1497		*powerCapabilityLen = 0;
1498
1499	return OK;
1500}
1501#if 0
1502	/* Supported Channels IE is not required */
1503
1504TI_STATUS assoc_supportedChannelBuild(assoc_t *pCtx, UINT8 *pSupportedChannels, UINT32 *supportedChannelsLen)
1505{
1506	paramInfo_t						param;
1507	TI_STATUS						status;
1508	dot11_CHANNEL_SUPPORTED_t		*pDot11SupportedChannels;
1509
1510	pDot11SupportedChannels = (dot11_CHANNEL_SUPPORTED_t*)pSupportedChannels;
1511
1512	/* set Supported Channels element id */
1513	pDot11SupportedChannels->hdr.eleId = DOT11_CHANNEL_SUPPORTED_ELE_ID;
1514	pDot11SupportedChannels->hdr.eleLen = 0;
1515
1516    /* get Num of Supported Channels */
1517    param.paramType = REGULATORY_DOMAIN_SUPPORTED_CHANNEL_PAIRS_NUM_PARAM;
1518	status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
1519
1520    if(status == OK)
1521    {
1522        pDot11SupportedChannels->hdr.eleLen = param.content.numOfSupportedChannelPairs * 2;
1523
1524	/* get Supported Channels */
1525    param.paramType = REGULATORY_DOMAIN_SUPPORTED_CHANNEL_PARAM;
1526	status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
1527
1528	if (status == OK)
1529	{
1530
1531            os_memoryCopy(pCtx->hOs,&(pDot11SupportedChannels->supportedChannel[0]),param.content.pSupportedChannel,pDot11SupportedChannels->hdr.eleLen * sizeof(UINT8));
1532		*supportedChannelsLen = pDot11SupportedChannels->hdr.eleLen + sizeof(dot11_eleHdr_t);
1533	}
1534	else
1535		*supportedChannelsLen = 0;
1536    }
1537    else
1538        *supportedChannelsLen = 0;
1539
1540	return OK;
1541}
1542#endif
1543
1544
1545TI_STATUS assoc_smRequestBuild(assoc_t *pCtx, UINT8* reqBuf, UINT32* reqLen)
1546{
1547	TI_STATUS		status;
1548	UINT8			*pRequest;
1549	UINT32			len;
1550	paramInfo_t		param;
1551    whalParamInfo_t whalParam;
1552	UINT16			capabilities;
1553
1554	pRequest = reqBuf;
1555	*reqLen = 0;
1556
1557	/* insert capabilities */
1558	status = assoc_smCapBuild(pCtx, &capabilities);
1559	if (status == OK)
1560	{
1561		*(UINT16*)pRequest = ENDIAN_HANDLE_WORD(capabilities);
1562	}
1563	else
1564		return NOK;
1565
1566	pRequest += 2;
1567	*reqLen += 2;
1568
1569	/* insert listen interval */
1570    whalParam.paramType = HAL_CTRL_LISTEN_INTERVAL_PARAM;
1571	status =  whalCtrl_GetParam(pCtx->hHalCtrl, &whalParam);
1572	if (status == OK)
1573	{
1574		*(UINT16*)pRequest = ENDIAN_HANDLE_WORD((UINT16)whalParam.content.halCtrlListenInterval);
1575	} else {
1576		return NOK;
1577	}
1578
1579	pRequest += 2;
1580	*reqLen += 2;
1581	if (pCtx->reAssoc)
1582	{	/* Insert currentAPAddress element only in reassoc request*/
1583		param.paramType = SITE_MGR_PREV_SITE_BSSID_PARAM;
1584		status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1585		if (status == OK)
1586		{
1587			os_memoryCopy(pCtx->hOs, pRequest, (void *)param.content.siteMgrDesiredBSSID.addr, MAC_ADDR_LEN);
1588			WLAN_REPORT_INFORMATION(pCtx->hReport, ASSOC_MODULE_LOG,
1589									("ASSOC_SM: ASSOC_REQ - prev AP = %x-%x-%x-%x-%x-%x\n",
1590									param.content.siteMgrDesiredBSSID.addr[0], param.content.siteMgrDesiredBSSID.addr[1],
1591									param.content.siteMgrDesiredBSSID.addr[2], param.content.siteMgrDesiredBSSID.addr[3],
1592									param.content.siteMgrDesiredBSSID.addr[4], param.content.siteMgrDesiredBSSID.addr[5]));
1593
1594
1595			pRequest += MAC_ADDR_LEN;
1596			*reqLen += MAC_ADDR_LEN;
1597		}
1598		else
1599		{
1600			WLAN_REPORT_ERROR(pCtx->hReport, ASSOC_MODULE_LOG,
1601									("ASSOC_SM: ASSOC_REQ - No prev AP \n"));
1602			return status;
1603
1604		}
1605	}
1606
1607	/* insert SSID element */
1608	status = assoc_smSSIDBuild(pCtx, pRequest, &len);
1609	if (status != OK)
1610	{
1611		return NOK;
1612	}
1613
1614	pRequest += len;
1615	*reqLen += len;
1616
1617	/* insert Rates element */
1618	status = assoc_smRatesBuild(pCtx, pRequest, &len);
1619	if (status != OK)
1620	{
1621		return NOK;
1622	}
1623	pRequest += len;
1624	*reqLen += len;
1625
1626	/* Checking if the station supports Spectrum Management (802.11h) */
1627	param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
1628	status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain,&param);
1629	if( (status == OK) && param.content.spectrumManagementEnabled)
1630	{
1631		/* Checking the selected AP capablities */
1632		param.paramType = SITE_MGR_SITE_CAPABILITY_PARAM;
1633		status =  siteMgr_getParam(pCtx->hSiteMgr,&param);
1634		if(status == OK && ((param.content.siteMgrSiteCapability & DOT11_SPECTRUM_MANAGEMENT) != 0))
1635		{
1636			/* insert Power capability element */
1637			status = assoc_powerCapabilityBuild(pCtx, pRequest, &len);
1638			if (status != OK)
1639			{
1640				return NOK;
1641			}
1642			pRequest += len;
1643			*reqLen += len;
1644#if 0
1645			/* insert Supported Channels element */
1646			status = assoc_supportedChannelBuild(pCtx, pRequest, &len);
1647			if (status != OK)
1648			{
1649				return NOK;
1650			}
1651			pRequest += len;
1652			*reqLen += len;
1653#endif
1654		}
1655
1656
1657	}
1658
1659	status = qosMngr_getQosCapabiltyInfeElement(pCtx->hQosMngr,pRequest,(UINT8*)&len);
1660	if (status != OK)
1661	{
1662		return NOK;
1663	}
1664	pRequest += len;
1665	*reqLen += len;
1666
1667
1668#ifdef EXC_MODULE_INCLUDED
1669	status = rsn_getExcExtendedInfoElement(pCtx->hRsn, pRequest, (UINT8*)&len);
1670	if (status != OK)
1671	{
1672		return NOK;
1673	}
1674	pRequest += len;
1675	*reqLen += len;
1676
1677	if (pCtx->reAssoc)
1678	{	/* insert CCKM information element only in reassoc */
1679		status = excMngr_getCckmInfoElement(pCtx->hExcMngr, pRequest, (UINT8*)&len);
1680
1681		if (status != OK)
1682		{
1683			return NOK;
1684		}
1685		pRequest += len;
1686		*reqLen += len;
1687	}
1688	status = excMngr_getEXCVersionInfoElement(pCtx->hExcMngr, pRequest, (UINT8*)&len);
1689	if (status != OK)
1690	{
1691		return NOK;
1692	}
1693	pRequest += len;
1694	*reqLen += len;
1695
1696    /* Insert Radio Mngt Capability IE */
1697    status = measurementMgr_radioMngtCapabilityBuild(pCtx->hMeasurementMgr, pRequest, (UINT8*)&len);
1698    if (status != OK)
1699	{
1700		return NOK;
1701	}
1702	pRequest += len;
1703	*reqLen += len;
1704#endif
1705
1706#ifdef SUPPORT_4X
1707	/* insert 4X element */
1708	status = assoc_4xBuild(pCtx, pRequest, &len);
1709	if (status != OK)
1710	{
1711		return NOK;
1712	}
1713	pRequest += len;
1714	*reqLen += len;
1715#endif
1716
1717    /* insert RSN information elements */
1718    status = rsn_getInfoElement(pCtx->hRsn, pRequest, (UINT8*)&len);
1719
1720	if (status != OK)
1721	{
1722		return NOK;
1723	}
1724	pRequest += len;
1725	*reqLen += len;
1726
1727	status = qosMngr_assocReqBuild(pCtx->hQosMngr,pRequest,(UINT8*)&len);
1728	if (status != OK)
1729	{
1730		return NOK;
1731	}
1732	pRequest += len;
1733	*reqLen += len;
1734
1735	status = apConn_getVendorSpecificIE(pCtx->hApConn, pRequest, &len);
1736	if (status != OK)
1737	{
1738		return NOK;
1739	}
1740	pRequest += len;
1741	*reqLen += len;
1742
1743	if (*reqLen>=MAX_ASSOC_MSG_LENGTH)
1744	{
1745		return NOK;
1746	}
1747
1748	return OK;
1749}
1750
1751
1752
1753TI_STATUS assoc_saveAssocRespMessage(assoc_t *pAssocSm, UINT8 *pAssocBuffer, UINT32 length)
1754{
1755    if ((pAssocSm==NULL) || (pAssocBuffer==NULL) || (length>=MAX_ASSOC_MSG_LENGTH))
1756    {
1757        return NOK;
1758    }
1759    os_memoryCopy(pAssocSm->hOs, pAssocSm->assocRespBuffer, pAssocBuffer, length);
1760    pAssocSm->assocRespLen = length;
1761
1762    WLAN_REPORT_INFORMATION(pAssocSm->hReport, ASSOC_MODULE_LOG,
1763                      ("assoc_saveAssocRespMessage: length=%ld \n",length));
1764    return OK;
1765}
1766
1767TI_STATUS assoc_saveAssocReqMessage(assoc_t *pAssocSm, UINT8 *pAssocBuffer, UINT32 length)
1768{
1769
1770    if ((pAssocSm==NULL) || (pAssocBuffer==NULL) || (length>=MAX_ASSOC_MSG_LENGTH))
1771    {
1772        return NOK;
1773    }
1774
1775    os_memoryCopy(pAssocSm->hOs, pAssocSm->assocReqBuffer, pAssocBuffer, length);
1776    pAssocSm->assocReqLen = length;
1777
1778    WLAN_REPORT_INFORMATION(pAssocSm->hReport, ASSOC_MODULE_LOG,
1779                      ("assoc_saveAssocReqMessage: length=%ld \n",length));
1780    return OK;
1781}
1782
1783
1784TI_STATUS assoc_sendDisAssoc(assoc_t *pAssocSm, mgmtStatus_e reason)
1785{
1786	TI_STATUS		status;
1787	disAssoc_t		disAssoc;
1788
1789	if (reason == STATUS_SUCCESSFUL)
1790	{
1791		disAssoc.reason = ENDIAN_HANDLE_WORD(STATUS_UNSPECIFIED);
1792	} else {
1793		disAssoc.reason = ENDIAN_HANDLE_WORD(reason);
1794	}
1795
1796	status = mlmeBuilder_sendFrame(pAssocSm->hMlme, DIS_ASSOC, (UINT8*)&disAssoc, sizeof(disAssoc_t), 0);
1797
1798	return status;
1799}
1800
1801
1802