Exemplo n.º 1
0
/**
*
* roamingMngr_smRoamTrigger
*
* \b Description:
*
* This procedure is called when an Roaming event occurs: BSS LOSS, LOW Quality etc.
 * Performs the following:
 * - If Roaming is disabled, ignore.
 * - Indicate Driver that Roaming process is starting
 * - Get the BSS list from the Scan Manager.
 * - If the list is not empty, start SELECTION
 * - If the list is empty, start SCANNING. The type of scan is decided
 *      according to the Neigbor APs existence.
*
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
*
*/
static void roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;
    roamingMngr_smEvents    roamingEvent;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smRoamTrigger, enableDisable = %d\n",pRoamingMngr->roamingMngrConfig.enableDisable);

    if (!pRoamingMngr->roamingMngrConfig.enableDisable) {
        /* Ignore any other Roaming event when Roaming is disabled */
        TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_smRoamTrigger, when Roaming is disabled\n");
        return;
    }
    /* Indicate the driver that Roaming process is starting */
    apConn_prepareToRoaming(pRoamingMngr->hAPConnection, pRoamingMngr->roamingTrigger);

    /* Get the current BSSIDs from ScanMngr */
    pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
    if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0)) {  /* No need to SCAN, start SELECTING */
        roamingEvent = ROAMING_EVENT_SELECT;
    } else {  /* check if list of APs exists in order to verify which scan to start */
        roamingEvent = ROAMING_EVENT_SCAN;
        if (pRoamingMngr->neighborApsExist) {  /* Scan only Neighbor APs */
            pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN;
        } else {  /* Scan all channels */
            pRoamingMngr->scanType = ROAMING_FULL_SCAN;
        }
    }
    TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smRoamTrigger, scanType = %d\n", pRoamingMngr->scanType);

    roamingMngr_smEvent(roamingEvent, pRoamingMngr);
}
TI_STATUS roamingMngr_connect(TI_HANDLE hRoamingMngr, TargetAp_t* pTargetAp)
{
	roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
	bssList_t *bssList;
	int i=0;

	TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_connect(),"
	       "transitionMethod = %d,"
	       "requestType = %d,"
	       " \n", pTargetAp->transitionMethod,pTargetAp->connRequest.requestType) ;


	TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connect(),"
	       " AP to roam BSSID: "
	       "%02x-%02x-%02x-%02x-%02x-%02x "
	       "\n", pTargetAp->newAP.BSSID[0],pTargetAp->newAP.BSSID[1],pTargetAp->newAP.BSSID[2],pTargetAp->newAP.BSSID[3],pTargetAp->newAP.BSSID[4],pTargetAp->newAP.BSSID[5]);


	/* Search for target AP in the scan manager results table, to get its beacon/ProbResponse buffer  */
	bssList = scanMngr_getBSSList(((roamingMngr_t*)hRoamingMngr)->hScanMngr);
	for (i=0; i< bssList->numOfEntries ; i++) {
		if (MAC_EQUAL(bssList->BSSList[i].BSSID, pTargetAp->newAP.BSSID)) {
			pTargetAp->newAP.pBuffer = bssList->BSSList[i].pBuffer;
			pTargetAp->newAP.bufferLength = bssList->BSSList[i].bufferLength;
			os_memoryCopy(pRoamingMngr->hOs, &(pRoamingMngr->targetAP), (void*)pTargetAp, sizeof(TargetAp_t));
			return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_CONNECT, hRoamingMngr);
		}
	}

	TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connect(),"
	       "AP was not found in scan table!! BSSID: "
	       "%02x-%02x-%02x-%02x-%02x-%02x "
	       "\n", pTargetAp->newAP.BSSID[0],pTargetAp->newAP.BSSID[1],pTargetAp->newAP.BSSID[2],pTargetAp->newAP.BSSID[3],pTargetAp->newAP.BSSID[4],pTargetAp->newAP.BSSID[5]);
	return TI_NOK;
}
TI_STATUS roamingMngr_startImmediateScan(TI_HANDLE hRoamingMngr, channelList_t* pChannelList)
{
	roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;

	TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_startImmediateScan().\n");

	/* Save the channelList for later usage in the scanMngr_startImmediateScan() */
	scanMngr_setManualScanChannelList (pRoamingMngr-> hScanMngr, pChannelList);
	return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_SCAN, hRoamingMngr);
}
static void roamingMngr_smConnectedToScan (TI_HANDLE hRoamingMngr)
{
	roamingMngr_t  *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
	TI_STATUS status = TI_OK;

	status= apConn_prepareToRoaming(pRoamingMngr->hAPConnection, ROAMING_TRIGGER_NONE);

	if (status  == TI_OK) {
		status = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr,TI_FALSE);
	} else {
		roamingMngr_smEvent(ROAMING_MANUAL_EVENT_COMPLETE, hRoamingMngr);
	}
}
static void roamingMngr_smConnectedToHandover(TI_HANDLE hRoamingMngr)
{
	roamingMngr_t  *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
	TI_STATUS status = TI_OK;

	pRoamingMngr->handoverWasPerformed = TI_TRUE;
	status= apConn_prepareToRoaming(pRoamingMngr->hAPConnection, pRoamingMngr->roamingTrigger);

	if (status  == TI_OK) {
		apConn_connectToAP(pRoamingMngr->hAPConnection, &(pRoamingMngr->targetAP.newAP), &(pRoamingMngr->targetAP.connRequest), TI_TRUE);
	} else {
		roamingMngr_smEvent(ROAMING_MANUAL_EVENT_REJECT, hRoamingMngr);
	}
}
Exemplo n.º 6
0
/**
*
* roamingMngr_smHandover 
*
* \b Description: 
*
* This procedure is called when handover should be invoked.
*   Go over the candidate APs and start handover to each of them. 
 * If there's no candidate APs, disconnect.
 * Handover to the current AP is allowed only if the trigger is
 * low quality.
 * 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smHandover(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;
    bssEntry_t              *pApToConnect;
    apConn_connRequest_t    requestToApConn;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;

    if ((pRoamingMngr->handoverWasPerformed) && (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX))
    {   /* Handover with the current AP already failed, Disconnect */
        roamingMngr_smEvent(ROAMING_EVENT_FAILURE, pRoamingMngr);
        return;
    }
    if (pRoamingMngr->listOfCandidateAps.numOfNeighborBSS > 0)
    {   /* Neighbor APs are the highest priority to Roam */
        pRoamingMngr->candidateApIndex = 
            pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS-1];
        pRoamingMngr->listOfCandidateAps.numOfNeighborBSS--;
    }
    else if (pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS > 0)
    {   /* Pre-Auth APs are the second priority to Roam */
        pRoamingMngr->candidateApIndex = 
            pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS-1];
        pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS--;
    }
    else if (pRoamingMngr->listOfCandidateAps.numOfRegularBSS > 0)
    {   /* Regular APs are APs that are not pre-authenticated and not Neighbor */
        pRoamingMngr->candidateApIndex = 
            pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS-1];
        pRoamingMngr->listOfCandidateAps.numOfRegularBSS--;
    }
    else
    {   /* No Candidate APs */
        pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
    }

    TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smHandover, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex);


    if (pRoamingMngr->candidateApIndex == INVALID_CANDIDATE_INDEX)
    {   /* No cnadidate to Roam to, only the current AP is candidate */
        if (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP)
        {   /* If the trigger to Roam is low quality, and there are no candidate APs
                to roam to, retain connected to the current AP */
            requestToApConn.requestType = (pRoamingMngr->handoverWasPerformed) ? AP_CONNECT_RECONNECT_CURR_AP : AP_CONNECT_RETAIN_CURR_AP;
            pRoamingMngr->candidateApIndex = CURRENT_AP_INDEX;
        }
        else
        {   /* Disconnect the BSS, there are no more APs to roam to */
            roamingMngr_smEvent(ROAMING_EVENT_FAILURE, pRoamingMngr);
            return;
        }
    }
    else
    {   /* There is a valid candidate AP */
        if (pRoamingMngr->roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
        {   /* Full re-connection should be perfromed */
            requestToApConn.requestType = AP_CONNECT_FULL_TO_AP; 
        }
        else
        {   /* Fast re-connection should be perfromed */
            requestToApConn.requestType = AP_CONNECT_FAST_TO_AP; 
        }
    }
#ifdef TI_DBG
    /* For debug */
    if (!pRoamingMngr->handoverWasPerformed)
    {   /* Take the time before the first handover started */
        pRoamingMngr->roamingHandoverStartedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
    }
#endif
    
    if (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX)
    {   /* get the current AP */
        pApToConnect = apConn_getBSSParams(pRoamingMngr->hAPConnection);
        if (pApToConnect == NULL)
         return;
    }
    else
    {   /* get the candidate AP */
        pRoamingMngr->handoverWasPerformed = TI_TRUE;
        pApToConnect = &pRoamingMngr->pListOfAPs->BSSList[pRoamingMngr->candidateApIndex];
    }
    TRACE3(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smHandover, candidateApIndex=%d, requestType = %d, channel=%d \n", 							 pRoamingMngr->candidateApIndex, requestToApConn.requestType, pApToConnect->channel);

    requestToApConn.dataBufLength = 0;

    apConn_connectToAP(pRoamingMngr->hAPConnection, pApToConnect, &requestToApConn, TI_TRUE);
}
Exemplo n.º 7
0
/**
*
* roamingMngr_smSelection 
*
* \b Description: 
*
* This procedure is called when selection should be performed.
*   It perform the following:
 * Prepare the candidate APs to roam according to:
 *  - Priority APs
 *  - Pre-Authenticated APs
 * If the candidate AP list is empty, only the current AP can be re-selected
 * Select one AP and trigger REQ_HANDOVER event.
 * 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smSelection(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t               *pRoamingMngr;
    TI_UINT32                      index;


    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
    pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
    pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;

    pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;

    if ((pRoamingMngr->pListOfAPs == NULL) || 
        (pRoamingMngr->pListOfAPs->numOfEntries == 0))
    {   /* Error, there cannot be selection  */
        TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smSelection pListOfAPs is empty \n");
        roamingMngr_smEvent(ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr);
        return;
    }

    /* Build the candidate AP list */
    for (index=0; index<pRoamingMngr->pListOfAPs->numOfEntries; index++ )
    {
        if ( (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP) &&
            (pRoamingMngr->pListOfAPs->BSSList[index].RSSI < pRoamingMngr->roamingMngrConfig.apQualityThreshold))
        {   /* Do not insert APs with low quality to the selection table, 
                if the Roaming Trigger was low Quality */
            TRACE8(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "candidate AP %x-%x-%x-%x-%x-%x with RSSI too low =%d, Quality=%d  \n", pRoamingMngr->pListOfAPs->BSSList[index].BSSID[0], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[1], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[2], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[3], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[4], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[5], pRoamingMngr->pListOfAPs->BSSList[index].RSSI, pRoamingMngr->roamingMngrConfig.apQualityThreshold);

            continue;
        }

        if (apConn_isSiteBanned(pRoamingMngr->hAPConnection, &pRoamingMngr->pListOfAPs->BSSList[index].BSSID) == TI_TRUE)
        {
            TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, ": Candidate AP %02X-%02X-%02X-%02X-%02X-%02X is banned!\n",									 pRoamingMngr->pListOfAPs->BSSList[index].BSSID[0],	pRoamingMngr->pListOfAPs->BSSList[index].BSSID[1], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[2], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[3], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[4], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[5]);
            continue;
        }

        if (pRoamingMngr->pListOfAPs->BSSList[index].bNeighborAP)
        {   /* The AP is a neighbor AP, insert its index to the neighbor APs list */
            pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS] = index; 
            pRoamingMngr->listOfCandidateAps.numOfNeighborBSS++;
        }
        else if (apConn_getPreAuthAPStatus(pRoamingMngr->hAPConnection, 
										   &pRoamingMngr->pListOfAPs->BSSList[index].BSSID))
        {   /* This AP is a pre-auth AP */
            pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS] = index; 
            pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS++;
        }
        else
        {   /* This AP is not Neighbor nor Pre-Auth */
            pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS] = index; 
            pRoamingMngr->listOfCandidateAps.numOfRegularBSS++;
        }
    }

