diff options
Diffstat (limited to 'wilink_6_1/stad/src/Sta_Management/assocSM.c')
-rw-r--r-- | wilink_6_1/stad/src/Sta_Management/assocSM.c | 1600 |
1 files changed, 1600 insertions, 0 deletions
diff --git a/wilink_6_1/stad/src/Sta_Management/assocSM.c b/wilink_6_1/stad/src/Sta_Management/assocSM.c new file mode 100644 index 0000000..53f583f --- /dev/null +++ b/wilink_6_1/stad/src/Sta_Management/assocSM.c @@ -0,0 +1,1600 @@ +/* + * assocSM.c + * + * Copyright(c) 1998 - 2009 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" + +/* 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); + + 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; +*/ + } + + /* 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; + + 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; + } + + /* Primary Site support HT ? */ + param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT; + siteMgr_getParam(pCtx->hSiteMgr, ¶m); + + if(TI_TRUE == param.content.bPrimarySiteHtSupport) + { + 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; +} + + |