Home | History | Annotate | Download | only in Sta_Management
      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, &param);
   1078     if (status == TI_OK)
   1079     {
   1080         if (param.content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE)
   1081         {
   1082             *cap |= DOT11_CAPS_ESS;
   1083         } else {
   1084             *cap |= DOT11_CAPS_IBSS;
   1085         }
   1086     } else {
   1087         return TI_NOK;
   1088     }
   1089 
   1090     /* Privacy */
   1091     param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
   1092     status =  rsn_getParam(pCtx->hRsn, &param);
   1093     if (status == TI_OK)
   1094     {
   1095         if (param.content.rsnEncryptionStatus != TWD_CIPHER_NONE)
   1096         {
   1097             *cap |= DOT11_CAPS_PRIVACY;
   1098         }
   1099     } else {
   1100         return TI_NOK;
   1101     }
   1102 
   1103     /* Preamble */
   1104     param.paramType = SITE_MGR_DESIRED_PREAMBLE_TYPE_PARAM;
   1105     status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
   1106     if (status == TI_OK)
   1107     {
   1108         if (param.content.siteMgrCurrentPreambleType == PREAMBLE_SHORT)
   1109             *cap |= DOT11_CAPS_SHORT_PREAMBLE;
   1110     } else {
   1111         return TI_NOK;
   1112     }
   1113 
   1114     /* Pbcc */
   1115     param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
   1116     status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
   1117     if (status == TI_OK)
   1118     {
   1119         if(param.content.siteMgrCurrentRateMask.supportedRateMask & DRV_RATE_MASK_22_PBCC)
   1120             *cap |= DOT11_CAPS_PBCC;
   1121     } else {
   1122         return TI_NOK;
   1123     }
   1124 
   1125 
   1126     /* Checking if the station supports Spectrum Management (802.11h) */
   1127     param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
   1128     status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
   1129     if (status == TI_OK )
   1130     {
   1131         if( param.content.spectrumManagementEnabled)
   1132             *cap |= DOT11_SPECTRUM_MANAGEMENT;
   1133     }
   1134     else
   1135     {
   1136         return TI_NOK;
   1137     }
   1138 
   1139     /* slot time */
   1140     param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
   1141     status = siteMgr_getParam(pCtx->hSiteMgr, &param);
   1142     if(status == TI_OK)
   1143     {
   1144         mode = param.content.siteMgrDot11OperationalMode;
   1145     }
   1146     else
   1147         return TI_NOK;
   1148 
   1149     if(mode == DOT11_G_MODE)
   1150     {
   1151         /* new requirement: the short slot time should be set only
   1152            if the AP's modulation is OFDM (highest rate) */
   1153 
   1154         /* get Rates */
   1155         param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
   1156         status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
   1157         if (status == TI_OK)
   1158         {
   1159             rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask;
   1160             rateSuppMask  = param.content.siteMgrCurrentRateMask.supportedRateMask;
   1161         } else {
   1162             return TI_NOK;
   1163         }
   1164 
   1165         /* convert the bit map to the rates array */
   1166         rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex);
   1167 
   1168         if(ofdmIndex < len)
   1169             *cap |= DOT11_CAPS_SHORT_SLOT_TIME;
   1170 
   1171 /*
   1172         param.paramType = SITE_MGR_CURRENT_MODULATION_TYPE_PARAM;
   1173         status = siteMgr_getParam(pCtx->hSiteMgr, &param);
   1174         if(param.content.siteMgrCurrentModulationType == DRV_MODULATION_OFDM)
   1175             *cap |= DOT11_CAPS_SHORT_SLOT_TIME;
   1176 */
   1177     }
   1178 
   1179     /* Primary Site support HT ? */
   1180     param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT;
   1181     siteMgr_getParam(pCtx->hSiteMgr, &param);
   1182 
   1183     if (param.content.bPrimarySiteHtSupport == TI_TRUE)
   1184     {
   1185         /* Immediate Block Ack subfield - (is WME on?) AND (is HT Enable?) */
   1186         /* verify 11n_Enable and Chip type */
   1187         StaCap_IsHtEnable (pCtx->hStaCap, &b11nEnable);
   1188         /* verify that WME flag enable */
   1189         qosMngr_GetWmeEnableFlag (pCtx->hQosMngr, &bWmeEnable);
   1190 
   1191         if ((b11nEnable != TI_FALSE) && (bWmeEnable != TI_FALSE))
   1192         {
   1193             *cap |= DOT11_CAPS_IMMEDIATE_BA;
   1194         }
   1195     }
   1196 
   1197     return TI_OK;
   1198 }
   1199 
   1200 
   1201 TI_STATUS assoc_smSSIDBuild(assoc_t *pCtx, TI_UINT8 *pSSID, TI_UINT32 *ssidLen)
   1202 {
   1203     paramInfo_t         param;
   1204     TI_STATUS               status;
   1205     dot11_SSID_t        *pDot11Ssid;
   1206 
   1207     pDot11Ssid = (dot11_SSID_t*)pSSID;
   1208     /* set SSID element id */
   1209     pDot11Ssid->hdr[0] = SSID_IE_ID;
   1210 
   1211     /* get SSID */
   1212     param.paramType = SME_DESIRED_SSID_ACT_PARAM;
   1213     status =  sme_GetParam(pCtx->hSme, &param);
   1214     if (status != TI_OK)
   1215     {
   1216         return status;
   1217     }
   1218 
   1219     /* check for ANY ssid */
   1220     if (param.content.smeDesiredSSID.len != 0)
   1221     {
   1222         pDot11Ssid->hdr[1] = param.content.smeDesiredSSID.len;
   1223         os_memoryCopy(pCtx->hOs,
   1224                       (void *)pDot11Ssid->serviceSetId,
   1225                       (void *)param.content.smeDesiredSSID.str,
   1226                       param.content.smeDesiredSSID.len);
   1227 
   1228     } else {
   1229         /* if ANY ssid is configured, use the current SSID */
   1230         param.paramType = SITE_MGR_CURRENT_SSID_PARAM;
   1231         status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
   1232         if (status != TI_OK)
   1233         {
   1234             return status;
   1235         }
   1236         pDot11Ssid->hdr[1] = param.content.siteMgrCurrentSSID.len;
   1237         os_memoryCopy(pCtx->hOs,
   1238                       (void *)pDot11Ssid->serviceSetId,
   1239                       (void *)param.content.siteMgrCurrentSSID.str,
   1240                       param.content.siteMgrCurrentSSID.len);
   1241 
   1242     }
   1243 
   1244     *ssidLen = pDot11Ssid->hdr[1] + sizeof(dot11_eleHdr_t);
   1245 
   1246     return TI_OK;
   1247 }
   1248 
   1249 TI_STATUS assoc_smRatesBuild(assoc_t *pCtx, TI_UINT8 *pRates, TI_UINT32 *ratesLen)
   1250 {
   1251     paramInfo_t         param;
   1252     TI_STATUS           status;
   1253     TI_UINT32           rateSuppMask, rateBasicMask;
   1254     dot11_RATES_t       *pDot11Rates;
   1255     TI_UINT32           len = 0, ofdmIndex = 0;
   1256     TI_UINT8            ratesBuf[DOT11_MAX_SUPPORTED_RATES];
   1257     EDot11Mode          mode;
   1258     TI_UINT32           suppRatesLen, extSuppRatesLen, i;
   1259     pDot11Rates = (dot11_RATES_t*)pRates;
   1260 
   1261 
   1262     /* get Rates */
   1263     param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
   1264     status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
   1265     if (status == TI_OK)
   1266     {
   1267         rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask;
   1268         rateSuppMask  = param.content.siteMgrCurrentRateMask.supportedRateMask;
   1269     }
   1270     else
   1271     {
   1272         return TI_NOK;
   1273     }
   1274 
   1275     /* get operational mode */
   1276     param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
   1277     status = siteMgr_getParam(pCtx->hSiteMgr, &param);
   1278     if(status == TI_OK)
   1279         mode = param.content.siteMgrDot11OperationalMode;
   1280     else
   1281         return TI_NOK;
   1282 
   1283     /* convert the bit map to the rates array */
   1284     /* remove MCS rates from Extended Supported Rates IE */
   1285     rateSuppMask &= ~(DRV_RATE_MASK_MCS_0_OFDM |
   1286                       DRV_RATE_MASK_MCS_1_OFDM |
   1287                       DRV_RATE_MASK_MCS_2_OFDM |
   1288                       DRV_RATE_MASK_MCS_3_OFDM |
   1289                       DRV_RATE_MASK_MCS_4_OFDM |
   1290                       DRV_RATE_MASK_MCS_5_OFDM |
   1291                       DRV_RATE_MASK_MCS_6_OFDM |
   1292                       DRV_RATE_MASK_MCS_7_OFDM );
   1293 
   1294     rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex);
   1295 
   1296     if(mode != DOT11_G_MODE || ofdmIndex == len )
   1297     {
   1298         pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID;
   1299         pDot11Rates->hdr[1] = len;
   1300         os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, len);
   1301         *ratesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
   1302     }
   1303     else
   1304     {
   1305         /* fill in the supported rates */
   1306         pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID;
   1307         pDot11Rates->hdr[1] = ofdmIndex;
   1308         os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]);
   1309         suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
   1310         /* fill in the extended supported rates */
   1311         pDot11Rates = (dot11_RATES_t*)(pRates + suppRatesLen);
   1312         pDot11Rates->hdr[0] = EXT_SUPPORTED_RATES_IE_ID;
   1313         pDot11Rates->hdr[1] = len - ofdmIndex;
   1314         os_memoryCopy(NULL, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]);
   1315         extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
   1316         *ratesLen = suppRatesLen + extSuppRatesLen;
   1317     }
   1318 
   1319     TRACE3(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - bitmapSupp= 0x%X,bitMapBasic = 0x%X, len = %d\n", rateSuppMask,rateBasicMask,len);
   1320     for(i=0; i<len; i++)
   1321     {
   1322         TRACE2(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - ratesBuf[%d] = 0x%X\n", i, ratesBuf[i]);
   1323     }
   1324 
   1325     return TI_OK;
   1326 }
   1327 
   1328 TI_STATUS assoc_powerCapabilityBuild(assoc_t *pCtx, TI_UINT8 *pPowerCapability, TI_UINT32 *powerCapabilityLen)
   1329 {
   1330     paramInfo_t         param;
   1331     TI_STATUS               status;
   1332     dot11_CAPABILITY_t      *pDot11PowerCapability;
   1333 
   1334     pDot11PowerCapability = (dot11_CAPABILITY_t*)pPowerCapability;
   1335 
   1336     /* set Power Capability element id */
   1337     pDot11PowerCapability->hdr[0] = DOT11_CAPABILITY_ELE_ID;
   1338     pDot11PowerCapability->hdr[1] = DOT11_CAPABILITY_ELE_LEN;
   1339 
   1340     /* get power capability */
   1341     param.paramType = REGULATORY_DOMAIN_POWER_CAPABILITY_PARAM;
   1342     status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
   1343 
   1344     if (status == TI_OK)
   1345     {
   1346         pDot11PowerCapability->minTxPower = param.content.powerCapability.minTxPower;
   1347         pDot11PowerCapability->maxTxPower = param.content.powerCapability.maxTxPower;
   1348         *powerCapabilityLen = pDot11PowerCapability->hdr[1] + sizeof(dot11_eleHdr_t);
   1349     }
   1350     else
   1351         *powerCapabilityLen = 0;
   1352 
   1353     return TI_OK;
   1354 }
   1355 
   1356 TI_STATUS assoc_smRequestBuild(assoc_t *pCtx, TI_UINT8* reqBuf, TI_UINT32* reqLen)
   1357 {
   1358     TI_STATUS       status;
   1359     TI_UINT8        *pRequest;
   1360     TI_UINT32       len;
   1361     paramInfo_t     param;
   1362     TTwdParamInfo   tTwdParam;
   1363     TI_UINT16       capabilities;
   1364     ECipherSuite    eCipherSuite = TWD_CIPHER_NONE; /* To be used for checking whether
   1365                                                        AP supports HT rates and TKIP
   1366                                                      */
   1367 
   1368     pRequest = reqBuf;
   1369     *reqLen = 0;
   1370 
   1371     /* insert capabilities */
   1372     status = assoc_smCapBuild(pCtx, &capabilities);
   1373     if (status == TI_OK)
   1374     {
   1375         *(TI_UINT16*)pRequest = capabilities;
   1376     }
   1377     else
   1378         return TI_NOK;
   1379 
   1380     pRequest += 2;
   1381     *reqLen += 2;
   1382 
   1383     /* insert listen interval */
   1384     tTwdParam.paramType = TWD_LISTEN_INTERVAL_PARAM_ID;
   1385     status =  TWD_GetParam (pCtx->hTWD, &tTwdParam);
   1386     if (status == TI_OK)
   1387     {
   1388         *(TI_UINT16*)pRequest = ENDIAN_HANDLE_WORD((TI_UINT16)tTwdParam.content.halCtrlListenInterval);
   1389     } else {
   1390         return TI_NOK;
   1391     }
   1392 
   1393     pRequest += 2;
   1394     *reqLen += 2;
   1395     if (pCtx->reAssoc)
   1396     {   /* Insert currentAPAddress element only in reassoc request*/
   1397         param.paramType = SITE_MGR_PREV_SITE_BSSID_PARAM;
   1398         status = siteMgr_getParam(pCtx->hSiteMgr, &param);
   1399         if (status == TI_OK)
   1400         {
   1401             MAC_COPY (pRequest, param.content.siteMgrDesiredBSSID);
   1402             TRACE6(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - prev AP = %x-%x-%x-%x-%x-%x\n", param.content.siteMgrDesiredBSSID[0], param.content.siteMgrDesiredBSSID[1], param.content.siteMgrDesiredBSSID[2], param.content.siteMgrDesiredBSSID[3], param.content.siteMgrDesiredBSSID[4], param.content.siteMgrDesiredBSSID[5]);
   1403 
   1404 
   1405             pRequest += MAC_ADDR_LEN;
   1406             *reqLen += MAC_ADDR_LEN;
   1407         }
   1408         else
   1409         {
   1410             TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: ASSOC_REQ - No prev AP \n");
   1411             return status;
   1412 
   1413         }
   1414     }
   1415 
   1416     /* insert SSID element */
   1417     status = assoc_smSSIDBuild(pCtx, pRequest, &len);
   1418     if (status != TI_OK)
   1419     {
   1420         return TI_NOK;
   1421     }
   1422 
   1423     pRequest += len;
   1424     *reqLen += len;
   1425 
   1426     /* insert Rates element */
   1427     status = assoc_smRatesBuild(pCtx, pRequest, &len);
   1428     if (status != TI_OK)
   1429     {
   1430         return TI_NOK;
   1431     }
   1432     pRequest += len;
   1433     *reqLen += len;
   1434 
   1435     /* Checking if the station supports Spectrum Management (802.11h) */
   1436     param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
   1437     status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain,&param);
   1438     if( (status == TI_OK) && param.content.spectrumManagementEnabled)
   1439     {
   1440         /* Checking the selected AP capablities */
   1441         param.paramType = SITE_MGR_SITE_CAPABILITY_PARAM;
   1442         status =  siteMgr_getParam(pCtx->hSiteMgr,&param);
   1443         if(status == TI_OK && ((param.content.siteMgrSiteCapability & DOT11_SPECTRUM_MANAGEMENT) != 0))
   1444         {
   1445             /* insert Power capability element */
   1446             status = assoc_powerCapabilityBuild(pCtx, pRequest, &len);
   1447             if (status != TI_OK)
   1448             {
   1449                 return TI_NOK;
   1450             }
   1451             pRequest += len;
   1452             *reqLen += len;
   1453 #if 0
   1454             /* insert Supported Channels element */
   1455             status = assoc_supportedChannelBuild(pCtx, pRequest, &len);
   1456             if (status != TI_OK)
   1457             {
   1458                 return TI_NOK;
   1459             }
   1460             pRequest += len;
   1461             *reqLen += len;
   1462 #endif
   1463         }
   1464 
   1465 
   1466     }
   1467 
   1468     status = qosMngr_getQosCapabiltyInfeElement(pCtx->hQosMngr,pRequest,&len);
   1469     if (status != TI_OK)
   1470     {
   1471         return TI_NOK;
   1472     }
   1473     pRequest += len;
   1474     *reqLen += len;
   1475 
   1476 
   1477 #ifdef XCC_MODULE_INCLUDED
   1478     status = rsn_getXCCExtendedInfoElement(pCtx->hRsn, pRequest, (TI_UINT8*)&len);
   1479     if (status != TI_OK)
   1480     {
   1481         return TI_NOK;
   1482     }
   1483     pRequest += len;
   1484     *reqLen += len;
   1485 
   1486     if (pCtx->reAssoc)
   1487     {   /* insert CCKM information element only in reassoc */
   1488         status = XCCMngr_getCckmInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len);
   1489 
   1490         if (status != TI_OK)
   1491         {
   1492             return TI_NOK;
   1493         }
   1494         pRequest += len;
   1495         *reqLen += len;
   1496     }
   1497     status = XCCMngr_getXCCVersionInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len);
   1498     if (status != TI_OK)
   1499     {
   1500         return TI_NOK;
   1501     }
   1502     pRequest += len;
   1503     *reqLen += len;
   1504 
   1505     /* Insert Radio Mngt Capability IE */
   1506     status = measurementMgr_radioMngtCapabilityBuild(pCtx->hMeasurementMgr, pRequest, (TI_UINT8*)&len);
   1507     if (status != TI_OK)
   1508     {
   1509         return TI_NOK;
   1510     }
   1511     pRequest += len;
   1512     *reqLen += len;
   1513 #endif
   1514 
   1515      /* Get Simple-Config state */
   1516     param.paramType = SITE_MGR_SIMPLE_CONFIG_MODE;
   1517     status = siteMgr_getParam(pCtx->hSiteMgr, &param);
   1518 
   1519    if (param.content.siteMgrWSCMode.WSCMode == TIWLN_SIMPLE_CONFIG_OFF)
   1520    {
   1521     /* insert RSN information elements */
   1522     status = rsn_getInfoElement(pCtx->hRsn, pRequest, &len);
   1523 
   1524 	if (status != TI_OK)
   1525 	{
   1526 		return TI_NOK;
   1527 	}
   1528 	pRequest += len;
   1529 	*reqLen += len;
   1530   }
   1531 
   1532     /* Privacy - Used later on HT */
   1533     param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
   1534     status          = rsn_getParam(pCtx->hRsn, &param);
   1535 
   1536     if(status == TI_OK)
   1537     {
   1538         eCipherSuite = param.content.rsnEncryptionStatus;
   1539     }
   1540 
   1541 
   1542     /* Primary Site support HT ? */
   1543     param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT;
   1544     siteMgr_getParam(pCtx->hSiteMgr, &param);
   1545 
   1546     /* Disallow TKIP with HT Rates: If this is the case - discard HT rates from Association Request */
   1547     if((TI_TRUE == param.content.bPrimarySiteHtSupport) && (eCipherSuite != TWD_CIPHER_TKIP))
   1548     {
   1549         status = StaCap_GetHtCapabilitiesIe (pCtx->hStaCap, pRequest, &len);
   1550     	if (status != TI_OK)
   1551     	{
   1552     		return TI_NOK;
   1553     	}
   1554     	pRequest += len;
   1555     	*reqLen += len;
   1556     }
   1557 
   1558 	status = qosMngr_assocReqBuild(pCtx->hQosMngr,pRequest,&len);
   1559 	if (status != TI_OK)
   1560 	{
   1561 		return TI_NOK;
   1562 	}
   1563 	pRequest += len;
   1564 	*reqLen += len;
   1565 
   1566 	status = apConn_getVendorSpecificIE(pCtx->hApConn, pRequest, &len);
   1567 	if (status != TI_OK)
   1568 	{
   1569 		return TI_NOK;
   1570 	}
   1571 	pRequest += len;
   1572 	*reqLen += len;
   1573 
   1574     if (*reqLen>=MAX_ASSOC_MSG_LENGTH)
   1575     {
   1576         return TI_NOK;
   1577     }
   1578 
   1579     return TI_OK;
   1580 }
   1581 
   1582 
   1583 
   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