#ifdef TI_DBG
    {   /* for debug */
        paramInfo_t     param;

        param.paramType = ROAMING_MNGR_PRINT_CANDIDATE_TABLE;
        roamingMngr_getParam(pRoamingMngr, &param);

    }
#endif
    roamingMngr_smEvent(ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr);

}
TI_STATUS roamingMngr_immediateScanComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus)
{
	roamingMngr_t           *pRoamingMngr;
	roamingMngr_smEvents    roamingEvent;


	pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
	if (pRoamingMngr == NULL) {
		return TI_NOK;
	}

	TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_immediateScanComplete, scanCmpltStatus = %d\n", 							 scanCmpltStatus);

	if (scanCmpltStatus == SCAN_MRS_SCAN_COMPLETE_OK) {
		/* The scan completed TI_OK, get the updated list of APs */
		pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
		if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0)) {
			/* APs were found, start selection */
			pRoamingMngr->scanType = ROAMING_NO_SCAN;
			roamingEvent = ROAMING_EVENT_SELECT;
		} else {  /* There were no APs, if the scan was partial, retry full scan */
			if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
			        (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY)) {
				pRoamingMngr->scanType = ROAMING_FULL_SCAN;
				roamingEvent = ROAMING_EVENT_SCAN;
			} else {
				/* No APs were found in FULL SCAN, report failure */
				roamingEvent = ROAMING_EVENT_SELECT;
			}
		}
	}
	/* scanCmpltStatus != SCAN_MRS_SCAN_COMPLETE_OK */
	else {
		/* The scan failed, retry scanning according to the current scan type */
		pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
		if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0)) {
			/* APs were found, start selection */
			pRoamingMngr->scanType = ROAMING_NO_SCAN;
			roamingEvent = ROAMING_EVENT_SELECT;
		} else {
			/* The scan failed, and there were no APs found.
			Retry scanning according to the current scan type */
			switch (pRoamingMngr->scanType) {
			case ROAMING_PARTIAL_SCAN:
				roamingEvent = ROAMING_EVENT_SCAN;
				pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN_RETRY;
				break;
			case ROAMING_PARTIAL_SCAN_RETRY:
				roamingEvent = ROAMING_EVENT_SELECT;
				pRoamingMngr->scanType = ROAMING_NO_SCAN;
				break;
			case ROAMING_FULL_SCAN:
				roamingEvent = ROAMING_EVENT_SCAN;
				pRoamingMngr->scanType = ROAMING_FULL_SCAN_RETRY;
				break;
			case ROAMING_FULL_SCAN_RETRY:
				roamingEvent = ROAMING_EVENT_SELECT;
				pRoamingMngr->scanType = ROAMING_NO_SCAN;
				break;
			default:
				roamingEvent = ROAMING_EVENT_SELECT;
				TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_immediateScanComplete, pRoamingMngr->scanType = %d\n", 								   pRoamingMngr->scanType);
				pRoamingMngr->scanType = ROAMING_NO_SCAN;
				break;
			} /* switch (pRoamingMngr->scanType) */
		}
	}

	TRACE2(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_immediateScanComplete, roamingEvent = %d, scanType=%d\n", 							roamingEvent, 							 pRoamingMngr->scanType);

	return (roamingMngr_smEvent(roamingEvent, pRoamingMngr));

}
TI_STATUS roamingMngr_setParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam)
{
	roamingMngr_t *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
	TI_STATUS      status       = TI_OK;

	if (pParam == NULL) {
		TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR , "roamingMngr_setParam(): pParam is NULL!\n");
		return TI_NOK;
	}

	TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION , "roamingMngr_setParam   %X \n", pParam->paramType);

	switch (pParam->paramType) {

	case ROAMING_MNGR_APPLICATION_CONFIGURATION: {
		roamingMngrConfigParams_t   *pRoamingMngrConfigParams;

		pRoamingMngrConfigParams = &pParam->content.roamingConfigBuffer;

		/* Configure the Roaming Parmeters */
		TRACE3(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam Configuration: \n                                  enableDisable= %d,\n  lowPassFilterRoamingAttempt=%d,\n                                  apQualityThreshold=%d\n", pRoamingMngrConfigParams->roamingMngrConfig.enableDisable, pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt, pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold);

		pRoamingMngr->roamingMngrConfig.apQualityThreshold = pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold;
		pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt;
		pRoamingMngr->lowPassFilterRoamingAttemptInMsec = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt * 1000;

		/* Configure the Roaming Trigger thresholds */
		TRACE7(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam Thresholds: \n                                  dataRetryThreshold= %d,\n  lowQualityForBackgroungScanCondition=%d,\n                                  lowRssiThreshold=%d,\n lowSNRThreshold=%d,\n                                  normalQualityForBackgroungScanCondition=%d,\n                                  numExpectedTbttForBSSLoss=%d,\n txRateThreshold=%d \n \n", pRoamingMngrConfigParams->roamingMngrThresholdsConfig.dataRetryThreshold, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowRssiThreshold, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowSnrThreshold, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.txRateThreshold);

		os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngr->roamingMngrThresholdsConfig, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t));

		status = apConn_setRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig);

		if (pRoamingMngr->roamingMngrConfig.enableDisable &&
		        !pRoamingMngrConfigParams->roamingMngrConfig.enableDisable) {  /* disable Roaming Manager */
			apConn_unregisterRoamMngrCallb(pRoamingMngr->hAPConnection);
			pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED;
			return (roamingMngr_smEvent(ROAMING_EVENT_STOP, pRoamingMngr));
		} else if (!pRoamingMngr->roamingMngrConfig.enableDisable &&
		           pRoamingMngrConfigParams->roamingMngrConfig.enableDisable) {  /* enable Roaming Manager */
			/* Save the Roaming Configuration parameters */
			pRoamingMngr->roamingMngrConfig.enableDisable = pRoamingMngrConfigParams->roamingMngrConfig.enableDisable;
			/* register Roaming callback */
			apConn_registerRoamMngrCallb(pRoamingMngr->hAPConnection,
			                             roamingMngr_triggerRoamingCb,
			                             roamingMngr_connStatusCb,
			                             roamingMngr_updateNeighborApListCb);
		}
	}
	break;


	/*********** For Debug Purposes ***********/

	case ROAMING_MNGR_TRIGGER_EVENT:
		/* Enable/disable Internal Roaming */
		TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam TRIGGER_EVENT=  %d \n", pParam->content.roamingTriggerType);
		apConn_reportRoamingEvent(pRoamingMngr->hAPConnection, (apConn_roamingTrigger_e)pParam->content.roamingTriggerType, NULL);
		break;

	case ROAMING_MNGR_CONN_STATUS:
		/* External request to connect to BBSID */
		TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_setParam CONN_STATUS=  %d \n", pParam->content.roamingConnStatus);
		roamingMngr_connStatusCb(pRoamingMngr, &pParam->content.roamingConnStatus);
		break;

	default:
		TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_setParam bad param=  %X\n", pParam->paramType);

		break;
	}


	return status;
}
/**
*
* roamingMngr_connStatusCb
*
* \b Description:
*
* This procedure is called when the connection status event
 * is triggered.
*
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*  I   - pData - pointer to the connection status.
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
*
*/
TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData)
{
	roamingMngr_t               *pRoamingMngr;
	apConn_connStatus_e         connStatus;
	roamingMngr_smEvents        roamingEvent;

	pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
	if ((pRoamingMngr == NULL) || (pData == NULL)) {
		return TI_NOK;
	}

	connStatus = ((apConn_connStatus_t *)pData)->status;
	TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_connStatusCb, conn status = %d\n", connStatus);

	if (!pRoamingMngr->roamingMngrConfig.enableDisable) {
		TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connStatusCb, connStatus=%d was received while Roaming is disabled. Stop Roaming \n", 						   connStatus);
		return TI_NOK;
	}

	if (ROAMING_OPERATIONAL_MODE_AUTO == pRoamingMngr->RoamingOperationalMode) {
		switch (connStatus) {
		case CONN_STATUS_CONNECTED:
			roamingEvent = ROAMING_EVENT_START;
			/* Get station capabilities */
			apConn_getStaCapabilities(pRoamingMngr->hAPConnection, &pRoamingMngr->staCapabilities);
			break;
		case CONN_STATUS_NOT_CONNECTED:
			roamingEvent = ROAMING_EVENT_STOP;
			break;
		case CONN_STATUS_HANDOVER_SUCCESS:
			roamingEvent = ROAMING_EVENT_ROAM_SUCCESS;
#ifdef TI_DBG
			/* For debug */
			pRoamingMngr->roamingSuccesfulHandoverNum++;
			pRoamingMngr->roamingHandoverCompletedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
			pRoamingMngr->roamingAverageSuccHandoverDuration += os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingHandoverStartedTimestamp;
			pRoamingMngr->roamingAverageRoamingDuration +=  os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingTriggerTimestamp;
			pRoamingMngr->roamingHandoverEvents[pRoamingMngr->roamingTrigger]++;
#endif
			break;
		case CONN_STATUS_HANDOVER_FAILURE:
			roamingEvent = ROAMING_EVENT_REQ_HANDOVER;
#ifdef TI_DBG
			/* For debug */
			pRoamingMngr->roamingFailedHandoverNum++;
#endif
			break;
		default:
			TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_connStatusCb, bad connStatus = %d\n", connStatus);
			return TI_NOK;
		}
	} else { /* Roaming Manual operational mode*/
		switch (connStatus) {
		case CONN_STATUS_CONNECTED:
			roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_START;
			apConn_getStaCapabilities(pRoamingMngr->hAPConnection,&pRoamingMngr->staCapabilities);
			break;
		case CONN_STATUS_NOT_CONNECTED:
			roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_STOP;
			break;
		case CONN_STATUS_HANDOVER_SUCCESS:
			roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_SUCCESS;
			break;
		case CONN_STATUS_HANDOVER_FAILURE:
			roamingEvent = (roamingMngr_smEvents)ROAMING_MANUAL_EVENT_FAIL;
			break;
		default:
			return TI_NOK;
		}
	}

	return (roamingMngr_smEvent(roamingEvent, pRoamingMngr));
}
/**
*
* roamingMngr_triggerRoamingCb
*
* \b Description:
*
* This procedure is called when Roaming should be triggered
 * due to one of apConn_roamingTrigger_e Roaming Reasons.
 * Save the trigger and process it only if there's no other Roaming trigger
 * in process.
*
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*  I   - pData - pointer to roaming trigger
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
*
*/
TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData, TI_UINT16 reasonCode)
{
	roamingMngr_t       *pRoamingMngr;
	apConn_roamingTrigger_e     roamingTrigger;
	TI_UINT32                   curTimestamp;
	TI_UINT16                   disConnReasonCode;


	pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
	if ((pRoamingMngr == NULL) || (pData == NULL)) {
		return TI_NOK;
	}

	roamingTrigger = *(apConn_roamingTrigger_e *)pData;

	if ((ROAMING_OPERATIONAL_MODE_MANUAL == pRoamingMngr->RoamingOperationalMode) &&
	        (roamingTrigger == ROAMING_TRIGGER_AP_DISCONNECT)) {
		disConnReasonCode = reasonCode;
		EvHandlerSendEvent(pRoamingMngr->hEvHandler, IPC_EVENT_AP_DISCONNECT, (TI_UINT8*)&disConnReasonCode, sizeof(disConnReasonCode));
	}


	if (roamingTrigger >= ROAMING_TRIGGER_LAST) {
		TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_triggerRoamingCb, bad roaming trigger = %d\n", roamingTrigger);
		return TI_NOK;
	}
#ifdef TI_DBG
	/* save parameters for debug*/
	pRoamingMngr->roamingTriggerEvents[pRoamingMngr->roamingTrigger]++;
#endif
	if (roamingTrigger <= ROAMING_TRIGGER_BG_SCAN_GROUP) {
		ERssiQuality    rssiQuality = ROAMING_QUALITY_NORMAL;
		if (roamingTrigger == ROAMING_TRIGGER_LOW_QUALITY_FOR_BG_SCAN) {
			rssiQuality = ROAMING_QUALITY_LOW;
		} else if (roamingTrigger == ROAMING_TRIGGER_HIGH_QUALITY_FOR_BG_SCAN) {
			rssiQuality = ROAMING_QUALITY_HIGH;
		}

		TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, rssiQuality = %d \n", rssiQuality);
		scanMngr_notifyChangeTrigger(pRoamingMngr->hScanMngr, rssiQuality);
	} else {
		if (roamingTrigger > pRoamingMngr->roamingTrigger) {  /* Save the highest priority roaming trigger */
			pRoamingMngr->roamingTrigger = roamingTrigger;
			TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, higher trigger = %d \n", roamingTrigger);

		}

		curTimestamp = os_timeStampMs(pRoamingMngr->hOs);

		/* If "No BSS" trigger received, disable count of low pass filter timer */
		if (roamingTrigger > ROAMING_TRIGGER_LOW_QUALITY_GROUP) {
			pRoamingMngr->lowQualityTriggerTimestamp = 0;
		}

		/* Do not invoke a new Roaming Trigger when a previous one is in process */
		if (pRoamingMngr->maskRoamingEvents == TI_FALSE) {  /* No Roaming trigger is in process */
			/* If the trigger is low quality check the low pass filter */
			TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, trigger = %d \n", roamingTrigger);
			if (roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP) {
				TI_UINT32 deltaTs = curTimestamp-pRoamingMngr->lowQualityTriggerTimestamp;

				if ((pRoamingMngr->lowQualityTriggerTimestamp != 0) &&
				        (deltaTs < pRoamingMngr->lowPassFilterRoamingAttemptInMsec)) { /* Ignore the low quality events. till the low pass time elapses */
					TRACE5(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_triggerRoamingCb, trigger = %d Ignored!!,deltaTs=%d, curTimestamp = %d, lowQualityTriggerTimestamp = %d, lowPassFilterRoamingAttempt=%d\n", roamingTrigger, deltaTs, curTimestamp, pRoamingMngr->lowQualityTriggerTimestamp, pRoamingMngr->lowPassFilterRoamingAttemptInMsec);
					return TI_OK;
				}
				pRoamingMngr->lowQualityTriggerTimestamp = curTimestamp;
			}

			/* Mask all future roaming events */
			pRoamingMngr->maskRoamingEvents = TI_TRUE;

#ifdef TI_DBG
			/* For debug */
			pRoamingMngr->roamingTriggerTimestamp = curTimestamp;
#endif
			return (roamingMngr_smEvent(ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));
		} else if (roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP) {  /* If the trigger is from the Full Connect group, then stop the connection. */
			return (roamingMngr_smEvent(ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));

		}
	}

	return TI_OK;
}
TI_STATUS  roamingMngr_immediateScanByAppComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus)
{
	return roamingMngr_smEvent(ROAMING_MANUAL_EVENT_COMPLETE, hRoamingMngr);
}