OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / system / wlan / ti / wilink_6_1 / stad / src / Sta_Management / assocSM.c
1 /*
2  * assocSM.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 assocSM.c
35  *  \brief 802.11 association SM source
36  *
37  *  \see assocSM.h
38  */
39
40
41 /***************************************************************************/
42 /*                                                                         */
43 /*      MODULE: assocSM.c                                                  */
44 /*    PURPOSE:  802.11 association SM source                               */
45 /*                                                                         */
46 /***************************************************************************/
47
48 #define __FILE_ID__  FILE_ID_63
49 #include "osApi.h"
50 #include "paramOut.h"
51 #include "rate.h"
52 #include "timer.h"
53 #include "fsm.h"
54 #include "report.h"
55 #include "DataCtrl_Api.h"
56 #include "siteMgrApi.h"
57 #include "rsnApi.h"
58 #include "regulatoryDomainApi.h"
59 #include "mlmeBuilder.h"
60 #include "mlmeApi.h"
61 #include "AssocSM.h"
62 #include "qosMngr_API.h"
63 #ifdef XCC_MODULE_INCLUDED
64 #include "XCCRMMngr.h"
65 #include "XCCMngr.h"
66 #endif
67 #include "apConn.h"
68 #include "TWDriver.h"
69 #include "DrvMainModules.h"
70 #include "StaCap.h"
71 #include "smeApi.h"
72
73 /* Constants */
74
75 /** number of states in the state machine */
76 #define ASSOC_SM_NUM_STATES     3
77
78 /** number of events in the state machine */
79 #define ASSOC_SM_NUM_EVENTS     6
80
81 /* Enumerations */
82
83 /* Typedefs */
84
85 /* Structures */
86
87 /* External data definitions */
88
89 /* External functions definitions */
90
91 /* Global variables */
92
93 /* Local function prototypes */
94
95 /* functions */
96
97
98 /* state machine functions */
99
100
101 TI_STATUS assoc_smEvent(assoc_t *pAssoc, TI_UINT8 event, void *pData);
102
103 void assoc_smTimeout(TI_HANDLE hAssoc, TI_BOOL bTwdInitOccured);
104
105 TI_STATUS assoc_smStartIdle(assoc_t *pAssoc);
106 TI_STATUS assoc_smStopWait(assoc_t *pAssoc);
107 TI_STATUS assoc_smSuccessWait(assoc_t *pAssoc);
108 TI_STATUS assoc_smFailureWait(assoc_t *pAssoc);
109 TI_STATUS assoc_smTimeoutWait(assoc_t *pAssoc);
110 TI_STATUS assoc_smMaxRetryWait(assoc_t *pAssoc);
111 TI_STATUS assoc_smStopAssoc(assoc_t *pAssoc);
112 TI_STATUS assoc_smActionUnexpected(assoc_t *pAssoc);
113
114 TI_STATUS assoc_smResetRetry(assoc_t *pAssoc);
115 TI_STATUS assoc_smIncRetry(assoc_t *pAssoc);
116 TI_STATUS assoc_smReportSuccess(assoc_t *pAssoc);
117 TI_STATUS assoc_smReportFailure(assoc_t *pAssoc, TI_UINT16 uStatusCode);
118 TI_STATUS assoc_smSendAssocReq(assoc_t *pAssoc);
119 TI_STATUS assoc_smStartTimer(assoc_t *pAssoc);
120 TI_STATUS assoc_smStopTimer(assoc_t *pAssoc);
121
122 TI_STATUS assoc_smCapBuild(assoc_t *pCtx, TI_UINT16 *cap);
123 TI_STATUS assoc_smSSIDBuild(assoc_t *pCtx, TI_UINT8 *pSSID, TI_UINT32 *ssidLen);
124 TI_STATUS assoc_smRatesBuild(assoc_t *pCtx, TI_UINT8 *pRates, TI_UINT32 *ratesLen);
125 TI_STATUS assoc_smRequestBuild(assoc_t *pCtx, TI_UINT8* reqBuf, TI_UINT32* reqLen);
126
127 TI_STATUS assoc_saveAssocReqMessage(assoc_t *pAssocSm, TI_UINT8 *pAssocBuffer, TI_UINT32 length);
128 TI_STATUS assoc_sendDisAssoc(assoc_t *pAssocSm, mgmtStatus_e reason);
129
130 /**
131 *
132 * assoc_create - allocate memory for association SM
133 *
134 * \b Description: 
135 *
136 * Allocate memory for association SM. \n
137 *       Allocates memory for Association context. \n
138 *       Allocates memory for association SM matrix. \n
139 *
140 * \b ARGS:
141 *
142 *  I   - hOs - OS context  \n
143 *
144 * \b RETURNS:
145 *
146 *  TI_OK if successful, TI_NOK otherwise.
147 *
148 * \sa rsn_mainSecSmKeysOnlyStop()
149 */
150 TI_HANDLE assoc_create(TI_HANDLE hOs)
151 {
152     assoc_t     *pHandle;
153     TI_STATUS       status;
154
155     /* allocate association context memory */
156     pHandle = (assoc_t*)os_memoryAlloc(hOs, sizeof(assoc_t));
157     if (pHandle == NULL)
158     {
159         return NULL;
160     }
161
162     os_memoryZero(hOs, pHandle, sizeof(assoc_t));
163
164     pHandle->hOs = hOs;
165
166     /* allocate memory for association state machine */
167     status = fsm_Create(hOs, &pHandle->pAssocSm, ASSOC_SM_NUM_STATES, ASSOC_SM_NUM_EVENTS);
168     if (status != TI_OK)
169     {
170         os_memoryFree(hOs, pHandle, sizeof(assoc_t));
171         return NULL;
172     }
173
174     return pHandle;
175 }
176
177
178 /**
179 *
180 * assocunload - unload association SM from memory
181 *
182 * \b Description: 
183 *
184 * Unload association SM from memory
185 *
186 * \b ARGS:
187 *
188 *  I   - hAssoc - association SM context  \n
189 *
190 * \b RETURNS:
191 *
192 *  TI_OK if successful, TI_NOK otherwise.
193 *
194 * \sa rsn_mainSecSmKeysOnlyStop()
195 */
196 TI_STATUS assoc_unload(TI_HANDLE hAssoc)
197 {
198     TI_STATUS       status;
199     assoc_t     *pHandle;
200
201     pHandle = (assoc_t*)hAssoc;
202
203     status = fsm_Unload(pHandle->hOs, pHandle->pAssocSm);
204     if (status != TI_OK)
205     {
206         /* report failure but don't stop... */
207         TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: Error releasing FSM memory \n");
208     }
209     
210         if (pHandle->hAssocSmTimer)
211         {
212                 tmr_DestroyTimer (pHandle->hAssocSmTimer);
213         }
214     
215     os_memoryFree(pHandle->hOs, hAssoc, sizeof(assoc_t));
216
217     return TI_OK;
218 }
219
220 /**
221 *
222 * assoc_config - configure a new association SM
223 *
224 * \b Description: 
225 *
226 * Configure a new association SM.
227 *
228 * \b RETURNS:
229 *
230 *  void
231 *
232 * \sa assoc_Create, assoc_Unload
233 */
234 void assoc_init (TStadHandlesList *pStadHandles)
235 {
236     assoc_t *pHandle = (assoc_t*)(pStadHandles->hAssoc);
237     
238     /** Main 802.1X State Machine matrix */
239     fsm_actionCell_t    assoc_smMatrix[ASSOC_SM_NUM_STATES][ASSOC_SM_NUM_EVENTS] =
240     {
241         /* next state and actions for IDLE state */
242         {{ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smStartIdle},
243          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
244          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
245          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
246          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected},
247          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected}
248         },
249         /* next state and actions for WAIT state */
250         {{ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smActionUnexpected},
251          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smStopWait},
252          {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smSuccessWait},
253          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smFailureWait},
254          {ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smTimeoutWait},
255          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smMaxRetryWait}
256         },
257         /* next state and actions for ASSOC state */
258         {{ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
259          {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smStopAssoc},
260          {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
261          {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
262          {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected},
263          {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected}
264         }};
265     
266     /* configure state machine */
267     fsm_Config (pHandle->pAssocSm, &assoc_smMatrix[0][0], ASSOC_SM_NUM_STATES, ASSOC_SM_NUM_EVENTS, NULL, pStadHandles->hOs);
268
269     pHandle->assocRejectCount = 0;
270     pHandle->assocTimeoutCount = 0;
271     pHandle->currentState = ASSOC_SM_STATE_IDLE;
272     
273     pHandle->hMlme             = pStadHandles->hMlmeSm;
274     pHandle->hRegulatoryDomain = pStadHandles->hRegulatoryDomain;
275     pHandle->hSiteMgr          = pStadHandles->hSiteMgr;
276     pHandle->hCtrlData         = pStadHandles->hCtrlData;
277     pHandle->hTWD              = pStadHandles->hTWD;
278     pHandle->hRsn              = pStadHandles->hRsn;
279     pHandle->hReport           = pStadHandles->hReport;
280     pHandle->hOs               = pStadHandles->hOs;
281     pHandle->hXCCMngr          = pStadHandles->hXCCMngr;
282     pHandle->hQosMngr          = pStadHandles->hQosMngr;
283     pHandle->hMeasurementMgr   = pStadHandles->hMeasurementMgr;
284     pHandle->hApConn           = pStadHandles->hAPConnection;
285     pHandle->hTimer            = pStadHandles->hTimer;
286     pHandle->hStaCap = pStadHandles->hStaCap;
287     pHandle->hSme              = pStadHandles->hSme;
288
289 }
290
291
292 TI_STATUS assoc_SetDefaults (TI_HANDLE hAssoc, assocInitParams_t *pAssocInitParams)
293 {
294     assoc_t *pHandle = (assoc_t*)hAssoc;
295
296     pHandle->timeout = pAssocInitParams->assocResponseTimeout;
297     pHandle->maxCount = pAssocInitParams->assocMaxRetryCount;
298
299     /* allocate OS timer memory */
300     pHandle->hAssocSmTimer = tmr_CreateTimer (pHandle->hTimer);
301     if (pHandle->hAssocSmTimer == NULL)
302     {
303         TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "assoc_SetDefaults(): Failed to create hAssocSmTimer!\n");
304         return TI_NOK;
305     }
306
307     return TI_OK;
308 }
309
310
311 /**
312 *
313 * assoc_start - Start event for the association SM
314 *
315 * \b Description: 
316 *
317 * Start event for the association SM
318 *
319 * \b ARGS:
320 *
321 *  I   - hAssoc - Association SM context  \n
322 *
323 * \b RETURNS:
324 *
325 *  TI_OK if successful, TI_NOK otherwise.
326 *
327 * \sa assoc_Stop, assoc_Recv
328 */
329 TI_STATUS assoc_start(TI_HANDLE hAssoc)
330 {
331     TI_STATUS       status;
332     assoc_t     *pHandle;
333
334     pHandle = (assoc_t*)hAssoc;
335
336     if (pHandle == NULL)
337     {
338         return TI_NOK;
339     }
340
341     pHandle->reAssoc = TI_FALSE;
342
343     pHandle->disAssoc = TI_FALSE;
344
345     status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_START, hAssoc);
346
347     return status;
348 }
349
350
351 /**
352 *
353 * assoc_start - Start event for the association SM
354 *
355 * \b Description: 
356 *
357 * Start event for the association SM - for Re-assoc request 
358 *
359 * \b ARGS:
360 *
361 *  I   - hAssoc - Association SM context  \n
362 *
363 * \b RETURNS:
364 *
365 *  TI_OK if successful, TI_NOK otherwise.
366 *
367 * \sa assoc_Stop, assoc_Recv
368 */
369 TI_STATUS reassoc_start(TI_HANDLE hAssoc)
370 {
371     TI_STATUS       status;
372     assoc_t     *pHandle;
373
374     pHandle = (assoc_t*)hAssoc;
375
376     if (pHandle == NULL)
377     {
378         return TI_NOK;
379     }
380     pHandle->reAssoc = TI_TRUE;
381
382     status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_START, hAssoc);
383
384     return status;
385 }
386
387 /**
388 *
389 * assoc_stop - Stop event for the association SM
390 *
391 * \b Description: 
392 *
393 * Stop event for the association SM
394 *
395 * \b ARGS:
396 *
397 *  I   - hAssoc - Association SM context  \n
398 *
399 * \b RETURNS:
400 *
401 *  TI_OK if successful, TI_NOK otherwise.
402 *
403 * \sa assoc_Start, assoc_Recv
404 */
405 TI_STATUS assoc_stop(TI_HANDLE hAssoc)
406 {
407     TI_STATUS       status;
408     assoc_t     *pHandle;
409
410     pHandle = (assoc_t*)hAssoc;
411
412     if (pHandle == NULL)
413     {
414         return TI_NOK;
415     }
416     
417     status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_STOP, hAssoc);
418     
419     return status;
420 }
421
422
423 TI_STATUS assoc_setDisAssocFlag(TI_HANDLE hAssoc, TI_BOOL disAsoccFlag)
424 {
425     assoc_t     *pHandle;
426     pHandle = (assoc_t*)hAssoc; 
427
428     pHandle->disAssoc = disAsoccFlag;
429
430     return TI_OK;
431 }
432
433
434
435 /**
436 *
437 * assoc_recv - Recive a message from the AP
438 *
439 * \b Description: 
440 *
441 * Parse a message form the AP and perform the appropriate event.
442 *
443 * \b ARGS:
444 *
445 *  I   - hAssoc - Association SM context  \n
446 *  I   - pFrame - Frame recieved  \n
447 *
448 * \b RETURNS:
449 *
450 *  TI_OK if successful, TI_NOK otherwise.
451 *
452 * \sa assoc_Start, assoc_Stop
453 */
454 TI_STATUS assoc_recv(TI_HANDLE hAssoc, mlmeFrameInfo_t *pFrame)
455 {
456     TI_STATUS       status;
457     assoc_t         *pHandle = (assoc_t*)hAssoc;
458     TTwdParamInfo   tTwdParam;
459     TI_UINT16           rspStatus;
460
461     if (pHandle == NULL)
462     {
463         return TI_NOK;
464     }
465
466     /* ensure that the SM is waiting for assoc response */
467     if(pHandle->currentState != ASSOC_SM_STATE_WAIT)
468         return TI_OK;
469
470     
471     if ((pFrame->subType != ASSOC_RESPONSE) && (pFrame->subType != RE_ASSOC_RESPONSE))
472     {
473         return TI_NOK;
474     }
475
476     /* check response status */
477     rspStatus  = pFrame->content.assocRsp.status;
478     
479     if (rspStatus == 0)
480     {
481         TRsnData        rsnData;
482         dot11_RSN_t *pRsnIe;
483         TI_UINT8       curRsnData[255];
484         TI_UINT8       rsnAssocIeLen;
485         TI_UINT8        length = 0;
486
487
488         TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG Success associating to AP \n");
489         
490         /* set AID to HAL */
491         tTwdParam.paramType = TWD_AID_PARAM_ID;
492         tTwdParam.content.halCtrlAid  = pFrame->content.assocRsp.aid;
493         TWD_SetParam (pHandle->hTWD, &tTwdParam);
494         
495
496         /* Get the RSN IE data */
497         pRsnIe = pFrame->content.assocRsp.pRsnIe;
498         while (length < pFrame->content.assocRsp.rsnIeLen && (pFrame->content.assocRsp.rsnIeLen < 255))
499         {
500             curRsnData[0+length] = pRsnIe->hdr[0];
501             curRsnData[1+length] = pRsnIe->hdr[1];
502             os_memoryCopy(pHandle->hOs, &curRsnData[2+length], (void *)pRsnIe->rsnIeData, pRsnIe->hdr[1]); 
503             length += pRsnIe->hdr[1] + 2;
504             pRsnIe += 1;
505         }
506         
507         if (pFrame->content.assocRsp.rsnIeLen != 0)
508         {
509             rsnData.pIe = curRsnData;
510             rsnData.ieLen = pFrame->content.assocRsp.rsnIeLen;
511             rsnData.privacy =  ((pFrame->content.assocRsp.capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TI_TRUE : TI_FALSE;
512             rsn_setSite(pHandle->hRsn, &rsnData, NULL, &rsnAssocIeLen);
513         }
514
515         /* update siteMgr with capabilities and whether we are connected to Cisco AP */
516         siteMgr_assocReport(pHandle->hSiteMgr,
517                             pFrame->content.assocRsp.capabilities, pFrame->content.assocRsp.ciscoIEPresent);
518
519         /* update QoS Manager - it the QOS active protocol is NONE, or no WME IE present, it will return TI_OK */
520         /* if configured by AP, update MSDU lifetime */
521         status = qosMngr_setSite(pHandle->hQosMngr, &pFrame->content.assocRsp);
522
523         if(status != TI_OK)
524         {
525             TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: DEBUG - Association failed : qosMngr_setSite error \n");
526             /* in case we wanted to work with qosAP and failed to connect to qos AP we want to reassociated again 
527                to another one */  
528             status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_FAIL, hAssoc);
529         }
530         else
531         {
532             status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_SUCCESS, hAssoc);
533         }
534     } 
535     else 
536     {
537         pHandle->assocRejectCount++;
538         
539         /* If there was attempt to renegotiate voice settings, update QoS Manager */
540         qosMngr_checkTspecRenegResults(pHandle->hQosMngr, &pFrame->content.assocRsp);
541
542         /* check failure reason */
543         switch (rspStatus)
544         {
545         case 0:
546             break;
547         case 1:
548             /* print debug message */
549             TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Unspecified error \n");
550             break;
551         case 10:
552             /* print debug message */
553             TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Cannot support all requested capabilities in the Capability Information field \n");
554             break;
555         case 11:
556             /* print debug message */
557             TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Reassociation denied due to inability to confirm that association exists \n");
558             break;
559         case 12:
560             /* print debug message */
561             TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Association denied due to reason outside the scope of this standard \n");
562             rsn_reportAuthFailure(pHandle->hRsn, RSN_AUTH_STATUS_INVALID_TYPE);
563             break;
564         case 13:
565             TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Association denied due to wrong authentication algorithm \n");
566             rsn_reportAuthFailure(pHandle->hRsn, RSN_AUTH_STATUS_INVALID_TYPE);
567             break;
568         case 17:
569             /* print debug message */
570             TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Association denied because AP is unable to handle additional associated stations \n");
571             break;
572         case 18:
573             /* print debug message */
574             TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter \n");
575             break;
576         default:
577             /* print error message on wrong error code for association response */
578             TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: ERROR - Association denied: error code (%d) irrelevant \n", rspStatus);
579             break;
580         }
581
582         status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_FAIL, hAssoc);
583     }
584
585     return status;
586 }
587
588 /**
589 *
590 * assoc_getParam - Get a specific parameter from the association SM
591 *
592 * \b Description: 
593 *
594 * Get a specific parameter from the association SM.
595 *
596 * \b ARGS:
597 *
598 *  I   - hAssoc - Association SM context  \n
599 *  I/O - pParam - Parameter \n
600 *
601 * \b RETURNS:
602 *
603 *  TI_OK if successful, TI_NOK otherwise.
604 *
605 * \sa assoc_Start, assoc_Stop
606 */
607 TI_STATUS assoc_getParam(TI_HANDLE hAssoc, paramInfo_t *pParam)
608 {
609     assoc_t *pHandle = (assoc_t *)hAssoc;
610
611     if ((pHandle == NULL) || (pParam == NULL))
612     {
613         return TI_NOK;
614     }
615
616     /* serch parameter type */
617     switch (pParam->paramType)
618     {
619     case ASSOC_RESPONSE_TIMEOUT_PARAM:
620         pParam->content.assocResponseTimeout = pHandle->timeout;
621         break;
622
623     case ASSOC_COUNTERS_PARAM:
624         pParam->content.siteMgrTiWlanCounters.AssocRejects = pHandle->assocRejectCount;
625         pParam->content.siteMgrTiWlanCounters.AssocTimeouts = pHandle->assocTimeoutCount;
626         break;
627
628     case ASSOC_ASSOCIATION_REQ_PARAM:
629         pParam->content.assocReqBuffer.buffer = pHandle->assocReqBuffer;
630         pParam->content.assocReqBuffer.bufferSize = pHandle->assocReqLen;
631                 pParam->content.assocReqBuffer.reAssoc = pHandle->reAssoc;
632         break;
633
634     case ASSOC_ASSOCIATION_RESP_PARAM:
635         pParam->content.assocReqBuffer.buffer = pHandle->assocRespBuffer;
636         pParam->content.assocReqBuffer.bufferSize = pHandle->assocRespLen;
637                 pParam->content.assocReqBuffer.reAssoc = pHandle->reAssocResp;
638         break;
639
640     case ASSOC_ASSOCIATION_INFORMATION_PARAM:
641        {
642            TI_UINT8  reqBuffIEOffset, respBuffIEOffset;
643            TI_UINT32 RequestIELength = 0;
644            TI_UINT32 ResponseIELength = 0;
645            paramInfo_t  *lParam;
646            ScanBssType_enum bssType;
647
648            TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association Information Get:  \n");
649            lParam = (paramInfo_t *)os_memoryAlloc(pHandle->hOs, sizeof(paramInfo_t));
650            if (!lParam)
651                return TI_NOK;
652
653            /* Assoc exists only in Infrastructure */
654            lParam->paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
655            ctrlData_getParam(pHandle->hCtrlData, lParam);
656            bssType = lParam->content.ctrlDataCurrentBssType;
657            os_memoryFree(pHandle->hOs, lParam, sizeof(paramInfo_t));
658            if (bssType != BSS_INFRASTRUCTURE)
659            {
660                TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "Not in Infrastructure BSS, No ASSOC Info for GET ASSOC_ASSOCIATION_INFORMATION_PARAM\n");
661                return TI_NOK;
662            }
663
664            /* Init the result buffer to 0 */
665            os_memoryZero(pHandle->hOs ,&pParam->content, sizeof(OS_802_11_ASSOCIATION_INFORMATION));
666
667            reqBuffIEOffset  = 4;  /* In Assoc request frame IEs are located from byte 4 */
668            respBuffIEOffset = 6;  /* In Assoc response frame the IEs are located from byte 6 */
669
670             /* If the last associate was re-associciation, the current AP MAC address */
671             /* is placed before the IEs. Copy it to the result parameters.            */
672             if (pHandle->reAssoc)
673             {
674                 MAC_COPY (pParam->content.assocAssociationInformation.RequestFixedIEs.CurrentAPAddress,
675                           &pHandle->assocReqBuffer[reqBuffIEOffset]);
676                 reqBuffIEOffset += MAC_ADDR_LEN;
677             }
678
679             /* Calculate length of Info elements in assoc request and response frames */
680             if(pHandle->assocReqLen > reqBuffIEOffset)
681                 RequestIELength = pHandle->assocReqLen - reqBuffIEOffset;
682
683             if(pHandle->assocRespLen > respBuffIEOffset)
684                 ResponseIELength = pHandle->assocRespLen - respBuffIEOffset;
685
686             /* Copy the association request information */
687             pParam->content.assocAssociationInformation.Length = sizeof(OS_802_11_ASSOCIATION_INFORMATION);
688             pParam->content.assocAssociationInformation.AvailableRequestFixedIEs = OS_802_11_AI_REQFI_CAPABILITIES | OS_802_11_AI_REQFI_LISTENINTERVAL;
689             pParam->content.assocAssociationInformation.RequestFixedIEs.Capabilities = *(TI_UINT16*)&(pHandle->assocReqBuffer[0]);
690             pParam->content.assocAssociationInformation.RequestFixedIEs.ListenInterval = *(TI_UINT16*)(&pHandle->assocReqBuffer[2]);
691
692             pParam->content.assocAssociationInformation.RequestIELength = RequestIELength; 
693             pParam->content.assocAssociationInformation.OffsetRequestIEs = 0;
694             if (RequestIELength > 0)
695             {
696                 pParam->content.assocAssociationInformation.OffsetRequestIEs = (TI_UINT32)&pHandle->assocReqBuffer[reqBuffIEOffset];
697             }
698             /* Copy the association response information */
699             pParam->content.assocAssociationInformation.AvailableResponseFixedIEs = 
700                 OS_802_11_AI_RESFI_CAPABILITIES | OS_802_11_AI_RESFI_STATUSCODE | OS_802_11_AI_RESFI_ASSOCIATIONID;
701             pParam->content.assocAssociationInformation.ResponseFixedIEs.Capabilities = *(TI_UINT16*)&(pHandle->assocRespBuffer[0]);
702             pParam->content.assocAssociationInformation.ResponseFixedIEs.StatusCode = *(TI_UINT16*)&(pHandle->assocRespBuffer[2]);
703             pParam->content.assocAssociationInformation.ResponseFixedIEs.AssociationId = *(TI_UINT16*)&(pHandle->assocRespBuffer[4]);
704             pParam->content.assocAssociationInformation.ResponseIELength = ResponseIELength;
705             pParam->content.assocAssociationInformation.OffsetResponseIEs = 0;
706             if (ResponseIELength > 0)
707             {
708                 pParam->content.assocAssociationInformation.OffsetResponseIEs = (TI_UINT32)&pHandle->assocRespBuffer[respBuffIEOffset];
709             }
710
711        }
712         break;
713     default:
714         return TI_NOK;
715     }
716
717     return TI_OK;
718 }
719
720 /**
721 *
722 * assoc_setParam - Set a specific parameter to the association SM
723 *
724 * \b Description: 
725 *
726 * Set a specific parameter to the association SM.
727 *
728 * \b ARGS:
729 *
730 *  I   - hAssoc - Association SM context  \n
731 *  I/O - pParam - Parameter \n
732 *
733 * \b RETURNS:
734 *
735 *  TI_OK if successful, TI_NOK otherwise.
736 *
737 * \sa assoc_Start, assoc_Stop
738 */
739 TI_STATUS assoc_setParam(TI_HANDLE hAssoc, paramInfo_t *pParam)
740 {
741     assoc_t     *pHandle;
742
743     pHandle = (assoc_t*)hAssoc;
744
745     if ((pHandle == NULL) || (pParam == NULL))
746     {
747         return TI_NOK;
748     }
749
750     switch (pParam->paramType)
751     {
752     case ASSOC_RESPONSE_TIMEOUT_PARAM:
753         /* check bounds */
754         if ((pParam->content.assocResponseTimeout >= ASSOC_RESPONSE_TIMEOUT_MIN) &&
755             (pParam->content.assocResponseTimeout <= ASSOC_RESPONSE_TIMEOUT_MAX))
756         {
757             pHandle->timeout = pParam->content.assocResponseTimeout;
758         } else {
759             return TI_NOK;
760         }
761         break;
762     default:
763         return TI_NOK;
764     }
765
766     return TI_OK;
767 }
768
769 /**
770 *
771 * assoc_smTimeout - Time out event activation function
772 *
773 * \b Description: 
774 *
775 * Time out event activation function.
776 *
777 * \b ARGS:
778 *
779 *  I   - hAssoc - Association SM context  \n
780 *
781 * \b RETURNS:
782 *
783 *  TI_OK if successful, TI_NOK otherwise.
784 *
785 * \sa assoc_Start, assoc_Stop
786 */
787 void assoc_smTimeout(TI_HANDLE hAssoc, TI_BOOL bTwdInitOccured)
788 {
789     assoc_t     *pHandle;
790
791     pHandle = (assoc_t*)hAssoc;
792
793
794     if (pHandle == NULL)
795     {
796         return;
797     }
798     
799     pHandle->assocTimeoutCount++;
800
801     assoc_smEvent(pHandle, ASSOC_SM_EVENT_TIMEOUT, hAssoc);
802 }
803
804 /**
805 *
806 * assoc_smEvent - Perform an event on the association SM
807 *
808 * \b Description: 
809 *
810 * Perform an event on the association SM.
811 *
812 * \b ARGS:
813 *
814 *  I   - pAssoc - Association SM context  \n
815 *  I   - event - Current event \n
816 *  I   - pData - event related data
817 *
818 * \b RETURNS:
819 *
820 *  TI_OK if successful, TI_NOK otherwise.
821 *
822 * \sa 
823 */
824 TI_STATUS assoc_smEvent(assoc_t *pAssoc, TI_UINT8 event, void *pData)
825 {
826     TI_STATUS       status;
827     TI_UINT8        nextState;
828
829     status = fsm_GetNextState(pAssoc->pAssocSm, pAssoc->currentState, event, &nextState);
830     if (status != TI_OK)
831     {
832         TRACE0(pAssoc->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: ERROR - failed getting next state \n");
833
834         return(TI_NOK);
835     }
836
837         TRACE3( pAssoc->hReport, REPORT_SEVERITY_INFORMATION, "assoc_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", pAssoc->currentState, event, nextState);
838
839     status = fsm_Event(pAssoc->pAssocSm, &pAssoc->currentState, event, pData);
840
841     return(status);
842 }
843
844 /* state machine functions */
845
846 TI_STATUS assoc_smStartIdle(assoc_t *pAssoc)
847 {
848     TI_STATUS       status;
849
850     status = assoc_smResetRetry(pAssoc);
851     status = assoc_smSendAssocReq(pAssoc);
852     status = assoc_smStartTimer(pAssoc);
853     status = assoc_smIncRetry(pAssoc);
854
855     return status;
856 }
857
858 TI_STATUS assoc_smStopWait(assoc_t *pAssoc)
859 {
860     TI_STATUS       status;
861
862     status = assoc_smStopTimer(pAssoc);
863
864     return status;
865 }
866
867 TI_STATUS assoc_smSuccessWait(assoc_t *pAssoc)
868 {
869     TI_STATUS       status;
870
871     status = assoc_smStopTimer(pAssoc);
872     status = assoc_smReportSuccess(pAssoc);
873
874     return status;
875 }
876
877 TI_STATUS assoc_smFailureWait(assoc_t *pAssoc)
878 {
879     TI_STATUS       status;
880     TI_UINT16           uRspStatus = *(TI_UINT16*)&(pAssoc->assocRespBuffer[2]);
881
882     status = assoc_smStopTimer(pAssoc);
883
884     /* Sanity check. If the Response status is indeed not 0 */
885     if (uRspStatus) 
886     {
887         status = assoc_smReportFailure(pAssoc, uRspStatus);
888     }
889     else    /* (uRspStatus == 0) how did we get here ? */ 
890     {
891         TRACE0(pAssoc->hReport, REPORT_SEVERITY_ERROR, "while Response status is OK (0) !!! \n");
892
893         status = assoc_smReportFailure(pAssoc, (TI_UINT16)TI_NOK);
894     }
895     return status;
896 }
897
898 TI_STATUS assoc_smTimeoutWait(assoc_t *pAssoc)
899 {
900     TI_STATUS       status;
901
902     status = assoc_smSendAssocReq(pAssoc);
903     status = assoc_smStartTimer(pAssoc);
904     status = assoc_smIncRetry(pAssoc);
905
906     return status;
907 }
908
909 TI_STATUS assoc_smMaxRetryWait(assoc_t *pAssoc)
910 {
911     TI_STATUS       status;
912
913     status = assoc_smStopTimer(pAssoc);
914     status = assoc_smReportFailure(pAssoc, STATUS_PACKET_REJ_TIMEOUT);
915
916     return status;
917 }
918
919 TI_STATUS assoc_smSendAssocReq(assoc_t *pAssoc)
920 {
921     TI_UINT8           *assocMsg;
922     TI_UINT32           msgLen;
923     TI_STATUS           status;
924     dot11MgmtSubType_e  assocType=ASSOC_REQUEST;
925
926     assocMsg = os_memoryAlloc(pAssoc->hOs, MAX_ASSOC_MSG_LENGTH);
927     if (!assocMsg)
928         return TI_NOK;
929
930     if (pAssoc->reAssoc)
931     {
932         assocType = RE_ASSOC_REQUEST;
933     }
934     status = assoc_smRequestBuild(pAssoc, assocMsg, &msgLen);
935     if (status == TI_OK) {
936         /* Save the association request message */
937         assoc_saveAssocReqMessage(pAssoc, assocMsg, msgLen);
938         status = mlmeBuilder_sendFrame(pAssoc->hMlme, assocType, assocMsg, msgLen, 0);
939     }
940     os_memoryFree(pAssoc->hOs, assocMsg, MAX_ASSOC_MSG_LENGTH);
941     return status;
942 }
943
944 TI_STATUS assoc_smStopAssoc(assoc_t *pAssoc)
945 {
946     if (pAssoc->disAssoc) {
947         assoc_sendDisAssoc(pAssoc, STATUS_UNSPECIFIED);
948     }
949     return TI_OK;
950 }
951
952 TI_STATUS assoc_smActionUnexpected(assoc_t *pAssoc)
953 {
954     return TI_OK;
955 }
956
957 /* local functions */
958
959
960 TI_STATUS assoc_smResetRetry(assoc_t *pAssoc)
961 {
962     if (pAssoc == NULL)
963     {
964         return TI_NOK;
965     }
966     
967     pAssoc->retryCount = 0;
968     
969     return TI_OK;
970 }
971
972 TI_STATUS assoc_smIncRetry(assoc_t *pAssoc)
973 {
974     TI_STATUS       status;
975
976     if (pAssoc == NULL)
977     {
978         return TI_NOK;
979     }
980     
981     pAssoc->retryCount++;
982     
983     if (pAssoc->retryCount > pAssoc->maxCount)
984     {
985         status = assoc_smEvent(pAssoc, ASSOC_SM_EVENT_MAX_RETRY, pAssoc);
986
987         return status;
988     }
989
990     return TI_OK;
991 }
992
993 TI_STATUS assoc_smReportSuccess(assoc_t *pAssoc)
994 {
995     TI_STATUS       status;
996
997     if (pAssoc == NULL)
998     {
999         return TI_NOK;
1000     }
1001     status = mlme_reportAssocStatus(pAssoc->hMlme, (TI_UINT16)TI_OK);
1002
1003     return status;
1004 }
1005
1006 TI_STATUS assoc_smReportFailure(assoc_t *pAssoc, TI_UINT16 uStatusCode)
1007 {
1008     TI_STATUS       status;
1009
1010     if (pAssoc == NULL)
1011     {
1012         return TI_NOK;
1013     }
1014     
1015     status = mlme_reportAssocStatus(pAssoc->hMlme, uStatusCode);
1016
1017     return status;
1018 }
1019
1020 TI_STATUS assoc_smStartTimer(assoc_t *pAssoc)
1021 {
1022     if (pAssoc == NULL)
1023     {
1024         return TI_NOK;
1025     }
1026     
1027     tmr_StartTimer (pAssoc->hAssocSmTimer,
1028                     assoc_smTimeout,
1029                     (TI_HANDLE)pAssoc,
1030                     pAssoc->timeout,
1031                     TI_FALSE);
1032
1033     return TI_OK;
1034 }
1035
1036 TI_STATUS assoc_smStopTimer(assoc_t *pAssoc)
1037 {
1038     if (pAssoc == NULL)
1039     {
1040         return TI_NOK;
1041     }
1042     
1043     tmr_StopTimer (pAssoc->hAssocSmTimer);
1044
1045     return TI_OK;
1046 }
1047
1048 /*****************************************************************************
1049 **
1050 ** Association messages builder/Parser
1051 **
1052 *****************************************************************************/
1053
1054 TI_STATUS assoc_smCapBuild(assoc_t *pCtx, TI_UINT16 *cap)
1055 {
1056     paramInfo_t         param;
1057     TI_STATUS           status;
1058     EDot11Mode          mode;
1059     TI_UINT32           rateSuppMask, rateBasicMask;
1060     TI_UINT8            ratesBuf[DOT11_MAX_SUPPORTED_RATES];
1061     TI_UINT32           len = 0, ofdmIndex = 0;
1062     TI_BOOL             b11nEnable, bWmeEnable;
1063
1064     *cap = 0;
1065
1066     /* Bss type */
1067     param.paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
1068     status =  ctrlData_getParam(pCtx->hCtrlData, &param);
1069     if (status == TI_OK)
1070     {
1071         if (param.content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE)
1072         {
1073             *cap |= DOT11_CAPS_ESS;
1074         } else {
1075             *cap |= DOT11_CAPS_IBSS;
1076         }
1077     } else {
1078         return TI_NOK;
1079     }
1080
1081     /* Privacy */
1082     param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
1083     status =  rsn_getParam(pCtx->hRsn, &param);
1084     if (status == TI_OK)
1085     {
1086         if (param.content.rsnEncryptionStatus != TWD_CIPHER_NONE)
1087         {
1088             *cap |= DOT11_CAPS_PRIVACY;
1089         }
1090     } else {
1091         return TI_NOK;
1092     }
1093
1094     /* Preamble */
1095     param.paramType = SITE_MGR_DESIRED_PREAMBLE_TYPE_PARAM;
1096     status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1097     if (status == TI_OK)
1098     {
1099         if (param.content.siteMgrCurrentPreambleType == PREAMBLE_SHORT)
1100             *cap |= DOT11_CAPS_SHORT_PREAMBLE;
1101     } else {
1102         return TI_NOK;
1103     }
1104
1105     /* Pbcc */
1106     param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
1107     status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1108     if (status == TI_OK)
1109     {
1110         if(param.content.siteMgrCurrentRateMask.supportedRateMask & DRV_RATE_MASK_22_PBCC)
1111             *cap |= DOT11_CAPS_PBCC;
1112     } else {
1113         return TI_NOK;
1114     }
1115
1116     
1117     /* Checking if the station supports Spectrum Management (802.11h) */
1118     param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
1119     status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
1120     if (status == TI_OK )
1121     {
1122         if( param.content.spectrumManagementEnabled)
1123             *cap |= DOT11_SPECTRUM_MANAGEMENT;
1124     } 
1125     else
1126     {
1127         return TI_NOK;
1128     }
1129     
1130     /* slot time */
1131     param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
1132     status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1133     if(status == TI_OK)
1134     {
1135         mode = param.content.siteMgrDot11OperationalMode;
1136     }
1137     else
1138         return TI_NOK;
1139
1140     if(mode == DOT11_G_MODE)
1141     {
1142         /* new requirement: the short slot time should be set only
1143            if the AP's modulation is OFDM (highest rate) */
1144         
1145         /* get Rates */
1146         param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
1147         status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1148         if (status == TI_OK)
1149         {
1150             rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask;
1151             rateSuppMask  = param.content.siteMgrCurrentRateMask.supportedRateMask;
1152         } else {
1153             return TI_NOK;
1154         }
1155         
1156         /* convert the bit map to the rates array */
1157         rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex);
1158
1159         if(ofdmIndex < len)
1160             *cap |= DOT11_CAPS_SHORT_SLOT_TIME;
1161
1162 /*      
1163         param.paramType = SITE_MGR_CURRENT_MODULATION_TYPE_PARAM;
1164         status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1165         if(param.content.siteMgrCurrentModulationType == DRV_MODULATION_OFDM)
1166             *cap |= DOT11_CAPS_SHORT_SLOT_TIME;
1167 */
1168     }
1169
1170     /* Immediate Block Ack subfield - (is WME on?) AND (is HT Enable?) */
1171     /* verify 11n_Enable and Chip type */
1172     StaCap_IsHtEnable (pCtx->hStaCap, &b11nEnable);
1173     /* verify that WME flag enable */
1174     qosMngr_GetWmeEnableFlag (pCtx->hQosMngr, &bWmeEnable); 
1175
1176     if ((b11nEnable != TI_FALSE) && (bWmeEnable != TI_FALSE))
1177     {
1178         *cap |= DOT11_CAPS_IMMEDIATE_BA;
1179       }
1180
1181     return TI_OK;
1182 }
1183
1184
1185 TI_STATUS assoc_smSSIDBuild(assoc_t *pCtx, TI_UINT8 *pSSID, TI_UINT32 *ssidLen)
1186 {
1187     paramInfo_t         param;
1188     TI_STATUS               status;
1189     dot11_SSID_t        *pDot11Ssid;
1190
1191     pDot11Ssid = (dot11_SSID_t*)pSSID;
1192     /* set SSID element id */
1193     pDot11Ssid->hdr[0] = SSID_IE_ID;
1194
1195     /* get SSID */
1196     param.paramType = SME_DESIRED_SSID_ACT_PARAM;
1197     status =  sme_GetParam(pCtx->hSme, &param);
1198     if (status != TI_OK)
1199     {
1200         return status;
1201     }
1202     
1203     /* check for ANY ssid */
1204     if (param.content.smeDesiredSSID.len != 0)
1205     {
1206         pDot11Ssid->hdr[1] = param.content.smeDesiredSSID.len;
1207         os_memoryCopy(pCtx->hOs, 
1208                       (void *)pDot11Ssid->serviceSetId, 
1209                       (void *)param.content.smeDesiredSSID.str, 
1210                       param.content.smeDesiredSSID.len);
1211
1212     } else {
1213         /* if ANY ssid is configured, use the current SSID */
1214         param.paramType = SITE_MGR_CURRENT_SSID_PARAM;
1215         status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1216         if (status != TI_OK)
1217         {
1218             return status;
1219         }
1220         pDot11Ssid->hdr[1] = param.content.siteMgrCurrentSSID.len;
1221         os_memoryCopy(pCtx->hOs, 
1222                       (void *)pDot11Ssid->serviceSetId, 
1223                       (void *)param.content.siteMgrCurrentSSID.str, 
1224                       param.content.siteMgrCurrentSSID.len);
1225
1226     }
1227
1228     *ssidLen = pDot11Ssid->hdr[1] + sizeof(dot11_eleHdr_t);
1229     
1230     return TI_OK;
1231 }
1232
1233 TI_STATUS assoc_smRatesBuild(assoc_t *pCtx, TI_UINT8 *pRates, TI_UINT32 *ratesLen)
1234 {
1235     paramInfo_t         param;
1236     TI_STATUS           status;
1237     TI_UINT32           rateSuppMask, rateBasicMask;
1238     dot11_RATES_t       *pDot11Rates;
1239     TI_UINT32           len = 0, ofdmIndex = 0;
1240     TI_UINT8            ratesBuf[DOT11_MAX_SUPPORTED_RATES];
1241     EDot11Mode          mode;
1242     TI_UINT32           suppRatesLen, extSuppRatesLen, i;
1243     pDot11Rates = (dot11_RATES_t*)pRates;
1244
1245
1246     /* get Rates */
1247     param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
1248     status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
1249     if (status == TI_OK)
1250     {
1251         rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask;
1252         rateSuppMask  = param.content.siteMgrCurrentRateMask.supportedRateMask;
1253     } 
1254     else 
1255     {
1256         return TI_NOK;
1257     }
1258
1259     /* get operational mode */
1260     param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
1261     status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1262     if(status == TI_OK)
1263         mode = param.content.siteMgrDot11OperationalMode;
1264     else
1265         return TI_NOK;
1266
1267     /* convert the bit map to the rates array */
1268     /* remove MCS rates from Extended Supported Rates IE */
1269     rateSuppMask &= ~(DRV_RATE_MASK_MCS_0_OFDM | 
1270                       DRV_RATE_MASK_MCS_1_OFDM |
1271                       DRV_RATE_MASK_MCS_2_OFDM |
1272                       DRV_RATE_MASK_MCS_3_OFDM |
1273                       DRV_RATE_MASK_MCS_4_OFDM |
1274                       DRV_RATE_MASK_MCS_5_OFDM |
1275                       DRV_RATE_MASK_MCS_6_OFDM |
1276                       DRV_RATE_MASK_MCS_7_OFDM );
1277
1278     rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex);
1279
1280     if(mode != DOT11_G_MODE || ofdmIndex == len )
1281     {
1282         pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID;
1283         pDot11Rates->hdr[1] = len;
1284         os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, len);
1285         *ratesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
1286     }
1287     else 
1288     {
1289         /* fill in the supported rates */
1290         pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID;
1291         pDot11Rates->hdr[1] = ofdmIndex;
1292         os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]);
1293         suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
1294         /* fill in the extended supported rates */
1295         pDot11Rates = (dot11_RATES_t*)(pRates + suppRatesLen);
1296         pDot11Rates->hdr[0] = EXT_SUPPORTED_RATES_IE_ID;
1297         pDot11Rates->hdr[1] = len - ofdmIndex;
1298         os_memoryCopy(NULL, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]);
1299         extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
1300         *ratesLen = suppRatesLen + extSuppRatesLen;
1301     }
1302
1303     TRACE3(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - bitmapSupp= 0x%X,bitMapBasic = 0x%X, len = %d\n", rateSuppMask,rateBasicMask,len);
1304     for(i=0; i<len; i++)
1305     {
1306         TRACE2(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - ratesBuf[%d] = 0x%X\n", i, ratesBuf[i]);
1307     }
1308
1309     return TI_OK;
1310 }
1311
1312 TI_STATUS assoc_powerCapabilityBuild(assoc_t *pCtx, TI_UINT8 *pPowerCapability, TI_UINT32 *powerCapabilityLen)
1313 {
1314     paramInfo_t         param;
1315     TI_STATUS               status;
1316     dot11_CAPABILITY_t      *pDot11PowerCapability;
1317
1318     pDot11PowerCapability = (dot11_CAPABILITY_t*)pPowerCapability;
1319     
1320     /* set Power Capability element id */
1321     pDot11PowerCapability->hdr[0] = DOT11_CAPABILITY_ELE_ID;
1322     pDot11PowerCapability->hdr[1] = DOT11_CAPABILITY_ELE_LEN;
1323
1324     /* get power capability */
1325     param.paramType = REGULATORY_DOMAIN_POWER_CAPABILITY_PARAM;
1326     status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
1327
1328     if (status == TI_OK)
1329     {
1330         pDot11PowerCapability->minTxPower = param.content.powerCapability.minTxPower;
1331         pDot11PowerCapability->maxTxPower = param.content.powerCapability.maxTxPower;
1332         *powerCapabilityLen = pDot11PowerCapability->hdr[1] + sizeof(dot11_eleHdr_t);
1333     }
1334     else
1335         *powerCapabilityLen = 0;
1336
1337     return TI_OK;
1338 }
1339
1340 TI_STATUS assoc_smRequestBuild(assoc_t *pCtx, TI_UINT8* reqBuf, TI_UINT32* reqLen)
1341 {
1342     TI_STATUS       status;
1343     TI_UINT8        *pRequest;
1344     TI_UINT32       len;
1345     paramInfo_t     param;
1346     TTwdParamInfo   tTwdParam;
1347     TI_UINT16       capabilities;
1348     
1349     pRequest = reqBuf;
1350     *reqLen = 0;
1351
1352     /* insert capabilities */
1353     status = assoc_smCapBuild(pCtx, &capabilities);
1354     if (status == TI_OK)
1355     {
1356         *(TI_UINT16*)pRequest = capabilities;
1357     }
1358     else
1359         return TI_NOK;
1360
1361     pRequest += 2;
1362     *reqLen += 2;
1363
1364     /* insert listen interval */
1365     tTwdParam.paramType = TWD_LISTEN_INTERVAL_PARAM_ID;
1366     status =  TWD_GetParam (pCtx->hTWD, &tTwdParam);
1367     if (status == TI_OK)
1368     {
1369         *(TI_UINT16*)pRequest = ENDIAN_HANDLE_WORD((TI_UINT16)tTwdParam.content.halCtrlListenInterval);
1370     } else {
1371         return TI_NOK;
1372     }
1373     
1374     pRequest += 2;
1375     *reqLen += 2;
1376     if (pCtx->reAssoc)
1377     {   /* Insert currentAPAddress element only in reassoc request*/
1378         param.paramType = SITE_MGR_PREV_SITE_BSSID_PARAM;
1379         status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1380         if (status == TI_OK)
1381         {
1382             MAC_COPY (pRequest, param.content.siteMgrDesiredBSSID);
1383             TRACE6(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - prev AP = %x-%x-%x-%x-%x-%x\n", param.content.siteMgrDesiredBSSID[0], param.content.siteMgrDesiredBSSID[1], param.content.siteMgrDesiredBSSID[2], param.content.siteMgrDesiredBSSID[3], param.content.siteMgrDesiredBSSID[4], param.content.siteMgrDesiredBSSID[5]);
1384
1385
1386             pRequest += MAC_ADDR_LEN;
1387             *reqLen += MAC_ADDR_LEN;
1388         }
1389         else
1390         {
1391             TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: ASSOC_REQ - No prev AP \n");
1392             return status;
1393
1394         }
1395     }
1396
1397     /* insert SSID element */
1398     status = assoc_smSSIDBuild(pCtx, pRequest, &len);
1399     if (status != TI_OK)
1400     {
1401         return TI_NOK;
1402     }
1403
1404     pRequest += len;
1405     *reqLen += len;
1406
1407     /* insert Rates element */
1408     status = assoc_smRatesBuild(pCtx, pRequest, &len);
1409     if (status != TI_OK)
1410     {
1411         return TI_NOK;
1412     }
1413     pRequest += len;
1414     *reqLen += len;
1415
1416     /* Checking if the station supports Spectrum Management (802.11h) */
1417     param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
1418     status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain,&param);
1419     if( (status == TI_OK) && param.content.spectrumManagementEnabled)
1420     {
1421         /* Checking the selected AP capablities */
1422         param.paramType = SITE_MGR_SITE_CAPABILITY_PARAM;
1423         status =  siteMgr_getParam(pCtx->hSiteMgr,&param);
1424         if(status == TI_OK && ((param.content.siteMgrSiteCapability & DOT11_SPECTRUM_MANAGEMENT) != 0)) 
1425         {
1426             /* insert Power capability element */
1427             status = assoc_powerCapabilityBuild(pCtx, pRequest, &len);
1428             if (status != TI_OK)
1429             {
1430                 return TI_NOK;
1431             }
1432             pRequest += len;
1433             *reqLen += len;
1434 #if 0
1435             /* insert Supported Channels element */
1436             status = assoc_supportedChannelBuild(pCtx, pRequest, &len);
1437             if (status != TI_OK)
1438             {
1439                 return TI_NOK;
1440             }
1441             pRequest += len;
1442             *reqLen += len;
1443 #endif
1444         }
1445
1446
1447     }
1448
1449     status = qosMngr_getQosCapabiltyInfeElement(pCtx->hQosMngr,pRequest,&len);
1450     if (status != TI_OK)
1451     {
1452         return TI_NOK;
1453     }
1454     pRequest += len;
1455     *reqLen += len;
1456
1457
1458 #ifdef XCC_MODULE_INCLUDED
1459     status = rsn_getXCCExtendedInfoElement(pCtx->hRsn, pRequest, (TI_UINT8*)&len);
1460     if (status != TI_OK)
1461     {
1462         return TI_NOK;
1463     }
1464     pRequest += len;
1465     *reqLen += len;
1466
1467     if (pCtx->reAssoc)
1468     {   /* insert CCKM information element only in reassoc */
1469         status = XCCMngr_getCckmInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len);
1470         
1471         if (status != TI_OK)
1472         {
1473             return TI_NOK;
1474         }
1475         pRequest += len;
1476         *reqLen += len;
1477     }
1478     status = XCCMngr_getXCCVersionInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len);
1479     if (status != TI_OK)
1480     {
1481         return TI_NOK;
1482     }
1483     pRequest += len;
1484     *reqLen += len;
1485
1486     /* Insert Radio Mngt Capability IE */
1487     status = measurementMgr_radioMngtCapabilityBuild(pCtx->hMeasurementMgr, pRequest, (TI_UINT8*)&len);
1488     if (status != TI_OK)
1489     {
1490         return TI_NOK;
1491     }
1492     pRequest += len;
1493     *reqLen += len;
1494 #endif
1495
1496      /* Get Simple-Config state */
1497     param.paramType = SITE_MGR_SIMPLE_CONFIG_MODE;
1498     status = siteMgr_getParam(pCtx->hSiteMgr, &param);
1499
1500    if (param.content.siteMgrWSCMode.WSCMode == TIWLN_SIMPLE_CONFIG_OFF)
1501    {
1502     /* insert RSN information elements */
1503     status = rsn_getInfoElement(pCtx->hRsn, pRequest, &len);
1504         
1505         if (status != TI_OK)
1506         {
1507                 return TI_NOK;
1508         }
1509         pRequest += len;
1510         *reqLen += len;
1511   }
1512
1513     /* Primary Site support HT ? */
1514     param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT;
1515     siteMgr_getParam(pCtx->hSiteMgr, &param);
1516
1517     if(TI_TRUE == param.content.bPrimarySiteHtSupport)
1518     {
1519         status = StaCap_GetHtCapabilitiesIe (pCtx->hStaCap, pRequest, &len);
1520         if (status != TI_OK)
1521         {
1522                 return TI_NOK;
1523         }
1524         pRequest += len;
1525         *reqLen += len;
1526     }
1527
1528         status = qosMngr_assocReqBuild(pCtx->hQosMngr,pRequest,&len);
1529         if (status != TI_OK)
1530         {
1531                 return TI_NOK;
1532         }
1533         pRequest += len;
1534         *reqLen += len;
1535
1536         status = apConn_getVendorSpecificIE(pCtx->hApConn, pRequest, &len);
1537         if (status != TI_OK)
1538         {
1539                 return TI_NOK;
1540         }
1541         pRequest += len;
1542         *reqLen += len;
1543  
1544     if (*reqLen>=MAX_ASSOC_MSG_LENGTH)
1545     {
1546         return TI_NOK;
1547     }
1548
1549     return TI_OK;
1550 }
1551
1552
1553
1554 TI_STATUS assoc_saveAssocRespMessage(assoc_t *pAssocSm, TI_UINT8 *pAssocBuffer, TI_UINT32 length)
1555 {
1556     if ((pAssocSm==NULL) || (pAssocBuffer==NULL) || (length>=MAX_ASSOC_MSG_LENGTH))
1557     {
1558         return TI_NOK;
1559     }
1560     os_memoryCopy(pAssocSm->hOs, pAssocSm->assocRespBuffer, pAssocBuffer, length);  
1561     pAssocSm->assocRespLen = length;
1562     
1563     TRACE1(pAssocSm->hReport, REPORT_SEVERITY_INFORMATION, "assoc_saveAssocRespMessage: length=%ld \n",length);
1564     return TI_OK;
1565 }
1566
1567 TI_STATUS assoc_saveAssocReqMessage(assoc_t *pAssocSm, TI_UINT8 *pAssocBuffer, TI_UINT32 length)
1568 {
1569
1570     if ((pAssocSm==NULL) || (pAssocBuffer==NULL) || (length>=MAX_ASSOC_MSG_LENGTH))
1571     {
1572         return TI_NOK;
1573     }
1574
1575     os_memoryCopy(pAssocSm->hOs, pAssocSm->assocReqBuffer, pAssocBuffer, length);  
1576     pAssocSm->assocReqLen = length;
1577     
1578     TRACE1(pAssocSm->hReport, REPORT_SEVERITY_INFORMATION, "assoc_saveAssocReqMessage: length=%ld \n",length);
1579     return TI_OK;
1580 }
1581
1582
1583 TI_STATUS assoc_sendDisAssoc(assoc_t *pAssocSm, mgmtStatus_e reason)
1584 {
1585     TI_STATUS       status;
1586     disAssoc_t      disAssoc;
1587
1588     if (reason == STATUS_SUCCESSFUL)
1589     {
1590         disAssoc.reason = ENDIAN_HANDLE_WORD(STATUS_UNSPECIFIED);
1591     } else {
1592         disAssoc.reason = ENDIAN_HANDLE_WORD(reason);
1593     }
1594
1595     status = mlmeBuilder_sendFrame(pAssocSm->hMlme, DIS_ASSOC, (TI_UINT8*)&disAssoc, sizeof(disAssoc_t), 0);
1596
1597     return status;
1598 }
1599
1600