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