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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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,¶m);
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,¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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