blob: ca2c516d49c8d59b9d5873676a54ab4a6663d8a3 [file] [log] [blame]
/*
* roamingMngr_manualSM.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_manualSM.c
* \brief Roaming Manager
*
* \see roamingMngr_manualSM.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_136
#include "osApi.h"
#include "paramOut.h"
#include "report.h"
#include "scanMngrApi.h"
#include "roamingMngrApi.h"
#include "roamingMngrTypes.h"
#include "bssTypes.h"
#include "DrvMainModules.h"
#include "TWDriver.h"
#include "siteMgrApi.h"
#include "GenSM.h"
#include "apConnApi.h"
#include "roamingMngr_manualSM.h"
#include "EvHandler.h"
#include "public_types.h"
typedef enum
{
REASSOC_RESP_SUCCESS =0,
REASSOC_RESP_FAILURE,
REASSOC_RESP_REJECT
} reassociationResp_e;
static void roamingMngr_SendReassocEvent(TI_HANDLE hRoamingMngr, reassociationResp_e ReassResp);
static void roamingMngr_smIdleToStart (TI_HANDLE hRoamingMngr);
static void roamingMngr_smSTOP (TI_HANDLE hRoamingMngr);
static void roamingMngr_smConnectedToScan (TI_HANDLE hRoamingMngr);
static void roamingMngr_smConnectedToHandover(TI_HANDLE hRoamingMngr);
static void roamingMngr_smScanToConnected(TI_HANDLE hRoamingMngr);
static void roamingMngr_smHandoverToHandoverConnectEvent (TI_HANDLE hRoamingMngr);
static void roamingMngr_smHandoverToHandoverFailEvent (TI_HANDLE hRoamingMngr);
static void roamingMngr_smHandoverToConnectedSuccessEvent(TI_HANDLE hRoamingMngr);
static void roamingMngr_smHandoverToConnectedRejectEvent(TI_HANDLE hRoamingMngr);
/*-----------*/
/* Constants */
/*-----------*/
TGenSM_actionCell roamingMngrManual_matrix[ROAMING_MANUAL_NUM_STATES][ROAMING_MANUAL_NUM_EVENTS] =
{
/* next state and actions for IDLE state */
{
{ROAMING_MANUAL_STATE_CONNECTED, roamingMngr_smIdleToStart}, /* START */
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* SCAN */
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /*CONNECT*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* STOP*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* REJECT*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* SUCCESS*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* FAIL*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* COMPLETE*/
},
/* next state and actions for CONNECTED state */
{
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* START */
{ROAMING_MANUAL_STATE_SCAN, roamingMngr_smConnectedToScan}, /* SCAN */
{ROAMING_MANUAL_STATE_HANDOVER, roamingMngr_smConnectedToHandover}, /*CONNECT*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smSTOP}, /* STOP*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* REJECT*/
{ROAMING_MANUAL_STATE_CONNECTED, roamingMngr_smNop}, /* SUCCESS* retain CurrAp called */
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* FAIL*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* COMPLETE*/
},
/* next state and actions for SCAN state */
{
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* START */
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* SCAN */
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /*CONNECT*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smSTOP}, /* STOP*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* REJECT*/
{ROAMING_MANUAL_STATE_SCAN, roamingMngr_smNop}, /* SUCCESS* retain CurrAp called */
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* FAIL*/
{ROAMING_MANUAL_STATE_CONNECTED, roamingMngr_smScanToConnected}, /* COMPLETE*/
},
/* next state and actions for HANDOVER state */
{
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* START */
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected}, /* SCAN */
{ROAMING_MANUAL_STATE_HANDOVER,roamingMngr_smHandoverToHandoverConnectEvent}, /*CONNECT*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smSTOP}, /* STOP*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smHandoverToConnectedRejectEvent}, /* REJECT*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smHandoverToConnectedSuccessEvent}, /* SUCCESS*/
{ROAMING_MANUAL_STATE_HANDOVER, roamingMngr_smHandoverToHandoverFailEvent}, /* FAIL*/
{ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected }, /* COMPLETE*/
}
};
TI_INT8* ManualRoamStateDescription[] =
{
"IDLE",
"CONNECTED",
"SCAN",
"HANDOVER"
};
TI_INT8* ManualRoamEventDescription[] =
{
"START",
"SCAN",
"CONNECT",
"STOP",
"REJECT",
"SUCCESS",
"FAIL",
"COMPLETE"
};
static void roamingMngr_smIdleToStart (TI_HANDLE hRoamingMngr)
{
roamingMngr_t* pRoamingMngr;
pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
scanMngr_startManual((TI_HANDLE)pRoamingMngr->hScanMngr);
}
static void roamingMngr_smSTOP (TI_HANDLE hRoamingMngr)
{
roamingMngr_t* pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
//if (SCAN_ISS_IDLE != pScanMngr->immedScanState || SCAN_CSS_IDLE!= != pScanMngr->contScanState)
{
roamingMngr_smStopWhileScanning(hRoamingMngr);
}
scanMngr_stopManual(pRoamingMngr->hScanMngr);
}
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);
}
}
static void roamingMngr_smScanToConnected(TI_HANDLE hRoamingMngr)
{
roamingMngr_t *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
apConn_connRequest_t request;
request.dataBufLength = 0;
request.requestType = AP_CONNECT_RETAIN_CURR_AP;
apConn_connectToAP(pRoamingMngr->hAPConnection, NULL , &request , TI_FALSE);
}
static void roamingMngr_smHandoverToHandoverConnectEvent (TI_HANDLE hRoamingMngr)
{
roamingMngr_t *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
apConn_connectToAP(pRoamingMngr->hAPConnection, &(pRoamingMngr->targetAP.newAP), &(pRoamingMngr->targetAP.connRequest), TI_TRUE);
}
static void roamingMngr_smHandoverToHandoverFailEvent (TI_HANDLE hRoamingMngr)
{
roamingMngr_SendReassocEvent(hRoamingMngr, REASSOC_RESP_FAILURE);
}
static void roamingMngr_smHandoverToConnectedSuccessEvent(TI_HANDLE hRoamingMngr)
{
roamingMngr_SendReassocEvent(hRoamingMngr, REASSOC_RESP_SUCCESS);
}
static void roamingMngr_smHandoverToConnectedRejectEvent(TI_HANDLE hRoamingMngr)
{
roamingMngr_SendReassocEvent(hRoamingMngr, REASSOC_RESP_REJECT);
}
static void roamingMngr_SendReassocEvent(TI_HANDLE hRoamingMngr, reassociationResp_e ReassResp)
{
roamingMngr_t *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_SendReassocEvent(): %d \n", ReassResp);
EvHandlerSendEvent(pRoamingMngr->hEvHandler,
IPC_EVENT_REASSOCIATION_RESP,
(TI_UINT8*)(&ReassResp),
sizeof(reassociationResp_e));
}