1 /****************************************************************************
2 **+-----------------------------------------------------------------------+**
4 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
5 **| 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. |**
33 **+-----------------------------------------------------------------------+**
34 ****************************************************************************/
37 * \brief SME SM API implementation
39 * The state machine itself is implemented in the file smeSm.c.
51 #include "802_11Defs.h"
52 #include "regulatoryDomainApi.h"
53 #include "siteMgrApi.h"
55 #include "EvHandler.h"
56 #include "TI_IPC_Api.h"
59 #define WLAN_INTER_SCAN_DELTA 10
61 /* State machine definitions */
62 #define SME_INIT_BIT 1
64 #define TIMER_INIT_BIT 3
66 /* Local functions prototypes */
68 static void release_module(smeSm_t *pSmeSm, UINT32 initVec);
70 void smeSm_InterScanTimeoutCB(TI_HANDLE hSmeSm);
73 /* Interface functions Implementation */
75 /************************************************************************
77 ************************************************************************
78 DESCRIPTION: SME SM module creation function, called by the config mgr in creation phase
79 performs the following:
80 - Allocate the SME SM handle
81 - Create the SME state machine
83 INPUT: hOs - Handle to OS
88 RETURN: Handle to the SME SM module on success, NULL otherwise
90 ************************************************************************/
91 TI_HANDLE smeSm_create(TI_HANDLE hOs)
98 pSmeSm = os_memoryAlloc(hOs, sizeof(smeSm_t));
101 os_memoryZero(hOs, pSmeSm, sizeof(smeSm_t)); /* Dm: Fix */
103 initVec |= (1 << SME_INIT_BIT);
105 pSmeSm->pFsm = smeSm_smCreate(hOs);
106 if (pSmeSm->pFsm == NULL)
108 release_module(pSmeSm, initVec);
112 initVec |= (1 << SM_INIT_BIT);
116 pSmeSm->interScanTimeoutTimer = os_timerCreate(hOs, smeSm_InterScanTimeoutCB, pSmeSm);
117 if(pSmeSm->interScanTimeoutTimer == NULL)
119 release_module(pSmeSm, initVec);
120 WLAN_OS_REPORT(("FATAL ERROR: smeSm_create(): Error Creating smeSm - Aborting\n"));
123 initVec |= (1 << TIMER_INIT_BIT);
128 /************************************************************************
130 ************************************************************************
131 DESCRIPTION: SME SM module configuration function, called by the config mgr in configuration phase
132 performs the following:
133 - Reset & initiailzes local variables
134 - Init the handles to be used by the module
136 INPUT: hSmeSm - SME SM handle
137 List of handles to be used by the module
141 RETURN: OK on success, NOK otherwise
143 ************************************************************************/
144 TI_STATUS smeSm_config(TI_HANDLE hSmeSm,
151 TI_HANDLE hEvHandler,
156 TI_HANDLE hRegulatoryDomain,
157 smeInitParams_t* smeInitParams)
163 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
165 pSmeSm->state = SME_SM_STATE_IDLE;
166 pSmeSm->hConn = hConn;
167 pSmeSm->hScanCncn = hScanCncn;
168 pSmeSm->hSiteMgr = hSiteMgr;
169 pSmeSm->hHalCtrl = hHalCtrl;
170 pSmeSm->hReport = hReport;
172 pSmeSm->hEvHandler = hEvHandler;
174 pSmeSm->hApConn = hApConn;
175 pSmeSm->hCurrBss = hCurrBss;
176 pSmeSm->hPowerMgr = hPowerMgr;
177 pSmeSm->hRegulatoryDomain = hRegulatoryDomain;
179 /* interscan timeout values */
180 pSmeSm->scanEnabled = (scanEnabledOptions_e)smeInitParams->EnableFirstConnScan;
181 pSmeSm->interScanTimeoutMin = smeInitParams->InterScanIntervalMin;
182 pSmeSm->interScanTimeoutMax = smeInitParams->InterScanIntervalMax;
183 pSmeSm->interScanTimeoutDelta = smeInitParams->InterScanIntervalDelta;
184 pSmeSm->shutDownStatus = 0;
188 * Setting scan parameters for band 2.4Ghtz
190 os_memoryCopy(hOs, &(pSmeSm->scanParamsBG), &(smeInitParams->scanParamsBG), sizeof(sme_scan_Params_t));
191 /* The channel list is represented as char string terminate in zeros. */
194 ((index < MAX_NUMBER_OF_CHANNELS_PER_SCAN )&&(pSmeSm->scanParamsBG.channelsList[index] != 0));
197 pSmeSm->scanParamsBG.numOfChannels = index;
200 * Setting scan parameters for band 5.0Ghtz
202 os_memoryCopy(hOs, &(pSmeSm->scanParamsA), &(smeInitParams->scanParamsA), sizeof(sme_scan_Params_t));
205 ((index < MAX_NUMBER_OF_CHANNELS_PER_SCAN )&&(pSmeSm->scanParamsA.channelsList[index] != 0));
208 pSmeSm->scanParamsA.numOfChannels = index;
212 /* register to scan result callback */
213 scanConcentrator_registerScanResultCB( pSmeSm->hScanCncn, SCAN_SCC_DRIVER, smeSm_scanComplete, hSmeSm );
215 status = smeSm_smConfig(pSmeSm);
218 WLAN_REPORT_INIT(hReport, SME_SM_MODULE_LOG, (".....Sme state machine configuration Failure\n"));
220 WLAN_REPORT_INIT(hReport, SME_SM_MODULE_LOG, (".....Sme state machine configuration Success\n"));
225 /************************************************************************
226 * smeSm_getDriverShutdownStatus *
227 ************************************************************************
228 DESCRIPTION: Return shutdown status of driver.
230 INPUT: hSmeSm - SME SM handle.
234 RETURN: shutdown status of driver (SME/HAL)
236 ************************************************************************/
237 UINT8 smeSm_getDriverShutdownStatus (TI_HANDLE hSmeSm)
239 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
240 return (pSmeSm->shutDownStatus);
244 /************************************************************************
246 ************************************************************************
247 DESCRIPTION: SME SM module unload function, called by the config mgr in the unlod phase
248 performs the following:
249 - Free all memory allocated by the module
251 INPUT: hSmeSm - SME SM handle.
256 RETURN: OK on success, NOK otherwise
258 ************************************************************************/
259 TI_STATUS smeSm_unLoad(TI_HANDLE hSmeSm)
262 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
268 release_module(pSmeSm, initVec);
273 /***********************************************************************
275 ***********************************************************************
276 DESCRIPTION: Called by the configuration module in order to start the driver
277 Calls the SME SM with a start event
279 INPUT: hSmeSm - SME SM handle.
283 RETURN: OK on success, NOK otherwise
285 ************************************************************************/
286 TI_STATUS smeSm_start(TI_HANDLE hSmeSm)
288 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
290 pSmeSm->radioOn = TRUE;
291 pSmeSm->immediateShutdownRequired = FALSE;
293 return smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_START, pSmeSm);
298 /***********************************************************************
300 ***********************************************************************
301 DESCRIPTION: Called by the configuration module in order to start the driver
302 Calls the SME SM with a start event
304 INPUT: hSmeSm - SME SM handle.
308 RETURN: OK on success, NOK otherwise
310 ************************************************************************/
311 TI_STATUS smeSm_reselect(TI_HANDLE hSmeSm)
313 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
316 /* For new SSID reset interScanTimeout */
317 pSmeSm->interScanTimeout = pSmeSm->interScanTimeoutMin;
320 Junk SSID is used for disabling connection attempts, if it is
321 set the driver will be stopped at "inter scan" state.
324 param.paramType = SITE_MGR_DESIRED_SSID_PARAM;
325 siteMgr_getParam(pSmeSm->hSiteMgr, ¶m);
327 if (utils_isJunkSSID(¶m.content.siteMgrDesiredSSID))
329 pSmeSm->connectEnabled = FALSE;
331 WLAN_REPORT_INFORMATION(pSmeSm->hReport, SME_SM_MODULE_LOG,
332 ("Sme Set JUNK SSID\n"));
334 if( pSmeSm->state == SME_SM_STATE_SCANNING )
335 /* If in scanning stop the scan, the disconnect event will
336 be sent by the scan complete function. */
337 scanConcentrator_stopScan( pSmeSm->hScanCncn, SCAN_SCC_DRIVER );
339 smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_DISCONNECT, pSmeSm);
343 pSmeSm->connectEnabled = TRUE;
344 smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_RESELECT, pSmeSm);
351 /***********************************************************************
353 ***********************************************************************
354 DESCRIPTION: Called by the configuration module in order to stop the driver
355 Calls the SME SM with a stop event
357 INPUT: hSmeSm - SME SM handle.
361 RETURN: OK on success, NOK otherwise
363 ************************************************************************/
364 TI_STATUS smeSm_stop(TI_HANDLE hSmeSm)
366 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
368 pSmeSm->radioOn = FALSE;
369 pSmeSm->immediateShutdownRequired = FALSE;
371 return smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_STOP, pSmeSm);
374 /***********************************************************************
375 * smeSm_stopAndShutdown
376 ***********************************************************************
377 DESCRIPTION: Called by the configuration module in order to stop the driver
378 Calls the SME SM with a stop event
380 INPUT: hSmeSm - SME SM handle.
384 RETURN: OK on success, NOK otherwise
386 ************************************************************************/
387 void smeSm_stopAndShutdown(TI_HANDLE hSmeSm)
389 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
391 pSmeSm->radioOn = FALSE;
392 pSmeSm->immediateShutdownRequired = TRUE;
394 smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_STOP, pSmeSm);
397 /***********************************************************************
399 ***********************************************************************
400 DESCRIPTION: Called by the site manager When scan is completed
401 Calls the SME SM with a scan complete event
403 INPUT: hSmeSm - SME SM handle.
407 RETURN: OK on success, NOK otherwise
409 ************************************************************************/
410 void smeSm_scanComplete( TI_HANDLE hSmeSm, scan_cncnResultStatus_e status,
411 scan_frameInfo_t *frameInfo, UINT16 SPSStatus )
413 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
415 /* if this call is due to a scan result received, simply store it in the site mngr */
416 if ( SCAN_CRS_RECEIVED_FRAME == status )
418 siteMgr_updateSite( pSmeSm->hSiteMgr, frameInfo->bssId, frameInfo->parsedIEs, frameInfo->channel, frameInfo->band, FALSE);
419 if ( BEACON == frameInfo->parsedIEs->subType )
421 siteMgr_saveBeaconBuffer( pSmeSm->hSiteMgr, frameInfo->bssId, frameInfo->buffer, frameInfo->bufferLength );
425 siteMgr_saveProbeRespBuffer( pSmeSm->hSiteMgr, frameInfo->bssId, frameInfo->buffer, frameInfo->bufferLength );
428 /* update statistics - count one more result that was received */
429 pSmeSm->smeStats.currentNumberOfScanResults++;
435 /* update statistics - update scan results histogram */
436 if ( SCAN_RESULT_HISTOGRAM_SIZE <= pSmeSm->smeStats.currentNumberOfScanResults )
438 pSmeSm->smeStats.scanResulCountHistogram[ SCAN_RESULT_HISTOGRAM_SIZE -1 ]++;
442 pSmeSm->smeStats.scanResulCountHistogram[ pSmeSm->smeStats.currentNumberOfScanResults ]++;
444 pSmeSm->smeStats.currentNumberOfScanResults = 0;
447 WLAN_REPORT_INFORMATION(pSmeSm->hReport, SME_SM_MODULE_LOG,
448 ("smeSm_scanComplete\n"));
450 siteMgr_removeNotReceivedSites(pSmeSm->hSiteMgr);
452 if ( pSmeSm->connectEnabled )
454 /* check for rescan and perform scan when it is on */
455 if ( TRUE == pSmeSm->reScanFlag )
457 WLAN_REPORT_INFORMATION( pSmeSm->hReport, SME_SM_MODULE_LOG,
458 ("SME_SM: doing additional scan due to reScanFlag = ON\n") );
459 pSmeSm->reScanFlag = FALSE;
460 sme_startScan(pSmeSm);
462 /* check for dual band rescan */
463 else if ( TRUE == pSmeSm->dualBandReScanFlag )
465 WLAN_REPORT_INFORMATION( pSmeSm->hReport, SME_SM_MODULE_LOG,
466 ("SME_SM: doing additional scan due to dualBandReScanFlag = ON\n") );
467 sme_startScan(pSmeSm);
471 smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_SCAN_COMPLETE, pSmeSm);
476 /* If connection is disabled then send disconnect event, the SM will
477 * move into inter scan state
479 pSmeSm->reScanFlag = FALSE; /* (Just to make sure) */
480 pSmeSm->dualBandReScanFlag = FALSE;
481 smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_DISCONNECT, pSmeSm);
486 /***********************************************************************
487 * smeSm_reportConnStatus
488 ***********************************************************************
489 DESCRIPTION: Called by the connection module when connection status changes
490 Calls the SME SM with a connection suceess or connection failure based on the status
492 INPUT: hSmeSm - SME SM handle.
493 statusType - Connection status
494 uStatusCode - extra information to statusType (usually status code of the packet)
498 RETURN: OK on success, NOK otherwise
500 ************************************************************************/
501 TI_STATUS smeSm_reportConnStatus(TI_HANDLE hSmeSm, mgmtStatus_e statusType, UINT32 uStatusCode)
503 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
505 WLAN_REPORT_INFORMATION(pSmeSm->hReport, SME_SM_MODULE_LOG,
506 ("%s statusType = %d, uStatusCode = %d \n",__FUNCTION__, statusType, uStatusCode));
510 case STATUS_SUCCESSFUL:
511 return smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_CONN_SUCCESS, pSmeSm);
514 * The next section handles connection failures, all cases are sending same event to SM.
516 case STATUS_AUTH_REJECT:
517 case STATUS_ASSOC_REJECT:
518 case STATUS_SECURITY_FAILURE:
519 case STATUS_AP_DEAUTHENTICATE:
520 case STATUS_AP_DISASSOCIATE:
521 case STATUS_ROAMING_TRIGGER:
522 pSmeSm->DisAssoc.mgmtStatus = statusType;
523 pSmeSm->DisAssoc.uStatusCode = uStatusCode;
524 /* Note that in case of unspecified status we won't update the status. This is done since this function could be called twice */
525 /* for example: apConn called this function and than SME called conn_stop and this function is called again */
526 case STATUS_UNSPECIFIED:
528 return smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_CONN_FAILURE, pSmeSm);
531 WLAN_REPORT_WARNING(pSmeSm->hReport, SME_SM_MODULE_LOG,
532 ("%s unknown statusType = %d\n",__FUNCTION__, statusType));
540 /***********************************************************************
541 * smeSm_reportSelectStatus
542 ***********************************************************************
543 DESCRIPTION: Called by the selection function
544 Calls the SME SM with a selection suceess or selection failure based on the status
546 INPUT: hSmeSm - SME SM handle.
547 status - selection status
551 RETURN: OK on success, NOK otherwise
553 ************************************************************************/
554 TI_STATUS smeSm_reportSelectStatus(TI_HANDLE hSmeSm,
557 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
559 if (status == SELECT_STATUS_SUCCESS)
560 return smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_SELECT_SUCCESS, pSmeSm);
562 return smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_SELECT_FAILURE, pSmeSm);
566 /***********************************************************************
568 ***********************************************************************
569 DESCRIPTION: Timer callback, on expiration of which, scan started
571 INPUT: hSmeSm - SME SM handle.
575 RETURN: OK on success, NOK otherwise
577 ************************************************************************/
578 void smeSm_InterScanTimeoutCB(TI_HANDLE hSmeSm)
580 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
582 if ( pSmeSm->connectEnabled )
584 pSmeSm->interScanTimeout += pSmeSm->interScanTimeoutDelta;
586 if( pSmeSm->interScanTimeout > pSmeSm->interScanTimeoutMax )
587 pSmeSm->interScanTimeout = pSmeSm->interScanTimeoutMax;
589 smeSm_SMEvent(&pSmeSm->state, SME_SM_EVENT_RESELECT, pSmeSm);
594 /***********************************************************************
596 ***********************************************************************
597 DESCRIPTION: Called by the un load function
598 Go over the vector, for each bit that is set, release the corresponding module.
600 INPUT: hConn - SME SM handle.
601 pSmeSm - Vector that contains a bit set for each module thah had been initiualized
605 RETURN: OK on success, NOK otherwise
607 ************************************************************************/
608 static void release_module(smeSm_t *pSmeSm, UINT32 initVec)
611 if (initVec & (1 << SM_INIT_BIT))
612 smeSm_smUnLoad(pSmeSm->hOs, pSmeSm->pFsm);
614 if (initVec & (1 << TIMER_INIT_BIT))
616 os_timerStop(pSmeSm->hOs, pSmeSm->interScanTimeoutTimer);
617 utils_nullTimerDestroy(pSmeSm->hOs, pSmeSm->interScanTimeoutTimer);
620 if (initVec & (1 << SME_INIT_BIT))
621 utils_nullMemoryFree(pSmeSm->hOs, pSmeSm, sizeof(smeSm_t));
627 /***********************************************************************
629 ***********************************************************************
630 DESCRIPTION: SME SM set param function, called by the following:
631 - config mgr in order to set a parameter from the OS abstraction layer.
632 - Form inside the driver
634 INPUT: hSmeSm - SME SM handle.
635 pParam - Pointer to the parameter
639 RETURN: OK on success, NOK otherwise
641 ************************************************************************/
642 TI_STATUS smeSm_setParam(TI_HANDLE hSmeSm,
645 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
647 switch(pParam->paramType)
649 case SME_SCAN_ENABLED_PARAM:
650 if (pSmeSm->scanEnabled != pParam->content.smeSMScanEnabled)
652 if ((pParam->content.smeSMScanEnabled == SCAN_ENABLED) &&
653 (pSmeSm->scanEnabled == SKIP_NEXT_SCAN))
655 /* Requested to st scanEnable to TRUE;
656 if we are about to skip the nextcoming scan, ignore the request */
659 if ((pParam->content.smeSMScanEnabled == SKIP_NEXT_SCAN) &&
660 (pSmeSm->scanEnabled == SCAN_DISABLED))
662 /* Requested to st scanEnable to SKIP_NEXT_SCAN
663 while it is currently set to FALSE - error, ignore the request */
664 WLAN_REPORT_ERROR( pSmeSm->hReport, SME_SM_MODULE_LOG,
665 ("Set param, error changing scan enabled param from %d to %d\n",
666 pSmeSm->scanEnabled, pParam->content.smeSMScanEnabled));
669 pSmeSm->scanEnabled = pParam->content.smeSMScanEnabled;
674 WLAN_REPORT_ERROR( pSmeSm->hReport, SME_SM_MODULE_LOG,
675 ("Set param, Params is not supported, %d\n\n", pParam->paramType));
676 return PARAM_NOT_SUPPORTED;
682 /***********************************************************************
684 ***********************************************************************
685 DESCRIPTION: SME SM get param function, called by the following:
686 - config mgr in order to get a parameter from the OS abstraction layer.
687 - Fomr inside the dirver
689 INPUT: hSmeSm - SME SM handle.
690 pParam - Pointer to the parameter
694 RETURN: OK on success, NOK otherwise
696 ************************************************************************/
697 TI_STATUS smeSm_getParam(TI_HANDLE hSmeSm,
700 smeSm_t *pSmeSm = (smeSm_t *)hSmeSm;
702 switch(pParam->paramType)
704 case SITE_MGR_CONNECTION_STATUS_PARAM:
705 switch (pSmeSm->state)
707 case SME_SM_STATE_IDLE:
708 case SME_SM_STATE_INTER_SCAN:
709 pParam->content.smeSmConnectionStatus = eDot11Idle;
711 case SME_SM_STATE_SCANNING:
712 pParam->content.smeSmConnectionStatus = eDot11Scaning;
714 case SME_SM_STATE_CONNECTING:
715 pParam->content.smeSmConnectionStatus = eDot11Connecting;
718 pParam->content.smeSmConnectionStatus = eDot11Associated;
723 case SME_SM_STATE_PARAM:
724 pParam->content.smeSmState = pSmeSm->state;
727 case SME_SCAN_ENABLED_PARAM:
728 pParam->content.smeSMScanEnabled = pSmeSm->scanEnabled;
732 WLAN_REPORT_ERROR(pSmeSm->hReport, SME_SM_MODULE_LOG, ("Get param, Params is not supported, %d\n\n", pParam->paramType));
733 return PARAM_NOT_SUPPORTED;