/* * assocSM.c * * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name Texas Instruments nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** \file assocSM.c * \brief 802.11 association SM source * * \see assocSM.h */ /***************************************************************************/ /* */ /* MODULE: assocSM.c */ /* PURPOSE: 802.11 association SM source */ /* */ /***************************************************************************/ #define __FILE_ID__ FILE_ID_63 #include "osApi.h" #include "paramOut.h" #include "rate.h" #include "timer.h" #include "fsm.h" #include "report.h" #include "DataCtrl_Api.h" #include "siteMgrApi.h" #include "rsnApi.h" #include "regulatoryDomainApi.h" #include "mlmeBuilder.h" #include "mlmeApi.h" #include "AssocSM.h" #include "qosMngr_API.h" #ifdef XCC_MODULE_INCLUDED #include "XCCRMMngr.h" #include "XCCMngr.h" #endif #include "apConn.h" #include "TWDriver.h" #include "DrvMainModules.h" #include "StaCap.h" #include "smeApi.h" #include "rsn.h" /* Constants */ /** number of states in the state machine */ #define ASSOC_SM_NUM_STATES 3 /** number of events in the state machine */ #define ASSOC_SM_NUM_EVENTS 6 /* Enumerations */ /* Typedefs */ /* Structures */ /* External data definitions */ /* External functions definitions */ /* Global variables */ /* Local function prototypes */ /* functions */ /* state machine functions */ TI_STATUS assoc_smEvent(assoc_t *pAssoc, TI_UINT8 event, void *pData); void assoc_smTimeout(TI_HANDLE hAssoc, TI_BOOL bTwdInitOccured); TI_STATUS assoc_smStartIdle(assoc_t *pAssoc); TI_STATUS assoc_smStopWait(assoc_t *pAssoc); TI_STATUS assoc_smSuccessWait(assoc_t *pAssoc); TI_STATUS assoc_smFailureWait(assoc_t *pAssoc); TI_STATUS assoc_smTimeoutWait(assoc_t *pAssoc); TI_STATUS assoc_smMaxRetryWait(assoc_t *pAssoc); TI_STATUS assoc_smStopAssoc(assoc_t *pAssoc); TI_STATUS assoc_smActionUnexpected(assoc_t *pAssoc); TI_STATUS assoc_smResetRetry(assoc_t *pAssoc); TI_STATUS assoc_smIncRetry(assoc_t *pAssoc); TI_STATUS assoc_smReportSuccess(assoc_t *pAssoc); TI_STATUS assoc_smReportFailure(assoc_t *pAssoc, TI_UINT16 uStatusCode); TI_STATUS assoc_smSendAssocReq(assoc_t *pAssoc); TI_STATUS assoc_smStartTimer(assoc_t *pAssoc); TI_STATUS assoc_smStopTimer(assoc_t *pAssoc); TI_STATUS assoc_smCapBuild(assoc_t *pCtx, TI_UINT16 *cap); TI_STATUS assoc_smSSIDBuild(assoc_t *pCtx, TI_UINT8 *pSSID, TI_UINT32 *ssidLen); TI_STATUS assoc_smRatesBuild(assoc_t *pCtx, TI_UINT8 *pRates, TI_UINT32 *ratesLen); TI_STATUS assoc_smRequestBuild(assoc_t *pCtx, TI_UINT8* reqBuf, TI_UINT32* reqLen); TI_STATUS assoc_saveAssocReqMessage(assoc_t *pAssocSm, TI_UINT8 *pAssocBuffer, TI_UINT32 length); TI_STATUS assoc_sendDisAssoc(assoc_t *pAssocSm, mgmtStatus_e reason); /** * * assoc_create - allocate memory for association SM * * \b Description: * * Allocate memory for association SM. \n * Allocates memory for Association context. \n * Allocates memory for association SM matrix. \n * * \b ARGS: * * I - hOs - OS context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa rsn_mainSecSmKeysOnlyStop() */ TI_HANDLE assoc_create(TI_HANDLE hOs) { assoc_t *pHandle; TI_STATUS status; /* allocate association context memory */ pHandle = (assoc_t*)os_memoryAlloc(hOs, sizeof(assoc_t)); if (pHandle == NULL) { return NULL; } os_memoryZero(hOs, pHandle, sizeof(assoc_t)); pHandle->hOs = hOs; /* allocate memory for association state machine */ status = fsm_Create(hOs, &pHandle->pAssocSm, ASSOC_SM_NUM_STATES, ASSOC_SM_NUM_EVENTS); if (status != TI_OK) { os_memoryFree(hOs, pHandle, sizeof(assoc_t)); return NULL; } return pHandle; } /** * * assocunload - unload association SM from memory * * \b Description: * * Unload association SM from memory * * \b ARGS: * * I - hAssoc - association SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa rsn_mainSecSmKeysOnlyStop() */ TI_STATUS assoc_unload(TI_HANDLE hAssoc) { TI_STATUS status; assoc_t *pHandle; pHandle = (assoc_t*)hAssoc; status = fsm_Unload(pHandle->hOs, pHandle->pAssocSm); if (status != TI_OK) { /* report failure but don't stop... */ TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: Error releasing FSM memory \n"); } if (pHandle->hAssocSmTimer) { tmr_DestroyTimer (pHandle->hAssocSmTimer); } os_memoryFree(pHandle->hOs, hAssoc, sizeof(assoc_t)); return TI_OK; } /** * * assoc_config - configure a new association SM * * \b Description: * * Configure a new association SM. * * \b RETURNS: * * void * * \sa assoc_Create, assoc_Unload */ void assoc_init (TStadHandlesList *pStadHandles) { assoc_t *pHandle = (assoc_t*)(pStadHandles->hAssoc); /** Main 802.1X State Machine matrix */ fsm_actionCell_t assoc_smMatrix[ASSOC_SM_NUM_STATES][ASSOC_SM_NUM_EVENTS] = { /* next state and actions for IDLE state */ {{ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smStartIdle}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smActionUnexpected} }, /* next state and actions for WAIT state */ {{ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smStopWait}, {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smSuccessWait}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smFailureWait}, {ASSOC_SM_STATE_WAIT, (fsm_Action_t)assoc_smTimeoutWait}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smMaxRetryWait} }, /* next state and actions for ASSOC state */ {{ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_IDLE, (fsm_Action_t)assoc_smStopAssoc}, {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected}, {ASSOC_SM_STATE_ASSOC, (fsm_Action_t)assoc_smActionUnexpected} }}; /* configure state machine */ fsm_Config (pHandle->pAssocSm, &assoc_smMatrix[0][0], ASSOC_SM_NUM_STATES, ASSOC_SM_NUM_EVENTS, NULL, pStadHandles->hOs); pHandle->assocRejectCount = 0; pHandle->assocTimeoutCount = 0; pHandle->currentState = ASSOC_SM_STATE_IDLE; pHandle->hMlme = pStadHandles->hMlmeSm; pHandle->hRegulatoryDomain = pStadHandles->hRegulatoryDomain; pHandle->hSiteMgr = pStadHandles->hSiteMgr; pHandle->hCtrlData = pStadHandles->hCtrlData; pHandle->hTWD = pStadHandles->hTWD; pHandle->hRsn = pStadHandles->hRsn; pHandle->hReport = pStadHandles->hReport; pHandle->hOs = pStadHandles->hOs; pHandle->hXCCMngr = pStadHandles->hXCCMngr; pHandle->hQosMngr = pStadHandles->hQosMngr; pHandle->hMeasurementMgr = pStadHandles->hMeasurementMgr; pHandle->hApConn = pStadHandles->hAPConnection; pHandle->hTimer = pStadHandles->hTimer; pHandle->hStaCap = pStadHandles->hStaCap; pHandle->hSme = pStadHandles->hSme; } TI_STATUS assoc_SetDefaults (TI_HANDLE hAssoc, assocInitParams_t *pAssocInitParams) { assoc_t *pHandle = (assoc_t*)hAssoc; pHandle->timeout = pAssocInitParams->assocResponseTimeout; pHandle->maxCount = pAssocInitParams->assocMaxRetryCount; /* allocate OS timer memory */ pHandle->hAssocSmTimer = tmr_CreateTimer (pHandle->hTimer); if (pHandle->hAssocSmTimer == NULL) { TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "assoc_SetDefaults(): Failed to create hAssocSmTimer!\n"); return TI_NOK; } return TI_OK; } /** * * assoc_start - Start event for the association SM * * \b Description: * * Start event for the association SM * * \b ARGS: * * I - hAssoc - Association SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa assoc_Stop, assoc_Recv */ TI_STATUS assoc_start(TI_HANDLE hAssoc) { TI_STATUS status; assoc_t *pHandle; pHandle = (assoc_t*)hAssoc; if (pHandle == NULL) { return TI_NOK; } pHandle->reAssoc = TI_FALSE; pHandle->disAssoc = TI_FALSE; status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_START, hAssoc); return status; } /** * * assoc_start - Start event for the association SM * * \b Description: * * Start event for the association SM - for Re-assoc request * * \b ARGS: * * I - hAssoc - Association SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa assoc_Stop, assoc_Recv */ TI_STATUS reassoc_start(TI_HANDLE hAssoc) { TI_STATUS status; assoc_t *pHandle; pHandle = (assoc_t*)hAssoc; if (pHandle == NULL) { return TI_NOK; } pHandle->reAssoc = TI_TRUE; status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_START, hAssoc); return status; } /** * * assoc_stop - Stop event for the association SM * * \b Description: * * Stop event for the association SM * * \b ARGS: * * I - hAssoc - Association SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa assoc_Start, assoc_Recv */ TI_STATUS assoc_stop(TI_HANDLE hAssoc) { TI_STATUS status; assoc_t *pHandle; pHandle = (assoc_t*)hAssoc; if (pHandle == NULL) { return TI_NOK; } status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_STOP, hAssoc); return status; } TI_STATUS assoc_setDisAssocFlag(TI_HANDLE hAssoc, TI_BOOL disAsoccFlag) { assoc_t *pHandle; pHandle = (assoc_t*)hAssoc; pHandle->disAssoc = disAsoccFlag; return TI_OK; } /** * * assoc_recv - Recive a message from the AP * * \b Description: * * Parse a message form the AP and perform the appropriate event. * * \b ARGS: * * I - hAssoc - Association SM context \n * I - pFrame - Frame recieved \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa assoc_Start, assoc_Stop */ TI_STATUS assoc_recv(TI_HANDLE hAssoc, mlmeFrameInfo_t *pFrame) { TI_STATUS status; assoc_t *pHandle = (assoc_t*)hAssoc; TTwdParamInfo tTwdParam; TI_UINT16 rspStatus; if (pHandle == NULL) { return TI_NOK; } /* ensure that the SM is waiting for assoc response */ if(pHandle->currentState != ASSOC_SM_STATE_WAIT) return TI_OK; if ((pFrame->subType != ASSOC_RESPONSE) && (pFrame->subType != RE_ASSOC_RESPONSE)) { return TI_NOK; } /* check response status */ rspStatus = pFrame->content.assocRsp.status; if (rspStatus == 0) { TRsnData rsnData; dot11_RSN_t *pRsnIe; TI_UINT8 curRsnData[255]; TI_UINT8 rsnAssocIeLen; TI_UINT8 length = 0; TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG Success associating to AP \n"); /* set AID to HAL */ tTwdParam.paramType = TWD_AID_PARAM_ID; tTwdParam.content.halCtrlAid = pFrame->content.assocRsp.aid; TWD_SetParam (pHandle->hTWD, &tTwdParam); /* Get the RSN IE data */ pRsnIe = pFrame->content.assocRsp.pRsnIe; while (length < pFrame->content.assocRsp.rsnIeLen && (pFrame->content.assocRsp.rsnIeLen < 255)) { curRsnData[0+length] = pRsnIe->hdr[0]; curRsnData[1+length] = pRsnIe->hdr[1]; os_memoryCopy(pHandle->hOs, &curRsnData[2+length], (void *)pRsnIe->rsnIeData, pRsnIe->hdr[1]); length += pRsnIe->hdr[1] + 2; pRsnIe += 1; } if (pFrame->content.assocRsp.rsnIeLen != 0) { rsnData.pIe = curRsnData; rsnData.ieLen = pFrame->content.assocRsp.rsnIeLen; rsnData.privacy = ((pFrame->content.assocRsp.capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TI_TRUE : TI_FALSE; rsn_setSite(pHandle->hRsn, &rsnData, NULL, &rsnAssocIeLen); } /* update siteMgr with capabilities and whether we are connected to Cisco AP */ siteMgr_assocReport(pHandle->hSiteMgr, pFrame->content.assocRsp.capabilities, pFrame->content.assocRsp.ciscoIEPresent); /* update QoS Manager - it the QOS active protocol is NONE, or no WME IE present, it will return TI_OK */ /* if configured by AP, update MSDU lifetime */ status = qosMngr_setSite(pHandle->hQosMngr, &pFrame->content.assocRsp); if(status != TI_OK) { TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: DEBUG - Association failed : qosMngr_setSite error \n"); /* in case we wanted to work with qosAP and failed to connect to qos AP we want to reassociated again to another one */ status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_FAIL, hAssoc); } else { status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_SUCCESS, hAssoc); } } else { pHandle->assocRejectCount++; /* If there was attempt to renegotiate voice settings, update QoS Manager */ qosMngr_checkTspecRenegResults(pHandle->hQosMngr, &pFrame->content.assocRsp); /* check failure reason */ switch (rspStatus) { case 0: break; case 1: /* print debug message */ TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Unspecified error \n"); break; case 10: /* print debug message */ TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Cannot support all requested capabilities in the Capability Information field \n"); break; case 11: /* print debug message */ TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Reassociation denied due to inability to confirm that association exists \n"); break; case 12: /* print debug message */ TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Association denied due to reason outside the scope of this standard \n"); rsn_reportAuthFailure(pHandle->hRsn, RSN_AUTH_STATUS_INVALID_TYPE); break; case 13: TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Association denied due to wrong authentication algorithm \n"); rsn_reportAuthFailure(pHandle->hRsn, RSN_AUTH_STATUS_INVALID_TYPE); break; case 17: /* print debug message */ TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association denied: Association denied because AP is unable to handle additional associated stations \n"); break; case 18: /* print debug message */ 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"); break; default: /* print error message on wrong error code for association response */ TRACE1(pHandle->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: ERROR - Association denied: error code (%d) irrelevant \n", rspStatus); break; } status = assoc_smEvent(pHandle, ASSOC_SM_EVENT_FAIL, hAssoc); } return status; } /** * * assoc_getParam - Get a specific parameter from the association SM * * \b Description: * * Get a specific parameter from the association SM. * * \b ARGS: * * I - hAssoc - Association SM context \n * I/O - pParam - Parameter \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa assoc_Start, assoc_Stop */ TI_STATUS assoc_getParam(TI_HANDLE hAssoc, paramInfo_t *pParam) { assoc_t *pHandle = (assoc_t *)hAssoc; if ((pHandle == NULL) || (pParam == NULL)) { return TI_NOK; } /* serch parameter type */ switch (pParam->paramType) { case ASSOC_RESPONSE_TIMEOUT_PARAM: pParam->content.assocResponseTimeout = pHandle->timeout; break; case ASSOC_COUNTERS_PARAM: pParam->content.siteMgrTiWlanCounters.AssocRejects = pHandle->assocRejectCount; pParam->content.siteMgrTiWlanCounters.AssocTimeouts = pHandle->assocTimeoutCount; break; case ASSOC_ASSOCIATION_REQ_PARAM: pParam->content.assocReqBuffer.buffer = pHandle->assocReqBuffer; pParam->content.assocReqBuffer.bufferSize = pHandle->assocReqLen; pParam->content.assocReqBuffer.reAssoc = pHandle->reAssoc; break; case ASSOC_ASSOCIATION_RESP_PARAM: pParam->content.assocReqBuffer.buffer = pHandle->assocRespBuffer; pParam->content.assocReqBuffer.bufferSize = pHandle->assocRespLen; pParam->content.assocReqBuffer.reAssoc = pHandle->reAssocResp; break; case ASSOC_ASSOCIATION_INFORMATION_PARAM: { TI_UINT8 reqBuffIEOffset, respBuffIEOffset; TI_UINT32 RequestIELength = 0; TI_UINT32 ResponseIELength = 0; paramInfo_t *lParam; ScanBssType_enum bssType; TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG - Association Information Get: \n"); lParam = (paramInfo_t *)os_memoryAlloc(pHandle->hOs, sizeof(paramInfo_t)); if (!lParam) { return TI_NOK; } /* Assoc exists only in Infrastructure */ lParam->paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM; ctrlData_getParam(pHandle->hCtrlData, lParam); bssType = lParam->content.ctrlDataCurrentBssType; os_memoryFree(pHandle->hOs, lParam, sizeof(paramInfo_t)); if (bssType != BSS_INFRASTRUCTURE) { TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "Not in Infrastructure BSS, No ASSOC Info for GET ASSOC_ASSOCIATION_INFORMATION_PARAM\n"); return TI_NOK; } /* Init the result buffer to 0 */ os_memoryZero(pHandle->hOs ,&pParam->content, sizeof(OS_802_11_ASSOCIATION_INFORMATION)); reqBuffIEOffset = 4; /* In Assoc request frame IEs are located from byte 4 */ respBuffIEOffset = 6; /* In Assoc response frame the IEs are located from byte 6 */ /* If the last associate was re-associciation, the current AP MAC address */ /* is placed before the IEs. Copy it to the result parameters. */ if (pHandle->reAssoc) { MAC_COPY (pParam->content.assocAssociationInformation.RequestFixedIEs.CurrentAPAddress, &pHandle->assocReqBuffer[reqBuffIEOffset]); reqBuffIEOffset += MAC_ADDR_LEN; } /* Calculate length of Info elements in assoc request and response frames */ if(pHandle->assocReqLen > reqBuffIEOffset) RequestIELength = pHandle->assocReqLen - reqBuffIEOffset; if(pHandle->assocRespLen > respBuffIEOffset) ResponseIELength = pHandle->assocRespLen - respBuffIEOffset; /* Copy the association request information */ pParam->content.assocAssociationInformation.Length = sizeof(OS_802_11_ASSOCIATION_INFORMATION); pParam->content.assocAssociationInformation.AvailableRequestFixedIEs = OS_802_11_AI_REQFI_CAPABILITIES | OS_802_11_AI_REQFI_LISTENINTERVAL; pParam->content.assocAssociationInformation.RequestFixedIEs.Capabilities = *(TI_UINT16*)&(pHandle->assocReqBuffer[0]); pParam->content.assocAssociationInformation.RequestFixedIEs.ListenInterval = *(TI_UINT16*)(&pHandle->assocReqBuffer[2]); pParam->content.assocAssociationInformation.RequestIELength = RequestIELength; pParam->content.assocAssociationInformation.OffsetRequestIEs = 0; if (RequestIELength > 0) { pParam->content.assocAssociationInformation.OffsetRequestIEs = (TI_UINT32)&pHandle->assocReqBuffer[reqBuffIEOffset]; } /* Copy the association response information */ pParam->content.assocAssociationInformation.AvailableResponseFixedIEs = OS_802_11_AI_RESFI_CAPABILITIES | OS_802_11_AI_RESFI_STATUSCODE | OS_802_11_AI_RESFI_ASSOCIATIONID; pParam->content.assocAssociationInformation.ResponseFixedIEs.Capabilities = *(TI_UINT16*)&(pHandle->assocRespBuffer[0]); pParam->content.assocAssociationInformation.ResponseFixedIEs.StatusCode = *(TI_UINT16*)&(pHandle->assocRespBuffer[2]); pParam->content.assocAssociationInformation.ResponseFixedIEs.AssociationId = *(TI_UINT16*)&(pHandle->assocRespBuffer[4]); pParam->content.assocAssociationInformation.ResponseIELength = ResponseIELength; pParam->content.assocAssociationInformation.OffsetResponseIEs = 0; if (ResponseIELength > 0) { pParam->content.assocAssociationInformation.OffsetResponseIEs = (TI_UINT32)&pHandle->assocRespBuffer[respBuffIEOffset]; } } break; default: return TI_NOK; } return TI_OK; } /** * * assoc_setParam - Set a specific parameter to the association SM * * \b Description: * * Set a specific parameter to the association SM. * * \b ARGS: * * I - hAssoc - Association SM context \n * I/O - pParam - Parameter \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa assoc_Start, assoc_Stop */ TI_STATUS assoc_setParam(TI_HANDLE hAssoc, paramInfo_t *pParam) { assoc_t *pHandle; pHandle = (assoc_t*)hAssoc; if ((pHandle == NULL) || (pParam == NULL)) { return TI_NOK; } switch (pParam->paramType) { case ASSOC_RESPONSE_TIMEOUT_PARAM: /* check bounds */ if ((pParam->content.assocResponseTimeout >= ASSOC_RESPONSE_TIMEOUT_MIN) && (pParam->content.assocResponseTimeout <= ASSOC_RESPONSE_TIMEOUT_MAX)) { pHandle->timeout = pParam->content.assocResponseTimeout; } else { return TI_NOK; } break; default: return TI_NOK; } return TI_OK; } /** * * assoc_smTimeout - Time out event activation function * * \b Description: * * Time out event activation function. * * \b ARGS: * * I - hAssoc - Association SM context \n * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa assoc_Start, assoc_Stop */ void assoc_smTimeout(TI_HANDLE hAssoc, TI_BOOL bTwdInitOccured) { assoc_t *pHandle; pHandle = (assoc_t*)hAssoc; if (pHandle == NULL) { return; } pHandle->assocTimeoutCount++; assoc_smEvent(pHandle, ASSOC_SM_EVENT_TIMEOUT, hAssoc); } /** * * assoc_smEvent - Perform an event on the association SM * * \b Description: * * Perform an event on the association SM. * * \b ARGS: * * I - pAssoc - Association SM context \n * I - event - Current event \n * I - pData - event related data * * \b RETURNS: * * TI_OK if successful, TI_NOK otherwise. * * \sa */ TI_STATUS assoc_smEvent(assoc_t *pAssoc, TI_UINT8 event, void *pData) { TI_STATUS status; TI_UINT8 nextState; status = fsm_GetNextState(pAssoc->pAssocSm, pAssoc->currentState, event, &nextState); if (status != TI_OK) { TRACE0(pAssoc->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: ERROR - failed getting next state \n"); return(TI_NOK); } TRACE3( pAssoc->hReport, REPORT_SEVERITY_INFORMATION, "assoc_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", pAssoc->currentState, event, nextState); status = fsm_Event(pAssoc->pAssocSm, &pAssoc->currentState, event, pData); return(status); } /* state machine functions */ TI_STATUS assoc_smStartIdle(assoc_t *pAssoc) { TI_STATUS status; status = assoc_smResetRetry(pAssoc); status = assoc_smSendAssocReq(pAssoc); status = assoc_smStartTimer(pAssoc); status = assoc_smIncRetry(pAssoc); return status; } TI_STATUS assoc_smStopWait(assoc_t *pAssoc) { TI_STATUS status; status = assoc_smStopTimer(pAssoc); return status; } TI_STATUS assoc_smSuccessWait(assoc_t *pAssoc) { TI_STATUS status; status = assoc_smStopTimer(pAssoc); status = assoc_smReportSuccess(pAssoc); return status; } TI_STATUS assoc_smFailureWait(assoc_t *pAssoc) { TI_STATUS status; TI_UINT16 uRspStatus = *(TI_UINT16*)&(pAssoc->assocRespBuffer[2]); status = assoc_smStopTimer(pAssoc); /* Sanity check. If the Response status is indeed not 0 */ if (uRspStatus) { status = assoc_smReportFailure(pAssoc, uRspStatus); } else /* (uRspStatus == 0) how did we get here ? */ { TRACE0(pAssoc->hReport, REPORT_SEVERITY_ERROR, "while Response status is OK (0) !!! \n"); status = assoc_smReportFailure(pAssoc, (TI_UINT16)TI_NOK); } return status; } TI_STATUS assoc_smTimeoutWait(assoc_t *pAssoc) { TI_STATUS status; status = assoc_smSendAssocReq(pAssoc); status = assoc_smStartTimer(pAssoc); status = assoc_smIncRetry(pAssoc); return status; } TI_STATUS assoc_smMaxRetryWait(assoc_t *pAssoc) { TI_STATUS status; status = assoc_smStopTimer(pAssoc); status = assoc_smReportFailure(pAssoc, STATUS_PACKET_REJ_TIMEOUT); return status; } TI_STATUS assoc_smSendAssocReq(assoc_t *pAssoc) { TI_UINT8 *assocMsg; TI_UINT32 msgLen; TI_STATUS status; dot11MgmtSubType_e assocType=ASSOC_REQUEST; assocMsg = os_memoryAlloc(pAssoc->hOs, MAX_ASSOC_MSG_LENGTH); if (!assocMsg) { return TI_NOK; } if (pAssoc->reAssoc) { assocType = RE_ASSOC_REQUEST; } status = assoc_smRequestBuild(pAssoc, assocMsg, &msgLen); if (status == TI_OK) { /* Save the association request message */ assoc_saveAssocReqMessage(pAssoc, assocMsg, msgLen); status = mlmeBuilder_sendFrame(pAssoc->hMlme, assocType, assocMsg, msgLen, 0); } os_memoryFree(pAssoc->hOs, assocMsg, MAX_ASSOC_MSG_LENGTH); return status; } TI_STATUS assoc_smStopAssoc(assoc_t *pAssoc) { if (pAssoc->disAssoc) { assoc_sendDisAssoc(pAssoc, STATUS_UNSPECIFIED); } return TI_OK; } TI_STATUS assoc_smActionUnexpected(assoc_t *pAssoc) { return TI_OK; } /* local functions */ TI_STATUS assoc_smResetRetry(assoc_t *pAssoc) { if (pAssoc == NULL) { return TI_NOK; } pAssoc->retryCount = 0; return TI_OK; } TI_STATUS assoc_smIncRetry(assoc_t *pAssoc) { TI_STATUS status; if (pAssoc == NULL) { return TI_NOK; } pAssoc->retryCount++; if (pAssoc->retryCount > pAssoc->maxCount) { status = assoc_smEvent(pAssoc, ASSOC_SM_EVENT_MAX_RETRY, pAssoc); return status; } return TI_OK; } TI_STATUS assoc_smReportSuccess(assoc_t *pAssoc) { TI_STATUS status; if (pAssoc == NULL) { return TI_NOK; } status = mlme_reportAssocStatus(pAssoc->hMlme, (TI_UINT16)TI_OK); return status; } TI_STATUS assoc_smReportFailure(assoc_t *pAssoc, TI_UINT16 uStatusCode) { TI_STATUS status; if (pAssoc == NULL) { return TI_NOK; } status = mlme_reportAssocStatus(pAssoc->hMlme, uStatusCode); return status; } TI_STATUS assoc_smStartTimer(assoc_t *pAssoc) { if (pAssoc == NULL) { return TI_NOK; } tmr_StartTimer (pAssoc->hAssocSmTimer, assoc_smTimeout, (TI_HANDLE)pAssoc, pAssoc->timeout, TI_FALSE); return TI_OK; } TI_STATUS assoc_smStopTimer(assoc_t *pAssoc) { if (pAssoc == NULL) { return TI_NOK; } tmr_StopTimer (pAssoc->hAssocSmTimer); /* If the timer was stopped it means the association is over, so we can clear the generic IE */ rsn_clearGenInfoElement(pAssoc->hRsn); return TI_OK; } /***************************************************************************** ** ** Association messages builder/Parser ** *****************************************************************************/ TI_STATUS assoc_smCapBuild(assoc_t *pCtx, TI_UINT16 *cap) { paramInfo_t param; TI_STATUS status; EDot11Mode mode; TI_UINT32 rateSuppMask, rateBasicMask; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; TI_UINT32 len = 0, ofdmIndex = 0; TI_BOOL b11nEnable, bWmeEnable; *cap = 0; /* Bss type */ param.paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM; status = ctrlData_getParam(pCtx->hCtrlData, ¶m); if (status == TI_OK) { if (param.content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE) { *cap |= DOT11_CAPS_ESS; } else { *cap |= DOT11_CAPS_IBSS; } } else { return TI_NOK; } /* Privacy */ param.paramType = RSN_ENCRYPTION_STATUS_PARAM; status = rsn_getParam(pCtx->hRsn, ¶m); if (status == TI_OK) { if (param.content.rsnEncryptionStatus != TWD_CIPHER_NONE) { *cap |= DOT11_CAPS_PRIVACY; } } else { return TI_NOK; } /* Preamble */ param.paramType = SITE_MGR_DESIRED_PREAMBLE_TYPE_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { if (param.content.siteMgrCurrentPreambleType == PREAMBLE_SHORT) *cap |= DOT11_CAPS_SHORT_PREAMBLE; } else { return TI_NOK; } /* Pbcc */ param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { if(param.content.siteMgrCurrentRateMask.supportedRateMask & DRV_RATE_MASK_22_PBCC) *cap |= DOT11_CAPS_PBCC; } else { return TI_NOK; } /* Checking if the station supports Spectrum Management (802.11h) */ param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain, ¶m); if (status == TI_OK ) { if( param.content.spectrumManagementEnabled) *cap |= DOT11_SPECTRUM_MANAGEMENT; } else { return TI_NOK; } /* slot time */ param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if(status == TI_OK) { mode = param.content.siteMgrDot11OperationalMode; } else return TI_NOK; if(mode == DOT11_G_MODE) { /* new requirement: the short slot time should be set only if the AP's modulation is OFDM (highest rate) */ /* get Rates */ param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask; rateSuppMask = param.content.siteMgrCurrentRateMask.supportedRateMask; } else { return TI_NOK; } /* convert the bit map to the rates array */ rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex); if(ofdmIndex < len) *cap |= DOT11_CAPS_SHORT_SLOT_TIME; /* param.paramType = SITE_MGR_CURRENT_MODULATION_TYPE_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if(param.content.siteMgrCurrentModulationType == DRV_MODULATION_OFDM) *cap |= DOT11_CAPS_SHORT_SLOT_TIME; */ } /* Primary Site support HT ? */ param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT; siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (param.content.bPrimarySiteHtSupport == TI_TRUE) { /* Immediate Block Ack subfield - (is WME on?) AND (is HT Enable?) */ /* verify 11n_Enable and Chip type */ StaCap_IsHtEnable (pCtx->hStaCap, &b11nEnable); /* verify that WME flag enable */ qosMngr_GetWmeEnableFlag (pCtx->hQosMngr, &bWmeEnable); if ((b11nEnable != TI_FALSE) && (bWmeEnable != TI_FALSE)) { *cap |= DOT11_CAPS_IMMEDIATE_BA; } } return TI_OK; } TI_STATUS assoc_smSSIDBuild(assoc_t *pCtx, TI_UINT8 *pSSID, TI_UINT32 *ssidLen) { paramInfo_t param; TI_STATUS status; dot11_SSID_t *pDot11Ssid; pDot11Ssid = (dot11_SSID_t*)pSSID; /* set SSID element id */ pDot11Ssid->hdr[0] = SSID_IE_ID; /* get SSID */ param.paramType = SME_DESIRED_SSID_ACT_PARAM; status = sme_GetParam(pCtx->hSme, ¶m); if (status != TI_OK) { return status; } /* check for ANY ssid */ if (param.content.smeDesiredSSID.len != 0) { pDot11Ssid->hdr[1] = param.content.smeDesiredSSID.len; os_memoryCopy(pCtx->hOs, (void *)pDot11Ssid->serviceSetId, (void *)param.content.smeDesiredSSID.str, param.content.smeDesiredSSID.len); } else { /* if ANY ssid is configured, use the current SSID */ param.paramType = SITE_MGR_CURRENT_SSID_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status != TI_OK) { return status; } pDot11Ssid->hdr[1] = param.content.siteMgrCurrentSSID.len; os_memoryCopy(pCtx->hOs, (void *)pDot11Ssid->serviceSetId, (void *)param.content.siteMgrCurrentSSID.str, param.content.siteMgrCurrentSSID.len); } *ssidLen = pDot11Ssid->hdr[1] + sizeof(dot11_eleHdr_t); return TI_OK; } TI_STATUS assoc_smRatesBuild(assoc_t *pCtx, TI_UINT8 *pRates, TI_UINT32 *ratesLen) { paramInfo_t param; TI_STATUS status; TI_UINT32 rateSuppMask, rateBasicMask; dot11_RATES_t *pDot11Rates; TI_UINT32 len = 0, ofdmIndex = 0; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; EDot11Mode mode; TI_UINT32 suppRatesLen, extSuppRatesLen, i; pDot11Rates = (dot11_RATES_t*)pRates; /* get Rates */ param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask; rateSuppMask = param.content.siteMgrCurrentRateMask.supportedRateMask; } else { return TI_NOK; } /* get operational mode */ param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if(status == TI_OK) mode = param.content.siteMgrDot11OperationalMode; else return TI_NOK; /* convert the bit map to the rates array */ /* remove MCS rates from Extended Supported Rates IE */ rateSuppMask &= ~(DRV_RATE_MASK_MCS_0_OFDM | DRV_RATE_MASK_MCS_1_OFDM | DRV_RATE_MASK_MCS_2_OFDM | DRV_RATE_MASK_MCS_3_OFDM | DRV_RATE_MASK_MCS_4_OFDM | DRV_RATE_MASK_MCS_5_OFDM | DRV_RATE_MASK_MCS_6_OFDM | DRV_RATE_MASK_MCS_7_OFDM ); rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex); if(mode != DOT11_G_MODE || ofdmIndex == len ) { pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID; pDot11Rates->hdr[1] = len; os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, len); *ratesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } else { /* fill in the supported rates */ pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID; pDot11Rates->hdr[1] = ofdmIndex; os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); /* fill in the extended supported rates */ pDot11Rates = (dot11_RATES_t*)(pRates + suppRatesLen); pDot11Rates->hdr[0] = EXT_SUPPORTED_RATES_IE_ID; pDot11Rates->hdr[1] = len - ofdmIndex; os_memoryCopy(NULL, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]); extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); *ratesLen = suppRatesLen + extSuppRatesLen; } TRACE3(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - bitmapSupp= 0x%X,bitMapBasic = 0x%X, len = %d\n", rateSuppMask,rateBasicMask,len); for(i=0; i<len; i++) { TRACE2(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - ratesBuf[%d] = 0x%X\n", i, ratesBuf[i]); } return TI_OK; } TI_STATUS assoc_powerCapabilityBuild(assoc_t *pCtx, TI_UINT8 *pPowerCapability, TI_UINT32 *powerCapabilityLen) { paramInfo_t param; TI_STATUS status; dot11_CAPABILITY_t *pDot11PowerCapability; pDot11PowerCapability = (dot11_CAPABILITY_t*)pPowerCapability; /* set Power Capability element id */ pDot11PowerCapability->hdr[0] = DOT11_CAPABILITY_ELE_ID; pDot11PowerCapability->hdr[1] = DOT11_CAPABILITY_ELE_LEN; /* get power capability */ param.paramType = REGULATORY_DOMAIN_POWER_CAPABILITY_PARAM; status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain, ¶m); if (status == TI_OK) { pDot11PowerCapability->minTxPower = param.content.powerCapability.minTxPower; pDot11PowerCapability->maxTxPower = param.content.powerCapability.maxTxPower; *powerCapabilityLen = pDot11PowerCapability->hdr[1] + sizeof(dot11_eleHdr_t); } else *powerCapabilityLen = 0; return TI_OK; } TI_STATUS assoc_smRequestBuild(assoc_t *pCtx, TI_UINT8* reqBuf, TI_UINT32* reqLen) { TI_STATUS status; TI_UINT8 *pRequest; TI_UINT32 len; paramInfo_t param; TTwdParamInfo tTwdParam; TI_UINT16 capabilities; ECipherSuite eCipherSuite = TWD_CIPHER_NONE; /* To be used for checking whether AP supports HT rates and TKIP */ pRequest = reqBuf; *reqLen = 0; /* insert capabilities */ status = assoc_smCapBuild(pCtx, &capabilities); if (status == TI_OK) { *(TI_UINT16*)pRequest = capabilities; } else return TI_NOK; pRequest += 2; *reqLen += 2; /* insert listen interval */ tTwdParam.paramType = TWD_LISTEN_INTERVAL_PARAM_ID; status = TWD_GetParam (pCtx->hTWD, &tTwdParam); if (status == TI_OK) { *(TI_UINT16*)pRequest = ENDIAN_HANDLE_WORD((TI_UINT16)tTwdParam.content.halCtrlListenInterval); } else { return TI_NOK; } pRequest += 2; *reqLen += 2; if (pCtx->reAssoc) { /* Insert currentAPAddress element only in reassoc request*/ param.paramType = SITE_MGR_PREV_SITE_BSSID_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { MAC_COPY (pRequest, param.content.siteMgrDesiredBSSID); 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]); pRequest += MAC_ADDR_LEN; *reqLen += MAC_ADDR_LEN; } else { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "ASSOC_SM: ASSOC_REQ - No prev AP \n"); return status; } } /* insert SSID element */ status = assoc_smSSIDBuild(pCtx, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; /* insert Rates element */ status = assoc_smRatesBuild(pCtx, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; /* Checking if the station supports Spectrum Management (802.11h) */ param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain,¶m); if( (status == TI_OK) && param.content.spectrumManagementEnabled) { /* Checking the selected AP capablities */ param.paramType = SITE_MGR_SITE_CAPABILITY_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr,¶m); if(status == TI_OK && ((param.content.siteMgrSiteCapability & DOT11_SPECTRUM_MANAGEMENT) != 0)) { /* insert Power capability element */ status = assoc_powerCapabilityBuild(pCtx, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; #if 0 /* insert Supported Channels element */ status = assoc_supportedChannelBuild(pCtx, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; #endif } } status = qosMngr_getQosCapabiltyInfeElement(pCtx->hQosMngr,pRequest,&len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; #ifdef XCC_MODULE_INCLUDED status = rsn_getXCCExtendedInfoElement(pCtx->hRsn, pRequest, (TI_UINT8*)&len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; if (pCtx->reAssoc) { /* insert CCKM information element only in reassoc */ status = XCCMngr_getCckmInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; } status = XCCMngr_getXCCVersionInfoElement(pCtx->hXCCMngr, pRequest, (TI_UINT8*)&len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; /* Insert Radio Mngt Capability IE */ status = measurementMgr_radioMngtCapabilityBuild(pCtx->hMeasurementMgr, pRequest, (TI_UINT8*)&len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; #endif /* Get Simple-Config state */ param.paramType = SITE_MGR_SIMPLE_CONFIG_MODE; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (param.content.siteMgrWSCMode.WSCMode == TIWLN_SIMPLE_CONFIG_OFF) { /* insert RSN information elements */ status = rsn_getInfoElement(pCtx->hRsn, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; } /* Privacy - Used later on HT */ param.paramType = RSN_ENCRYPTION_STATUS_PARAM; status = rsn_getParam(pCtx->hRsn, ¶m); if(status == TI_OK) { eCipherSuite = param.content.rsnEncryptionStatus; } /* Primary Site support HT ? */ param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT; siteMgr_getParam(pCtx->hSiteMgr, ¶m); /* Disallow TKIP with HT Rates: If this is the case - discard HT rates from Association Request */ if((TI_TRUE == param.content.bPrimarySiteHtSupport) && (eCipherSuite != TWD_CIPHER_TKIP)) { status = StaCap_GetHtCapabilitiesIe (pCtx->hStaCap, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; } status = qosMngr_assocReqBuild(pCtx->hQosMngr,pRequest,&len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; status = apConn_getVendorSpecificIE(pCtx->hApConn, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; if (*reqLen>=MAX_ASSOC_MSG_LENGTH) { return TI_NOK; } return TI_OK; } TI_STATUS assoc_saveAssocRespMessage(assoc_t *pAssocSm, TI_UINT8 *pAssocBuffer, TI_UINT32 length) { if ((pAssocSm==NULL) || (pAssocBuffer==NULL) || (length>=MAX_ASSOC_MSG_LENGTH)) { return TI_NOK; } os_memoryCopy(pAssocSm->hOs, pAssocSm->assocRespBuffer, pAssocBuffer, length); pAssocSm->assocRespLen = length; TRACE1(pAssocSm->hReport, REPORT_SEVERITY_INFORMATION, "assoc_saveAssocRespMessage: length=%ld \n",length); return TI_OK; } TI_STATUS assoc_saveAssocReqMessage(assoc_t *pAssocSm, TI_UINT8 *pAssocBuffer, TI_UINT32 length) { if ((pAssocSm==NULL) || (pAssocBuffer==NULL) || (length>=MAX_ASSOC_MSG_LENGTH)) { return TI_NOK; } os_memoryCopy(pAssocSm->hOs, pAssocSm->assocReqBuffer, pAssocBuffer, length); pAssocSm->assocReqLen = length; TRACE1(pAssocSm->hReport, REPORT_SEVERITY_INFORMATION, "assoc_saveAssocReqMessage: length=%ld \n",length); return TI_OK; } TI_STATUS assoc_sendDisAssoc(assoc_t *pAssocSm, mgmtStatus_e reason) { TI_STATUS status; disAssoc_t disAssoc; if (reason == STATUS_SUCCESSFUL) { disAssoc.reason = ENDIAN_HANDLE_WORD(STATUS_UNSPECIFIED); } else { disAssoc.reason = ENDIAN_HANDLE_WORD(reason); } status = mlmeBuilder_sendFrame(pAssocSm->hMlme, DIS_ASSOC, (TI_UINT8*)&disAssoc, sizeof(disAssoc_t), 0); return status; }