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