4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
35 * \brief 802.11 MLME SM source
41 /***************************************************************************/
43 /* MODULE: mlmeSM.c */
44 /* PURPOSE: 802.11 MLME SM source */
46 /***************************************************************************/
48 #define __FILE_ID__ FILE_ID_69
56 #include "mlmeBuilder.h"
58 #include "openAuthSm.h"
59 #include "sharedKeyAuthSm.h"
61 #include "DrvMainModules.h"
65 #include "siteMgrApi.h"
75 /* External data definitions */
77 /* External functions definitions */
79 /* Global variables */
81 /* Local function prototypes */
82 static void mlme_stopAssocAndAuth(mlme_t *pMlme);
88 * mlme_Create - allocate memory for MLME SM
92 * Allocate memory for MLME SM. \n
93 * Allocates memory for MLME context. \n
94 * Allocates memory for MLME timer. \n
95 * Allocates memory for MLME SM matrix. \n
99 * I - pOs - OS context \n
103 * TI_OK if successful, TI_NOK otherwise.
105 * \sa rsn_mainSecSmKeysOnlyStop()
107 TI_HANDLE mlme_create(TI_HANDLE hOs)
112 /* allocate MLME context memory */
113 pHandle = (mlme_t*)os_memoryAlloc(hOs, sizeof(mlme_t));
119 /* zero all MLME context */
120 os_memoryZero(hOs, pHandle, sizeof(mlme_t));
124 /* allocate memory for MLME state machine */
125 status = fsm_Create(hOs, &pHandle->pMlmeSm, MLME_SM_NUM_STATES, MLME_SM_NUM_EVENTS);
128 os_memoryFree(hOs, pHandle, sizeof(mlme_t));
138 * mlme_Unload - unload MLME SM from memory
142 * Unload MLME SM from memory
146 * I - hMlme - MLME SM context \n
150 * TI_OK if successful, TI_NOK otherwise.
152 * \sa rsn_mainSecSmKeysOnlyStop()
154 TI_STATUS mlme_unload(TI_HANDLE hMlme)
159 pHandle = (mlme_t*)hMlme;
161 status = fsm_Unload(pHandle->hOs, pHandle->pMlmeSm);
164 /* report failure but don't stop... */
167 os_memoryFree(pHandle->hOs, hMlme, sizeof(mlme_t));
174 * mlme_smConfig - configure a new MLME SM
178 * Configure a new MLME SM and other modules handles.
184 * \sa mlme_Create, mlme_Unload
186 void mlme_init (TStadHandlesList *pStadHandles)
188 mlme_t *pHandle = (mlme_t *)(pStadHandles->hMlmeSm);
190 /** Main 802.1X State Machine matrix */
191 fsm_actionCell_t mlme_smMatrix[MLME_SM_NUM_STATES][MLME_SM_NUM_EVENTS] =
193 /* next state and actions for IDLE state */
194 {{MLME_SM_STATE_AUTH_WAIT, (fsm_Action_t)mlme_smStartIdle}, /* MLME_SM_EVENT_START */
195 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smNOP}, /* MLME_SM_EVENT_STOP */
196 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_AUTH_SUCCESS */
197 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_AUTH_FAIL */
198 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_ASSOC_SUCCESS */
199 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smActionUnexpected} /* MLME_SM_EVENT_ASSOC_FAIL */
201 /* next state and actions for AUTH_WAIT state */
202 {{MLME_SM_STATE_AUTH_WAIT, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_START */
203 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smNOP}, /* MLME_SM_EVENT_STOP */
204 {MLME_SM_STATE_ASSOC_WAIT, (fsm_Action_t)mlme_smAuthSuccessAuthWait}, /* MLME_SM_EVENT_AUTH_SUCCESS */
205 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smAuthFailAuthWait}, /* MLME_SM_EVENT_AUTH_FAIL */
206 {MLME_SM_STATE_AUTH_WAIT, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_ASSOC_SUCCESS */
207 {MLME_SM_STATE_AUTH_WAIT, (fsm_Action_t)mlme_smActionUnexpected} /* MLME_SM_EVENT_ASSOC_FAIL */
209 /* next state and actions for ASSOC_WAIT state */
210 {{MLME_SM_STATE_ASSOC_WAIT, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_START */
211 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smStopAssocWait}, /* MLME_SM_EVENT_STOP */
212 {MLME_SM_STATE_ASSOC_WAIT, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_AUTH_SUCCESS */
213 {MLME_SM_STATE_ASSOC_WAIT, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_AUTH_FAIL */
214 {MLME_SM_STATE_ASSOC, (fsm_Action_t)mlme_smAssocSuccessAssocWait}, /* MLME_SM_EVENT_ASSOC_SUCCESS */
215 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smAssocFailAssocWait} /* MLME_SM_EVENT_ASSOC_FAIL */
217 /* next state and actions for ASSOC state */
218 {{MLME_SM_STATE_ASSOC, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_START */
219 {MLME_SM_STATE_IDLE, (fsm_Action_t)mlme_smStopAssoc}, /* MLME_SM_EVENT_STOP */
220 {MLME_SM_STATE_ASSOC, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_AUTH_SUCCESS */
221 {MLME_SM_STATE_ASSOC, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_AUTH_FAIL */
222 {MLME_SM_STATE_ASSOC, (fsm_Action_t)mlme_smActionUnexpected}, /* MLME_SM_EVENT_ASSOC_SUCCESS */
223 {MLME_SM_STATE_ASSOC, (fsm_Action_t)mlme_smActionUnexpected} /* MLME_SM_EVENT_ASSOC_FAIL */
227 fsm_Config(pHandle->pMlmeSm, &mlme_smMatrix[0][0], MLME_SM_NUM_STATES, MLME_SM_NUM_EVENTS, mlme_smEvent, pStadHandles->hOs);
229 pHandle->currentState = MLME_SM_STATE_IDLE;
230 pHandle->legacyAuthType = AUTH_LEGACY_NONE;
231 pHandle->reAssoc = TI_FALSE;
232 pHandle->disConnType = DISCONNECT_IMMEDIATE;
233 pHandle->disConnReason = STATUS_UNSPECIFIED;
235 pHandle->hAssoc = pStadHandles->hAssoc;
236 pHandle->hAuth = pStadHandles->hAuth;
237 pHandle->hSiteMgr = pStadHandles->hSiteMgr;
238 pHandle->hCtrlData = pStadHandles->hCtrlData;
239 pHandle->hTxMgmtQ = pStadHandles->hTxMgmtQ;
240 pHandle->hMeasurementMgr = pStadHandles->hMeasurementMgr;
241 pHandle->hSwitchChannel = pStadHandles->hSwitchChannel;
242 pHandle->hRegulatoryDomain = pStadHandles->hRegulatoryDomain;
243 pHandle->hReport = pStadHandles->hReport;
244 pHandle->hOs = pStadHandles->hOs;
245 pHandle->hConn = pStadHandles->hConn;
246 pHandle->hCurrBss = pStadHandles->hCurrBss;
247 pHandle->hApConn = pStadHandles->hAPConnection;
248 pHandle->hScanCncn = pStadHandles->hScanCncn;
249 pHandle->hQosMngr = pStadHandles->hQosMngr;
250 pHandle->hTWD = pStadHandles->hTWD;
251 pHandle->hTxCtrl = pStadHandles->hTxCtrl;
256 pHandle->debug_lastProbeRspTSFTime = 0;
257 pHandle->debug_lastDtimBcnTSFTime = 0;
258 pHandle->debug_lastBeaconTSFTime = 0;
259 pHandle->debug_isFunctionFirstTime = TI_TRUE;
260 pHandle->BeaconsCounterPS = 0;
263 void mlme_SetDefaults (TI_HANDLE hMlmeSm, TMlmeInitParams *pMlmeInitParams)
265 mlme_t *pMlme = (mlme_t *)(hMlmeSm);
267 /* set default values */
268 pMlme->bParseBeaconWSC = pMlmeInitParams->parseWSCInBeacons;
271 TI_STATUS mlme_setParam(TI_HANDLE hMlmeSm,
274 mlme_t *pMlmeSm = (mlme_t *)hMlmeSm;
276 switch(pParam->paramType)
278 case MLME_LEGACY_TYPE_PARAM:
280 switch (pParam->content.mlmeLegacyAuthType)
282 case AUTH_LEGACY_RESERVED1:
283 case AUTH_LEGACY_OPEN_SYSTEM:
284 /* First configure the MLME with the new legacy authentication type */
285 pMlmeSm->legacyAuthType = pParam->content.mlmeLegacyAuthType;
286 /* Now configure the authentication module. */
287 pParam->paramType = AUTH_LEGACY_TYPE_PARAM;
288 return auth_setParam(pMlmeSm->hAuth, pParam);
290 case AUTH_LEGACY_SHARED_KEY:
291 /* First configure the MLME with the new legacy authentication type */
292 pMlmeSm->legacyAuthType = AUTH_LEGACY_SHARED_KEY;
293 /* Now configure the authentication module. */
294 pParam->paramType = AUTH_LEGACY_TYPE_PARAM;
295 return auth_setParam(pMlmeSm->hAuth, pParam);
297 case AUTH_LEGACY_AUTO_SWITCH:
298 /* First configure the MLME with the new legacy authentication type */
299 pMlmeSm->legacyAuthType = AUTH_LEGACY_AUTO_SWITCH;
300 /* Now configure the authentication module,
301 Auto switch mode means start always with shared key, if fail move to open system. */
302 pParam->paramType = AUTH_LEGACY_TYPE_PARAM;
303 pParam->content.authLegacyAuthType = AUTH_LEGACY_SHARED_KEY;
304 return auth_setParam(pMlmeSm->hAuth, pParam);
307 TRACE1(pMlmeSm->hReport, REPORT_SEVERITY_ERROR, "Set param, Params is not supported, 0x%x\n\n", pParam->content.mlmeLegacyAuthType);
308 return PARAM_VALUE_NOT_VALID;
310 /* break; - unreachable */
312 case MLME_RE_ASSOC_PARAM:
313 pMlmeSm->reAssoc = pParam->content.mlmeReAssoc;
317 TRACE1(pMlmeSm->hReport, REPORT_SEVERITY_ERROR, "Set param, Params is not supported, 0x%x\n\n", pParam->paramType);
318 return PARAM_NOT_SUPPORTED;
324 TI_STATUS mlme_getParam(TI_HANDLE hMlmeSm,
327 mlme_t *pMlmeSm = (mlme_t *)hMlmeSm;
329 switch(pParam->paramType)
331 case MLME_LEGACY_TYPE_PARAM:
332 pParam->content.mlmeLegacyAuthType = pMlmeSm->legacyAuthType;
335 case MLME_CAPABILITY_PARAM:
336 pParam->content.mlmeLegacyAuthType = pMlmeSm->legacyAuthType;
337 assoc_smCapBuild(pMlmeSm->hAssoc, &(pParam->content.siteMgrSiteCapability));
340 case MLME_BEACON_RECV:
341 pParam->content.siteMgrTiWlanCounters.BeaconsRecv = pMlmeSm->BeaconsCounterPS;
345 TRACE1(pMlmeSm->hReport, REPORT_SEVERITY_ERROR, "Get param, Params is not supported, %d\n\n", pParam->content.mlmeLegacyAuthType);
346 return PARAM_NOT_SUPPORTED;
354 * mlme_Start - Start event for the MLME SM
358 * Start event for the MLME SM
362 * I - hMlme - MLME SM context \n
366 * TI_OK if successful, TI_NOK otherwise.
368 * \sa mlme_Stop, mlme_Recv
370 TI_STATUS mlme_start(TI_HANDLE hMlme)
373 mlme_t *pHandle = (mlme_t*)hMlme;
380 if (pHandle->legacyAuthType == AUTH_LEGACY_NONE)
382 TRACE0(pHandle->hReport, REPORT_SEVERITY_ERROR, "mlme_start: pHandle->legacyAuthType == AUTH_LEGACY_NONE\n");
386 status = mlme_smEvent(&pHandle->currentState, MLME_SM_EVENT_START, pHandle);
393 * mlme_Stop - Stop event for the MLME SM
397 * Stop event for the MLME SM
401 * I - hMlme - MLME SM context \n
405 * TI_OK if successful, TI_NOK otherwise.
407 * \sa mlme_Start, mlme_Recv
409 TI_STATUS mlme_stop(TI_HANDLE hMlme, DisconnectType_e disConnType, mgmtStatus_e reason)
414 pHandle = (mlme_t*)hMlme;
416 if (pHandle->legacyAuthType == AUTH_LEGACY_NONE)
419 pHandle->disConnType = disConnType;
420 pHandle->disConnReason = reason;
422 status = mlme_smEvent(&pHandle->currentState, MLME_SM_EVENT_STOP, pHandle);
430 * mlme_reportAuthStatus - Set a specific parameter to the MLME SM
434 * Set a specific parameter to the MLME SM.
438 * I - hMlme - MLME SM context \n
439 * I/O - pParam - Parameter \n
443 * TI_OK if successful, TI_NOK otherwise.
445 * \sa mlme_Start, mlme_Stop
447 TI_STATUS mlme_reportAuthStatus(TI_HANDLE hMlme, TI_UINT16 status)
453 pHandle = (mlme_t*)hMlme;
458 if (pHandle->legacyAuthType == AUTH_LEGACY_NONE)
461 pHandle->mlmeData.uStatusCode = status;
463 /* If status is successful */
466 /* Mark a successful status - used for conn.c */
467 pHandle->mlmeData.mgmtStatus = STATUS_SUCCESSFUL;
468 fStatus = mlme_smEvent(&pHandle->currentState, MLME_SM_EVENT_AUTH_SUCCESS, pHandle);
472 /* Now, if the MLME legacy auth type is AUTO_SWITCH, and the Auth legacy auth type is shared key,
473 we configure the auth SM to open system, otherwise, this is really an authentication failure. */
474 param.paramType = AUTH_LEGACY_TYPE_PARAM;
475 auth_getParam(pHandle->hAuth, ¶m);
477 if ((pHandle->legacyAuthType == AUTH_LEGACY_AUTO_SWITCH) && (param.content.authLegacyAuthType == AUTH_LEGACY_SHARED_KEY))
479 param.content.authLegacyAuthType = AUTH_LEGACY_OPEN_SYSTEM;
480 fStatus = auth_setParam(pHandle->hAuth, ¶m);
481 fStatus = auth_start(pHandle->hAuth);
486 pHandle->mlmeData.mgmtStatus = STATUS_AUTH_REJECT;
487 fStatus = mlme_smEvent(&pHandle->currentState, MLME_SM_EVENT_AUTH_FAIL, pHandle);
497 * mlme_reportAssocStatus - Set a specific parameter to the MLME SM
501 * Set a specific parameter to the MLME SM.
505 * I - hMlme - MLME SM context \n
506 * I/O - pParam - Parameter \n
510 * TI_OK if successful, TI_NOK otherwise.
512 * \sa mlme_Start, mlme_Stop
514 TI_STATUS mlme_reportAssocStatus(TI_HANDLE hMlme, TI_UINT16 status)
519 pHandle = (mlme_t*)hMlme;
524 if (pHandle->legacyAuthType == AUTH_LEGACY_NONE)
527 pHandle->mlmeData.uStatusCode = status;
529 /* If status is successful */
532 pHandle->mlmeData.mgmtStatus = STATUS_SUCCESSFUL;
533 fStatus = mlme_smEvent(&pHandle->currentState, MLME_SM_EVENT_ASSOC_SUCCESS, pHandle);
536 pHandle->mlmeData.mgmtStatus = STATUS_ASSOC_REJECT;
537 fStatus = mlme_smEvent(&pHandle->currentState, MLME_SM_EVENT_ASSOC_FAIL, pHandle);
546 * mlme_SetParam - Set a specific parameter to the MLME SM
550 * Set a specific parameter to the MLME SM.
554 * I - hMlme - MLME SM context \n
555 * I/O - pParam - Parameter \n
559 * TI_OK if successful, TI_NOK otherwise.
561 * \sa mlme_Start, mlme_Stop
563 TI_STATUS mlme_smEvent(TI_UINT8 *currentState, TI_UINT8 event, TI_HANDLE hMlme)
565 mlme_t *pMlme = (mlme_t *)hMlme;
569 status = fsm_GetNextState(pMlme->pMlmeSm, *currentState, event, &nextState);
572 TRACE0(pMlme->hReport, REPORT_SEVERITY_ERROR, "MLME_SM: ERROR - failed getting next state \n");
577 TRACE3( pMlme->hReport, REPORT_SEVERITY_INFORMATION, "mlme_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currentState, event, nextState);
579 status = fsm_Event(pMlme->pMlmeSm, currentState, event, (void *)pMlme);
584 /* state machine functions */
586 TI_STATUS mlme_smStartIdle(mlme_t *pMlme)
590 status = auth_start(pMlme->hAuth);
595 TI_STATUS mlme_smClass3Idle(mlme_t *pMlme)
602 TI_STATUS mlme_smAuthSuccessAuthWait(mlme_t *pMlme)
608 status = reassoc_start(pMlme->hAssoc);
612 status = assoc_start(pMlme->hAssoc);
618 TI_STATUS mlme_smAuthFailAuthWait(mlme_t *pMlme)
622 status = mlme_smReportStatus(pMlme);
627 TI_STATUS mlme_smStopAssocWait(mlme_t *pMlme)
629 mlme_stopAssocAndAuth(pMlme);
633 TI_STATUS mlme_smAssocSuccessAssocWait(mlme_t *pMlme)
637 status = mlme_smReportStatus(pMlme);
642 TI_STATUS mlme_smAssocFailAssocWait(mlme_t *pMlme)
646 status = mlme_smReportStatus(pMlme);
652 TI_STATUS mlme_smStopAssoc(mlme_t *pMlme)
654 mlme_stopAssocAndAuth(pMlme);
660 TI_STATUS mlme_smNOP(mlme_t *pMlme)
665 TI_STATUS mlme_smActionUnexpected(mlme_t *pMlme)
670 /* local functions */
672 TI_STATUS mlme_smReportStatus(mlme_t *pMlme)
681 status = conn_reportMlmeStatus(pMlme->hConn, pMlme->mlmeData.mgmtStatus, pMlme->mlmeData.uStatusCode);
686 static void mlme_stopAssocAndAuth(mlme_t *pMlme)
690 TI_BOOL sendDisAssoc;
692 /* Don't send deauth/disassoc, FW will do it on disconnect command */
693 sendDeAuth = TI_FALSE;
694 sendDisAssoc = TI_FALSE;
696 TRACE0(pMlme->hReport, REPORT_SEVERITY_INFORMATION, "mlme_stopAssocAndAuth: Auth/assoc stop without sending deauth/disassoc\n");
698 assoc_setDisAssocFlag(pMlme->hAssoc, sendDisAssoc);
699 assoc_stop(pMlme->hAssoc);
701 auth_stop(pMlme->hAuth, sendDeAuth, pMlme->disConnReason );
703 /*****************************************************************************
705 ** MLME messages builder/Parser
707 *****************************************************************************/