/*
 * roamingMngr_autoSM.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 roamingMngr_autoSM.c
 *  \brief Roaming Manager
 *
 *  \see roamingMngr_autoSM.h
 */

/****************************************************************************
 *                                                                          *
 *   MODULE:  Roaming Manager                                               *
 *   PURPOSE:                                                               *
 *   Roaming manager is responsible to receive Roaming triggers and try
 *      to select a better AP.
 *      The Roaming triggers are: Low RSSI, PER, consecutive No ACK on TX,
 *      beacon Missed or External request.
 *      In each Internal Roaming request, scan is performed and selection for 
 *      better AP. Better AP is defined as a different AP with better RSSI,
 *      and similar SSID and security settings.
 *      If better AP is found, there is a check for fast-roaming via the
 *      Supplicant. Then connection to the new AP is invoked.
 *                                                                          *
 ****************************************************************************/

#define __FILE_ID__  FILE_ID_135
#include "osApi.h"

#include "paramOut.h"
#include "report.h"
#include "scanMngrApi.h"
#include "roamingMngrApi.h"
#include "apConnApi.h"
#include "roamingMngrTypes.h"
#include "bssTypes.h"
#include "DrvMainModules.h"
#include "TWDriver.h"
#include "siteMgrApi.h"
#include "GenSM.h"
#include "roamingMngr_autoSM.h"


/*****************************************************************************
**         Private Function section                                      **
*****************************************************************************/
/* SM functions */

static void roamingMngr_smStartIdle(TI_HANDLE hRoamingMngr);
static void roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr);
static void roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr);
static void roamingMngr_smSelection(TI_HANDLE hRoamingMngr);
static void roamingMngr_smHandover(TI_HANDLE hRoamingMngr);
static void roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr);
static void roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr);
static void roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr);
static void roamingMngr_smDisconnectWhileConnecting(TI_HANDLE hRoamingMngr);

/*static TI_STATUS roamingMngr_smUnexpected(TI_HANDLE hRoamingMngr);
static TI_STATUS roamingMngr_smNop(TI_HANDLE hRoamingMngr);
static TI_STATUS roamingMngr_smStopWhileScanning(TI_HANDLE hRoamingMngr);
*/

typedef enum 
{
	REASSOC_RESP_SUCCESS =0,
	REASSOC_RESP_FAILURE,
    REASSOC_RESP_REJECT
} reassociationResp_e;


/*-----------*/
/* Constants */
/*-----------*/

