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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 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 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 957 TI_STATUS assoc_smActionUnexpected(assoc_t *pAssoc) 958 { 959 return TI_OK; 960 } 961 962 /* local functions */ 963 964 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 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 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 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 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 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 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 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 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 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 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 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 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 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