blob: 89b2fc20756b3d1d0aca74e4f0b0f1c63c2756c3 [file] [log] [blame]
/*
* 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));
}
}