TGenSM_actionCell roamingMngrAuto_matrix[ROAMING_MNGR_NUM_STATES][ROAMING_MNGR_NUM_EVENTS] =
{
    /* next state and actions for IDLE state */
        {   {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smStartIdle},        /* START            */
            {ROAMING_STATE_IDLE, roamingMngr_smNop},                        /* STOP             */ 
            {ROAMING_STATE_IDLE, roamingMngr_smNop},                        /* ROAM_TRIGGER     */
            {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* SCAN             */
            {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* SELECT           */
            {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* REQ_HANDOVER     */
            {ROAMING_STATE_IDLE, roamingMngr_smUnexpected},                 /* ROAM_SUCCESS     */
            {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}                  /* FAILURE          */
        },                                                                              

        /* next state and actions for WAIT_4_TRIGGER state */    
        {   {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* START            */ 
            {ROAMING_STATE_IDLE, roamingMngr_smStop},                   /* STOP             */ 
            {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smRoamTrigger},      /* ROAM_TRIGGER     */ 
            {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* SCAN             */ 
            {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* SELECT           */ 
            {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* REQ_HANDOVER     */ 
            {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected},   /* ROAM_SUCCESS     */ 
            {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}    /* FAILURE          */
        },                                                                              
    
        /* next state and actions for WAIT_4_CMD state */    
        {   {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* START            */ 
            {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* STOP             */ 
            {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* ROAM_TRIGGER     */ 
            {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan},                 /* SCAN             */ 
            {ROAMING_STATE_SELECTING, roamingMngr_smSelection},                 /* SELECT           */ 
            {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* REQ_HANDOVER     */ 
            {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected},               /* ROAM_SUCCESS     */ 
            {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}                /* FAILURE          */ 
        },                                                                              

        /* next state and actions for SCANNING state */                      
        {   {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected},              /* START            */
            {ROAMING_STATE_IDLE, roamingMngr_smStopWhileScanning},           /* STOP             */
            {ROAMING_STATE_SCANNING, roamingMngr_smNop},                     /* ROAM_TRIGGER     */
            {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan},              /* SCAN             */
            {ROAMING_STATE_SELECTING, roamingMngr_smSelection},              /* SELECT           */
            {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected},              /* REQ_HANDOVER     */
            {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected},              /* ROAM_SUCCESS     */
            {ROAMING_STATE_IDLE, roamingMngr_smScanFailure}                  /* FAILURE          */
                                                                                   
        }, 

        /* next state and actions for SELECTING state */                      
        {   {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* START            */
            {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* STOP             */
            {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* ROAM_TRIGGER     */
            {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* SCAN             */
            {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* SELECT           */
            {ROAMING_STATE_CONNECTING, roamingMngr_smHandover},              /* REQ_HANDOVER     */
            {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected},             /* ROAM_SUCCESS     */
            {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}              /* FAILURE          */
                                                                                   
        }, 

        /* next state and actions for CONNECTING state */                      
        {   {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected},           /* START            */ 
            {ROAMING_STATE_IDLE, roamingMngr_smStop},                       /* STOP             */ 
            {ROAMING_STATE_IDLE, roamingMngr_smDisconnectWhileConnecting},      /* ROAM_TRIGGER     */ 
            {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected},           /* SCAN,            */ 
            {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected},           /* SELECT           */ 
            {ROAMING_STATE_CONNECTING, roamingMngr_smHandover},             /* REQ_HANDOVER     */ 
            {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smSuccHandover} ,    /* ROAM_SUCCESS     */ 
            {ROAMING_STATE_IDLE, roamingMngr_smFailHandover}                /* FAILURE          */ 
                                                                                   
        } 
}; 


TI_INT8*  AutoRoamStateDescription[] = 
{
    "IDLE",
    "WAIT_4_TRIGGER",
    "WAIT_4_CMD",
    "SCANNING",
    "SELECTING",
    "CONNECTING"
};

TI_INT8*  AutoRoamEventDescription[] = 
{
    "START",
    "STOP",
    "ROAM_TRIGGER",
    "SCAN",
    "SELECT",
    "REQ_HANDOVER",
    "ROAM_SUCCESS",
    "FAILURE"
};

/**
*
* 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);
}

/**
*
* roamingMngr_smInvokeScan 
*
* \b Description: 
*
* This procedure is called when scan should be performed in order
 * to select an AP to roam to.
 * This can be the first scan, a second scan after partail scan,
 * or scan after previous scan was failed.
 * In any case, the scan can either be:
 *  partail, on list of channles or
 *  full on all channels.
*
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t       *pRoamingMngr;
    scan_mngrResultStatus_e     scanResult;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;

    /* check which scan should be performed: Partial on list of channels, or full scan */
    if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
        (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY))
    {
        scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, TI_TRUE);
    }
    else
    {    /* Scan all channels */
        scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, TI_FALSE);
    }
   
    if (scanResult != SCAN_MRS_SCAN_RUNNING)
    {   /* the scan failed, immitate scan complete event */
        TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smInvokeScan, scanResult = %d\n", scanResult);
        roamingMngr_immediateScanComplete(pRoamingMngr, scanResult);
    }
}

/**
*
* 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);

}

/**
*
* 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);
    }
    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);
}

/**
*
* roamingMngr_smDisconnectWhileConnecting 
*
* \b Description: 
*
* This procedure is called when the Station is in the process of connection,
 * and the AP disconnects the station. 
 * 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smDisconnectWhileConnecting(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
 
    TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smDisconnectWhileConnecting, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex);

    if (pRoamingMngr->roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
    {   /* If the trigger is from the Full Connect group, then stop the connection. */
        /* clean intenal variables */
        pRoamingMngr->maskRoamingEvents = TI_TRUE;
        pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;

        scanMngr_stopContScan(pRoamingMngr->hScanMngr);
#ifdef TI_DBG
        pRoamingMngr->roamingFailedHandoverNum++;
#endif
        apConn_disconnect(pRoamingMngr->hAPConnection);
        
    }
}

/**
*
* roamingMngr_smSuccHandover 
*
* \b Description: 
*
* This procedure is called when handover succeeded.
 * Inform Scan Manager about the new AP.    
 * UnMask Roaming Triggers. 
 * 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;
    bssEntry_t              *pNewConnectedAp;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;

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

    if (pRoamingMngr->handoverWasPerformed &&
        (pRoamingMngr->pListOfAPs != NULL) &&
        (pRoamingMngr->pListOfAPs->numOfEntries>0))
    {
        if (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX)
        {   
			/* get the current AP */
            pNewConnectedAp = apConn_getBSSParams(pRoamingMngr->hAPConnection);
        }
        else
        {   
			/* get the candidate AP */
            pNewConnectedAp = &pRoamingMngr->pListOfAPs->BSSList[pRoamingMngr->candidateApIndex];
        }

        scanMngr_handoverDone(pRoamingMngr->hScanMngr, 
							  &pNewConnectedAp->BSSID,
							  pNewConnectedAp->band);
    }
    pRoamingMngr->maskRoamingEvents = TI_FALSE;
    pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
    pRoamingMngr->handoverWasPerformed = TI_FALSE;
    pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;

    /* Start pre-authentication in order to set PMKID
        for the current AP */
    if (pRoamingMngr->staCapabilities.authMode==os802_11AuthModeWPA2)
    {
		/* No Pre-Auth is required */
        bssList_t           *pBssList;

        TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smStartIdle, Pre-Auth to cur AP\n");
        pBssList = os_memoryAlloc(pRoamingMngr->hOs, sizeof(bssList_t));
        if (!pBssList)
            return;
        pBssList->numOfEntries = 0;
        apConn_preAuthenticate(pRoamingMngr->hAPConnection, pBssList);
        os_memoryFree(pRoamingMngr->hOs, pBssList, sizeof(bssList_t));
    }
}

/**
*
* roamingMngr_smFailHandover 
*
* \b Description: 
*
* This procedure is called when handover failed and there are no more
 * APs to roam to. Disconnect the BSS and retrun to IDLE state.
* 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smFailHandover \n");

    /* clean intenal variables */
    pRoamingMngr->maskRoamingEvents = TI_TRUE;
    pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;

    scanMngr_stopContScan(pRoamingMngr->hScanMngr);
#ifdef TI_DBG
    pRoamingMngr->roamingFailedHandoverNum++;
#endif
    apConn_disconnect(pRoamingMngr->hAPConnection);
}

/**
*
* roamingMngr_smScanFailure 
*
* \b Description: 
*
* This procedure is called when all scan attempts failed. 
 * Send Disconnect event and return to IDLE state.
 *
* 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smScanFailure \n");

    /* clean intenal variables */
    pRoamingMngr->maskRoamingEvents = TI_TRUE;
    pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;

    scanMngr_stopContScan(pRoamingMngr->hScanMngr);

    apConn_disconnect(pRoamingMngr->hAPConnection);
}

#if 0
/**
*
* roamingMngr_smCmdFailure 
*
* \b Description: 
*
* This procedure is called when all the driver failed to prepare to Roaming. 
 * Mask all future Roaming triggers.
 *
* 
* \b ARGS:
*
*  I   - hRoamingMngr - roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smCmdFailure(TI_HANDLE hRoamingMngr)
{
    roamingMngr_t           *pRoamingMngr;

    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
    TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smCmdFailure \n");

    /* clean intenal variables */
    pRoamingMngr->maskRoamingEvents = TI_TRUE;
    pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE; 
}
#endif

/**
*
* roamingMngr_smStartIdle - Start event when in Idle state
*
* \b Description: 
*
* Start event when in Idle state. 
 * This function is called when the station becomes CONNECTED.
 * Perform the following:
 * - The current state becomes WAIT_4_TRIGGER 
 * - Unmask Roaming events
 * - Set handoverWasPerformed to TI_FALSE
 * - Start the Scan Manager
*
* \b ARGS:
*
*  I   - pData - pointer to the roamingMngr SM context  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* 
*/
static void roamingMngr_smStartIdle(void *pData)
{
    roamingMngr_t       *pRoamingMngr;
    bssEntry_t          *pCurBssEntry;

    pRoamingMngr = (roamingMngr_t*)pData;
    TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smStartIdle, Unmask Roaming events and start continuos scan \n");

    pRoamingMngr->maskRoamingEvents = TI_FALSE;
    pRoamingMngr->handoverWasPerformed = TI_FALSE;
    pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;

    pCurBssEntry = apConn_getBSSParams(pRoamingMngr->hAPConnection);
    scanMngr_startContScan(pRoamingMngr->hScanMngr, &pCurBssEntry->BSSID, pCurBssEntry->band);

    /* Start pre-authentication in order to set PMKID
        for the current AP */
    if (pRoamingMngr->staCapabilities.authMode==os802_11AuthModeWPA2)
    {   /* No Pre-Auth is required */
        bssList_t           *pBssList;

        TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smStartIdle, Pre-Auth to cur AP\n");
        pBssList = os_memoryAlloc(pRoamingMngr->hOs, sizeof(bssList_t));
        if (!pBssList)
            return;

        pBssList->numOfEntries = 0;
        apConn_preAuthenticate(pRoamingMngr->hAPConnection, pBssList);
        os_memoryFree(pRoamingMngr->hOs, pBssList, sizeof(bssList_t));
    }
}

