| /**************************************************************************** |
| **+-----------------------------------------------------------------------+** |
| **| |** |
| **| Copyright(c) 1998 - 2008 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 apConn.c |
| * \brief AP Connection |
| * |
| * \see apConn.h |
| */ |
| |
| /**************************************************************************** |
| * * |
| * MODULE: AP Connection * |
| * PURPOSE: * |
| * Roaming ability of eSTA is implemented by Roaming Manager Component and |
| * described in "Roaming Manager module LLD" document, and by |
| * AP Connection module. AP Connection module implemented as two sub-modules: |
| * The major one is AP Connection, that is responsible for: |
| * - providing Roaming Manager with access to other parts of WLAN Driver, |
| * - implementing low levels of roaming mechanism. |
| * Current BSS sub-module takes care of: |
| * - maintaining database of current AP info, |
| * - providing access to database of current AP info. |
| * * |
| ****************************************************************************/ |
| |
| #include "osApi.h" |
| |
| #include "paramIn.h" |
| #include "report.h" |
| #include "utils.h" |
| |
| #include "smeSmApi.h" |
| #include "siteMgrApi.h" |
| #include "smeApi.h" |
| #include "PowerMgr_API.h" |
| #include "TrafficMonitorAPI.h" |
| #include "RateAdaptation.h" |
| #include "qosMngr_API.h" |
| #ifdef EXC_MODULE_INCLUDED |
| #include "excMngr.h" |
| #endif |
| #include "measurementMgrApi.h" |
| #include "connApi.h" |
| #include "EvHandler.h" |
| #include "apConn.h" |
| #include "currBss.h" |
| #include "Ctrl.h" |
| #include "fsm.h" |
| #include "scrApi.h" |
| #include "regulatoryDomainApi.h" |
| |
| /* Constants and macros */ |
| #ifdef TI_DBG |
| #define AP_CONN_VALIDATE_HANDLE(hAPConnection) \ |
| if (hAPConnection == NULL) \ |
| { \ |
| WLAN_OS_REPORT(("FATAL ERROR: AP Connection context is not initiated\n")); \ |
| return NOK; \ |
| } |
| #else |
| #define AP_CONN_VALIDATE_HANDLE(hAPConnection) |
| #endif |
| |
| #define MAX_ROAMING_TRIGGERS ROAMING_TRIGGER_LAST |
| |
| #define UPDATE_SEND_DEAUTH_PACKET_FLAG(roamingEventType) \ |
| if ((roamingEventType >= ROAMING_TRIGGER_MAX_TX_RETRIES) && \ |
| (roamingEventType != ROAMING_TRIGGER_SECURITY_ATTACK)) \ |
| { \ |
| pAPConnection->sendDeauthPacket = FALSE; \ |
| } |
| |
| /* Init bits */ |
| |
| |
| /* Enumerations */ |
| |
| /** |
| * AP Connection state machine states |
| */ |
| typedef enum |
| { |
| AP_CONNECT_STATE_IDLE = 0, /**< Initial state */ |
| AP_CONNECT_STATE_WAIT_ROAM, /**< Connected to AP, waiting for start roaming command */ |
| AP_CONNECT_STATE_SWITCHING_CHANNEL, /**< Connected to AP, switch channel in progress */ |
| AP_CONNECT_STATE_WAIT_CONNECT_CMD, /**< SCR allocated, PS mode entered; wait for cmd from Roam Mngr */ |
| AP_CONNECT_STATE_PREPARE_HAND_OFF, /**< Request CCKM for new AP, wait for response */ |
| AP_CONNECT_STATE_CONNECTING, /**< Performing Connection to new AP; wait for response from Conn SM */ |
| AP_CONNECT_STATE_DISCONNECTING, /**< Wait for completion of current link disconnection */ |
| AP_CONNECT_STATE_REESTABLISH_VOICE, /**< Wait for completion of voice TSPEC re-negotiation */ |
| AP_CONNECT_STATE_LAST |
| } apConn_smStates; |
| |
| |
| /** |
| * AP Connection state machine events |
| */ |
| typedef enum |
| { |
| AP_CONNECT_EVENT_PREPARE_FOR_ROAMING= 0,/**< Sent by Roam MNGR when roaming event occurs */ |
| AP_CONNECT_EVENT_FINISHED_OK, /**< Indicates successful completion of request sent to Conn SM */ |
| AP_CONNECT_EVENT_FINISHED_NOT_OK, /**< Indicates unsuccessful completion of request sent to Conn SM */ |
| AP_CONNECT_EVENT_RETAIN_CURRENT_AP, /**< Sent by Roam MNGR when it wishes to give-up roaming */ |
| AP_CONNECT_EVENT_START, /**< Sent by SME when first time link to AP is established */ |
| AP_CONNECT_EVENT_START_ROAM, /**< Sent by Roam MNGR when it wishes to roam to new AP */ |
| AP_CONNECT_EVENT_START_SWITCH_CHANNEL, /**< Sent by Switch channel module when starting switch channel process (tx enabled) */ |
| AP_CONNECT_EVENT_FINISHED_SWITCH_CH, /**< Sent by Switch channel module when finishing switch channel process (tx enabled) */ |
| AP_CONNECT_EVENT_FINISHED_HAND_OVER, /**< Sent by EXC module when finishing hand-over */ |
| AP_CONNECT_EVENT_STOP, /**< Disconnect current link, send stop indication to other modules */ |
| AP_CONNECT_EVENT_LAST |
| } apConn_smEvents; |
| |
| #define AP_CONNECT_NUM_STATES AP_CONNECT_STATE_LAST |
| #define AP_CONNECT_NUM_EVENTS AP_CONNECT_EVENT_LAST |
| |
| |
| #ifdef REPORT_LOG |
| |
| /* Global variables */ |
| static char *apConn_stateDesc[AP_CONNECT_NUM_STATES] = { |
| "APC_STATE_IDLE", |
| "APC_STATE_WAIT_ROAM", |
| "APC_STATE_SWITCHING_CHANNEL", |
| "APC_STATE_WAIT_CONNECT_CMD", |
| "APC_STATE_PREPARE_HAND_OFF", |
| "APC_STATE_CONNECTING", |
| "APC_STATE_DISCONNECTING", |
| "APC_STATE_REESTABLISH_VOICE" |
| }; |
| |
| static char *apConn_eventDesc[AP_CONNECT_NUM_EVENTS] = { |
| "APC_EVENT_PREPARE_FOR_ROAMING", |
| "APC_EVENT_FINISHED_OK", |
| "APC_EVENT_FINISHED_NOT_OK", |
| "APC_EVENT_RETAIN_CURRENT_AP", |
| "APC_EVENT_START", |
| "APC_EVENT_START_ROAM", |
| "APC_EVENT_START_SWITCH_CHANNEL", |
| "APC_EVENT_FINISHED_SWITCH_CHANNEL", |
| "APC_EVENT_FINISHED_HAND_OVER", |
| "APC_EVENT_STOP" |
| }; |
| |
| #endif |
| |
| |
| /* Typedefs */ |
| |
| /* Structures */ |
| |
| /** |
| * AP Connection control block |
| * Following structure defines parameters that can be configured externally, |
| * internal variables, AP Connection state machine and handlers of other modules |
| * used by AP Connection module |
| */ |
| typedef struct _apConn_t |
| { |
| /* AP Connection state machine */ |
| fsm_stateMachine_t *apConnSM; /**< AP Connection module state machine */ |
| apConn_smStates currentState; /**< AP Connection state machine current state */ |
| |
| /* Internal parameters */ |
| BOOL firstAttempt2Roam; /**< TRUE if still connected to original AP, FALSE otherwise */ |
| BOOL roamingEnabled; /**< If FALSE, act like if no roaming callback registered. */ |
| apConn_roamingTrigger_e roamReason; /**< The most severe and recent reason for roaming */ |
| APDisconnect_t APDisconnect; /**< The AP disconnect trigger extra information */ |
| bssEntry_t *newAP; /**< Stores parameters of roaming candidate */ |
| apConn_connRequest_e requestType; /**< Stores type of roaming request */ |
| INT8 rssiThreshold; /**< Stores recently configured RSSI threshold */ |
| UINT8 snrThreshold; /**< Stores recently configured SNR threshold */ |
| UINT8 txFailureThreshold; /**< Stores recently configured consec. no ack threshold */ |
| UINT8 lowRateThreshold; /**< Stores recently configured consec. no ack threshold */ |
| UINT32 vsIElength; /**< Length of vendor specific info-element for assoc req (if defined) */ |
| char *vsIEbuf; /**< Pointer to vendor specific info-element for assoc req (if defined) */ |
| BOOL isRssiTriggerMaskedOut; |
| BOOL isSnrTriggerMaskedOut; |
| BOOL isConsTxFailureMaskedOut; |
| BOOL islowRateTriggerMaskedOut; |
| BOOL removeKeys; /**< Indicates whether keys should be removed after disconnect or not */ |
| BOOL ignoreDeauthReason0;/**< Indicates whether to ignore DeAuth with reason 0, required for Rogue AP test EXC-V2 */ |
| BOOL sendDeauthPacket; /**< Indicates whether to send DEAUTH packet when discommecting or not */ |
| BOOL voiceTspecConfigured;/**< Shall be set to TRUE before roaming in case the TSPEC is configured */ |
| BOOL videoTspecConfigured;/**< Shall be set to TRUE before roaming in case the TSPEC is configured */ |
| BOOL reNegotiateTSPEC; /**< Shall be set to TRUE before hand-over if requested by Roaming Manager */ |
| BOOL resetReportedRoamingStatistics; /**< Shall be set to TRUE if starting to measure traffic */ |
| UINT16 lastRoamingDelay; |
| UINT32 roamingStartedTimestamp; |
| UINT8 roamingSuccesfulHandoverNum; |
| BOOL bNonRoamingDisAssocReason; /**< Indicate whether last disconnection was called from outside (SME) */ |
| /** Callback functions, registered by Roaming manager */ |
| apConn_roamMngrCallb_t roamEventCallb; /**< roam event triggers */ |
| apConn_roamMngrCallb_t reportStatusCallb; /**< connection status events */ |
| apConn_roamMngrCallb_t returnNeighborApsCallb; /**< neighbor APs list update */ |
| |
| /* Handlers of other modules used by AP Connection */ |
| TI_HANDLE hOs; |
| TI_HANDLE hReport; |
| TI_HANDLE hCurrBSS; |
| TI_HANDLE hRoamMng; |
| TI_HANDLE hSme; |
| TI_HANDLE hSiteMgr; |
| TI_HANDLE hExcMngr; |
| TI_HANDLE hConnSm; |
| TI_HANDLE hPrivacy; |
| TI_HANDLE hQos; |
| TI_HANDLE hRateAdapt; |
| TI_HANDLE hEvHandler; |
| TI_HANDLE hScr; |
| TI_HANDLE hAssoc; |
| TI_HANDLE hRegulatoryDomain; |
| |
| /* Counters for statistics */ |
| UINT32 roamingTriggerEvents[MAX_ROAMING_TRIGGERS]; |
| UINT32 roamingSuccesfulHandoverTotalNum; |
| UINT32 roamingFailedHandoverNum; |
| UINT32 retainCurrAPNum; |
| UINT32 disconnectFromRoamMngrNum; |
| UINT32 stopFromSmeNum; |
| } apConn_t; |
| |
| |
| /* Internal functions prototypes */ |
| |
| /* SM functions */ |
| static TI_STATUS apConn_smEvent(apConn_smStates *currState, UINT8 event, void* data); |
| static TI_STATUS apConn_smNop(void *pData); |
| static TI_STATUS apConn_smUnexpected(void *pData); |
| static TI_STATUS apConn_startWaitingForTriggers(void *pData); |
| static TI_STATUS apConn_connectedToNewAP(void *pData); |
| static TI_STATUS apConn_configureDriverBeforeRoaming(void *pData); |
| static TI_STATUS apConn_stopConnection(void *pData); |
| static TI_STATUS apConn_invokeConnectionToNewAp(void *pData); |
| static TI_STATUS apConn_reportDisconnected(void *pData); |
| static TI_STATUS apConn_retainAP(void *pData); |
| static TI_STATUS apConn_requestCCKM(void *pData); |
| static TI_STATUS apConn_reportConnFail(void *pData); |
| static TI_STATUS apConn_swChFinished(void *pData); |
| static TI_STATUS apConn_handleTspecReneg (void *pData); |
| |
| /* other functions */ |
| #ifdef EXC_MODULE_INCLUDED |
| static void apConn_calcNewTsf(apConn_t *hAPConnection, UINT8 *tsfTimeStamp, UINT32 newSiteOsTimeStamp, UINT32 beaconInterval); |
| #endif |
| static TI_STATUS apConn_qosMngrReportResultCallb (TI_HANDLE hApConn, trafficAdmRequestStatus_e result); |
| static void apConn_reportConnStatusToSME (apConn_t *pAPConnection); |
| |
| |
| /* Public functions implementation */ |
| |
| /** |
| * |
| * apConn_create |
| * |
| * \b Description: |
| * |
| * Create the AP Connection context: |
| * allocate memory for internal variables; |
| * create state machine. |
| * |
| * \b ARGS: |
| * |
| * I - hOs - OS handler |
| * |
| * \b RETURNS: |
| * |
| * Pointer to the AP Connection on success, NULL on failure |
| * (unable to allocate memory or other error). |
| * |
| * \sa |
| */ |
| TI_HANDLE apConn_create(TI_HANDLE hOs) |
| { |
| TI_STATUS status; |
| apConn_t *pAPConnection; |
| |
| if ((pAPConnection = os_memoryAlloc(hOs, sizeof(apConn_t))) != NULL) |
| { |
| pAPConnection->hOs = hOs; |
| |
| status = fsm_Create(hOs, &(pAPConnection->apConnSM), AP_CONNECT_NUM_STATES, AP_CONNECT_NUM_EVENTS); |
| if (status == OK) |
| { |
| /* Succeeded to create AP Connection module context - return pointer to it */ |
| return pAPConnection; |
| } |
| else /* Failed to create state machine */ |
| { |
| WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error creating apConnSM - aborting\n")); |
| /* Free pre-allocated control block */ |
| utils_nullMemoryFree(hOs, pAPConnection, sizeof(apConn_t)); |
| return NULL; |
| } |
| } |
| else /* Failed to allocate control block */ |
| { |
| WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n")); |
| return NULL; |
| } |
| } |
| |
| /** |
| * |
| * apConn_unload |
| * |
| * \b Description: |
| * |
| * Finish AP Connection module work: |
| * release the allocation for state machine and internal variables. |
| * |
| * \b ARGS: |
| * |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_unload(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pAPConnection = (apConn_t *)hAPConnection; |
| |
| /* Unload state machine */ |
| fsm_Unload(pAPConnection->hOs, pAPConnection->apConnSM); |
| |
| /* Free pre-allocated control block */ |
| utils_nullMemoryFree(pAPConnection->hOs, pAPConnection, sizeof(apConn_t)); |
| |
| return OK; |
| } |
| |
| /** |
| * |
| * apConn_config |
| * |
| * \b Description: |
| * |
| * Prepare AP Connection module to work: initiate internal variables, start state machine |
| * |
| * \b ARGS: |
| * |
| * I - hCurrAP - Current BSS handle \n |
| * I - hRoamMng - Roaming Manager handle \n |
| * I - hSme - SME context \n |
| * I - hPowerMgr - Power Manager context \n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK on failure. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_config(TI_HANDLE hAPConnection, |
| TI_HANDLE hReport, |
| TI_HANDLE hCurrAP, |
| TI_HANDLE hRoamMng, |
| TI_HANDLE hSme, |
| TI_HANDLE hSiteMgr, |
| TI_HANDLE hExcMngr, |
| TI_HANDLE hConnSm, |
| TI_HANDLE hPrivacy, |
| TI_HANDLE hQos, |
| TI_HANDLE hCtrl, |
| TI_HANDLE hEvHandler, |
| TI_HANDLE hScr, |
| TI_HANDLE hAssoc, |
| TI_HANDLE hRegulatoryDomain, |
| apConnParams_t *pApConnParams) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| TI_STATUS status; |
| UINT32 index; |
| |
| /** State Machine matrix */ |
| fsm_actionCell_t apConn_matrix[AP_CONNECT_NUM_STATES][AP_CONNECT_NUM_EVENTS] = |
| { |
| /* next state and actions for IDLE state */ |
| { {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}, /* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}, /* FINISHED_OK */ |
| {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_WAIT_ROAM,apConn_startWaitingForTriggers},/* START */ |
| {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}, /* START_ROAM */ |
| {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_IDLE, apConn_smNop}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_IDLE, apConn_smNop}, /* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_IDLE, apConn_smUnexpected} /* STOP */ |
| }, |
| /* next state and actions for WAIT_ROAM state */ |
| { {AP_CONNECT_STATE_WAIT_CONNECT_CMD,apConn_configureDriverBeforeRoaming},/* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected}, /* FINISHED_OK */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected}, /* START */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected}, /* START_ROAM */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smNop}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected}, /* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP */ |
| }, |
| /* next state and actions for SWITCHING_CHANNEL state */ |
| { {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected}, /* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected}, /* FINISHED_OK */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected}, /* START */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected}, /* START_ROAM */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_swChFinished}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_smNop}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected}, /* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP */ |
| }, |
| /* next state and actions for WAIT_CONNECT_CMD state */ |
| { {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected}, /* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected}, /* FINISHED_OK */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_WAIT_ROAM, apConn_retainAP}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected}, /* START */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_requestCCKM}, /* START_ROAM */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected}, /* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP */ |
| }, |
| /* next state and actions for PREPARE_HAND_OFF state */ |
| { {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* FINISHED_OK */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* START */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* START_ROAM */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_CONNECTING, apConn_invokeConnectionToNewAp},/* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP */ |
| }, |
| /* next state and actions for CONNECTING state */ |
| { {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected}, /* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_REESTABLISH_VOICE,apConn_handleTspecReneg},/* FINISHED_OK */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_reportConnFail}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected}, /* START */ |
| {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected}, /* START_ROAM */ |
| {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected}, /* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP */ |
| }, |
| /* next state and actions for DISCONNECTING state */ |
| { {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop}, /* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_IDLE, apConn_reportDisconnected}, /* FINISHED_OK */ |
| {AP_CONNECT_STATE_IDLE, apConn_reportDisconnected}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_smUnexpected}, /* START */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop}, /* START_ROAM */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop}, /* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop}, /* STOP */ |
| }, |
| /* next state and actions for REESTABLISH_VOICE state */ |
| { {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected}, /* PREPARE_FOR_ROAMING */ |
| {AP_CONNECT_STATE_WAIT_ROAM,apConn_connectedToNewAP}, /* FINISHED_OK */ |
| {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_reportConnFail}, /* FINISHED_NOT_OK */ |
| {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected}, /* RETAIN_CURRENT_AP */ |
| {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected}, /* START */ |
| {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected}, /* START_ROAM */ |
| {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected}, /* START_SWITCH_CHANNEL */ |
| {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected}, /* FINISHED_SWITCH_CH */ |
| {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected}, /* FINISHED_HAND_OVER */ |
| {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP */ |
| } |
| }; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| status = fsm_Config(pAPConnection->apConnSM, |
| (fsm_Matrix_t)&apConn_matrix[0][0], |
| AP_CONNECT_NUM_STATES, |
| AP_CONNECT_NUM_EVENTS, |
| (fsm_eventActivation_t)apConn_smEvent, |
| pAPConnection->hOs); |
| |
| |
| if (status == OK) |
| { |
| pAPConnection->currentState = AP_CONNECT_STATE_IDLE; |
| pAPConnection->firstAttempt2Roam = TRUE; |
| pAPConnection->hReport = hReport; |
| pAPConnection->hCurrBSS = hCurrAP; |
| pAPConnection->hRoamMng = hRoamMng; |
| pAPConnection->hSme = hSme; |
| pAPConnection->hSiteMgr = hSiteMgr; |
| pAPConnection->hExcMngr = hExcMngr; |
| pAPConnection->hConnSm = hConnSm; |
| pAPConnection->hPrivacy = hPrivacy; |
| pAPConnection->hQos = hQos; |
| pAPConnection->hRateAdapt = ((ctrlData_t *)hCtrl)->pRateAdaptation; |
| pAPConnection->hEvHandler = hEvHandler; |
| pAPConnection->hScr = hScr; |
| pAPConnection->hAssoc = hAssoc; |
| pAPConnection->hRegulatoryDomain = hRegulatoryDomain; |
| |
| pAPConnection->roamingEnabled = TRUE; |
| pAPConnection->reportStatusCallb = NULL; |
| pAPConnection->roamEventCallb = NULL; |
| pAPConnection->returnNeighborApsCallb = NULL; |
| pAPConnection->ignoreDeauthReason0 = pApConnParams->ignoreDeauthReason0; |
| |
| for (index=ROAMING_TRIGGER_NONE; index<ROAMING_TRIGGER_LAST; index++) |
| { |
| pAPConnection->roamingTriggerEvents[index] = 0; |
| } |
| pAPConnection->roamingSuccesfulHandoverNum = 0; |
| pAPConnection->roamingSuccesfulHandoverTotalNum = 0; |
| pAPConnection->roamingFailedHandoverNum = 0; |
| pAPConnection->retainCurrAPNum = 0; |
| pAPConnection->disconnectFromRoamMngrNum = 0; |
| pAPConnection->stopFromSmeNum = 0; |
| pAPConnection->txFailureThreshold = NO_ACK_DEFAULT_THRESHOLD; |
| pAPConnection->lowRateThreshold = LOW_RATE_DEFAULT_THRESHOLD; |
| pAPConnection->rssiThreshold = RSSI_DEFAULT_THRESHOLD; |
| pAPConnection->snrThreshold = SNR_DEFAULT_THRESHOLD; |
| pAPConnection->vsIElength = 0; |
| pAPConnection->isRssiTriggerMaskedOut = FALSE; |
| pAPConnection->isSnrTriggerMaskedOut = TRUE; |
| pAPConnection->islowRateTriggerMaskedOut = FALSE; |
| pAPConnection->isConsTxFailureMaskedOut = FALSE; |
| pAPConnection->removeKeys = TRUE; |
| pAPConnection->sendDeauthPacket = TRUE; /* Default behavior is radio On - send DISASSOC frame */ |
| pAPConnection->voiceTspecConfigured = FALSE; |
| pAPConnection->videoTspecConfigured = FALSE; |
| pAPConnection->resetReportedRoamingStatistics = FALSE; |
| pAPConnection->reNegotiateTSPEC = FALSE; |
| pAPConnection->bNonRoamingDisAssocReason = FALSE; |
| |
| pAPConnection->roamingStartedTimestamp = 0; |
| pAPConnection->lastRoamingDelay = 0; |
| pAPConnection->roamingSuccesfulHandoverNum = 0; |
| |
| return OK; |
| } |
| else/* Unable to configure State Machine */ |
| { |
| WLAN_REPORT_ERROR(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("FATAL ERROR: apConn_config(): Failed to configure sm\n")); |
| return status; |
| } |
| } |
| |
| |
| /** |
| * |
| * apConn_isPsRequiredBeforeScan |
| * |
| * \b Description: |
| * |
| * verify if the PS required before scan according if roaming triger is part of ROAMING_TRIGGER_LOW_QUALITY_GROUP |
| * |
| * \b ARGS: |
| * |
| * I - hAPConnection - pointer to module\n |
| * |
| * \b RETURNS: |
| * |
| * TRUE or FALSE. |
| * |
| * \sa |
| */ |
| BOOLEAN apConn_isPsRequiredBeforeScan(TI_HANDLE hAPConnection) |
| { |
| apConn_t * pAPConnection = (apConn_t *) hAPConnection; |
| |
| /* check if part of ROAMING_TRIGGER_LOW_QUALITY_GROUP */ |
| if (pAPConnection->roamReason <= ROAMING_TRIGGER_MAX_TX_RETRIES) |
| return TRUE; |
| else |
| return FALSE; |
| } |
| |
| /** |
| * |
| * apConn_ConnCompleteInd |
| * |
| * \b Description: |
| * |
| * Inform AP Connection about successful / unsuccessful completion |
| * of link establishing |
| * |
| * \b ARGS: |
| * |
| * I - result - OK if successfully connected, NOK otherwise \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_ConnCompleteInd(TI_HANDLE hAPConnection, mgmtStatus_e status, UINT32 uStatusCode) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| if (status == STATUS_SUCCESSFUL) |
| { |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection); |
| } |
| else |
| { |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection); |
| } |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_getRoamThresholds |
| * |
| * \b Description: |
| * |
| * Used to query for the current roaming thresholds configuration |
| * |
| * \b ARGS: |
| * |
| * I - hAPConnection - pointer to module\n |
| * O - pParam - pointer to buffer to store the thresholds\n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_getRoamThresholds(TI_HANDLE hAPConnection, roamingMngrThresholdsConfig_t *pParam) |
| { |
| apConn_t * pAPConnection = (apConn_t *) hAPConnection; |
| |
| pParam->lowRssiThreshold = pAPConnection->rssiThreshold; |
| pParam->lowSnrThreshold = pAPConnection->snrThreshold; |
| pParam->txRateThreshold = pAPConnection->lowRateThreshold; |
| pParam->dataRetryThreshold = pAPConnection->txFailureThreshold; |
| |
| currBSS_getRoamingParams(pAPConnection->hCurrBSS, |
| &pParam->numExpectedTbttForBSSLoss, |
| &pParam->lowQualityForBackgroungScanCondition, |
| &pParam->normalQualityForBackgroungScanCondition, |
| &pParam->rssiFilterWeight, |
| &pParam->snrFilterWeight); |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_setRoamThresholds |
| * |
| * \b Description: |
| * |
| * Used to configure roaming thresholds |
| * |
| * \b ARGS: |
| * |
| * I - pParam - pointer to type and details of configuration request\n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_setRoamThresholds(TI_HANDLE hAPConnection, roamingMngrThresholdsConfig_t *pParam) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| /* If low quality trigger threshold is set to 0 - this is the request to ignore this trigger */ |
| /* Otherwise store it */ |
| if (pParam->lowRssiThreshold == (INT8)AP_CONNECT_TRIGGER_IGNORED) |
| { |
| pAPConnection->isRssiTriggerMaskedOut = TRUE; |
| pParam->lowRssiThreshold = pAPConnection->rssiThreshold; |
| } |
| else |
| { |
| pAPConnection->isRssiTriggerMaskedOut = FALSE; |
| pAPConnection->rssiThreshold = pParam->lowRssiThreshold; |
| } |
| |
| if (pParam->txRateThreshold == AP_CONNECT_TRIGGER_IGNORED) |
| { |
| pAPConnection->islowRateTriggerMaskedOut = TRUE; |
| pParam->txRateThreshold = pAPConnection->lowRateThreshold; |
| } |
| else |
| { |
| pAPConnection->islowRateTriggerMaskedOut = FALSE; |
| pAPConnection->lowRateThreshold = pParam->txRateThreshold; |
| } |
| |
| if (pParam->dataRetryThreshold == AP_CONNECT_TRIGGER_IGNORED) |
| { |
| pAPConnection->isConsTxFailureMaskedOut = TRUE; |
| pParam->dataRetryThreshold = pAPConnection->txFailureThreshold; |
| } |
| else |
| { |
| pAPConnection->isConsTxFailureMaskedOut = FALSE; |
| pAPConnection->txFailureThreshold = pParam->dataRetryThreshold; |
| } |
| |
| if (pParam->rssiFilterWeight == (UINT8)AP_CONNECT_TRIGGER_IGNORED) |
| { |
| pParam->rssiFilterWeight = RSSI_DEFAULT_WEIGHT; |
| } |
| |
| if (pParam->snrFilterWeight == (UINT8)AP_CONNECT_TRIGGER_IGNORED) |
| { |
| pParam->snrFilterWeight = SNR_DEFAULT_WEIGHT; |
| } |
| |
| pAPConnection->isSnrTriggerMaskedOut = FALSE; |
| pAPConnection->snrThreshold = pParam->lowSnrThreshold; |
| |
| currBSS_updateRoamingTriggers(pAPConnection->hCurrBSS, pParam); |
| |
| rateAdaptation_configLowRateThrsh(pAPConnection->hRateAdapt,pParam->txRateThreshold); |
| |
| return OK; |
| } |
| |
| /** |
| * |
| * apConn_registerRoamMngrCallb |
| * |
| * \b Description: |
| * |
| * Used to store method of Roaming Manager in the internal database of AP Connection Module. |
| * If this function was never called, any roaming event would cause disconnect. |
| * |
| * \b ARGS: |
| * |
| * I - callbackType - type of callback \n |
| * I - callbackFunction - pointer to callback \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_registerRoamMngrCallb(TI_HANDLE hAPConnection, |
| apConn_roamMngrCallb_t roamEventCallb, |
| apConn_roamMngrCallb_t reportStatusCallb, |
| apConn_roamMngrCallb_t returnNeighborApsCallb) |
| { |
| apConn_t *pAPConnection; |
| apConn_connStatus_t reportStatus; |
| paramInfo_t param; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pAPConnection = (apConn_t *)hAPConnection; |
| |
| pAPConnection->roamEventCallb = roamEventCallb; |
| pAPConnection->reportStatusCallb = reportStatusCallb; |
| if ((pAPConnection->roamingEnabled) && (pAPConnection->currentState != AP_CONNECT_STATE_IDLE)) |
| { |
| param.paramType = ASSOC_ASSOCIATION_RESP_PARAM; |
| |
| assoc_getParam(pAPConnection->hAssoc, ¶m); |
| reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer); |
| reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize; |
| |
| reportStatus.status = CONN_STATUS_CONNECTED; |
| reportStatusCallb(pAPConnection->hRoamMng, &reportStatus); |
| } |
| ((apConn_t *)hAPConnection)->returnNeighborApsCallb = returnNeighborApsCallb; |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_unregisterRoamMngrCallb |
| * |
| * \b Description: |
| * |
| * Used to Erase methods of Roaming Manager from the internal database of AP Connection |
| * module. From the moment this function was called, any roaming event would cause disconnect. |
| * |
| * \b ARGS: |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_unregisterRoamMngrCallb(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pAPConnection = (apConn_t *)hAPConnection; |
| |
| pAPConnection->roamEventCallb = NULL; |
| pAPConnection->reportStatusCallb = NULL; |
| pAPConnection->returnNeighborApsCallb = NULL; |
| |
| if ((pAPConnection->currentState != AP_CONNECT_STATE_IDLE) && (pAPConnection->currentState != AP_CONNECT_STATE_WAIT_ROAM)) |
| { |
| /* Roaming Manager is unregistering it's callbacks in the middle of roaming - disconnect */ |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection); |
| } |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_disconnect |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function when it fails to find candidate for roaming from |
| * one hand, and the connection with current AP is not possible from another. |
| * |
| * \b ARGS: |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_disconnect(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pAPConnection = (apConn_t *)hAPConnection; |
| |
| UPDATE_SEND_DEAUTH_PACKET_FLAG(pAPConnection->roamReason); |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection); |
| pAPConnection->disconnectFromRoamMngrNum++; |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_getStaCapabilities |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function during selection of new candidate for roaming. |
| * Returned are local Station capabilities (IEs) of quality and privacy, needed to |
| * evaluate AP sites as suitable for roaming. |
| * |
| * \b ARGS: |
| * |
| * O - ie_list - station capabilities \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_getStaCapabilities(TI_HANDLE hAPConnection, |
| apConn_staCapabilities_t *ie_list) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| apConn_staCapabilities_t *pList; |
| paramInfo_t param; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pList = ie_list; |
| |
| /* Get authentication suite type */ |
| param.paramType = RSN_EXT_AUTHENTICATION_MODE; |
| rsn_getParam(pAPConnection->hPrivacy, ¶m); |
| |
| switch (param.content.rsnExtAuthneticationMode) |
| { |
| case RSN_EXT_AUTH_MODE_OPEN: |
| pList->authMode = os802_11AuthModeOpen; |
| break; |
| case RSN_EXT_AUTH_MODE_SHARED_KEY: |
| pList->authMode = os802_11AuthModeShared; |
| break; |
| case RSN_EXT_AUTH_MODE_AUTO_SWITCH: |
| pList->authMode = os802_11AuthModeAutoSwitch; |
| break; |
| case RSN_EXT_AUTH_MODE_WPA: |
| pList->authMode = os802_11AuthModeWPA; |
| break; |
| case RSN_EXT_AUTH_MODE_WPAPSK: |
| pList->authMode = os802_11AuthModeWPAPSK; |
| break; |
| case RSN_EXT_AUTH_MODE_WPANONE: |
| pList->authMode = os802_11AuthModeWPANone; |
| break; |
| case RSN_EXT_AUTH_MODE_WPA2: |
| pList->authMode = os802_11AuthModeWPA2; |
| break; |
| case RSN_EXT_AUTH_MODE_WPA2PSK: |
| pList->authMode = os802_11AuthModeWPA2PSK; |
| break; |
| default: |
| pList->authMode = os802_11AuthModeOpen; |
| break; |
| } |
| |
| /* Get encryption type */ |
| param.paramType = RSN_ENCRYPTION_STATUS_PARAM; |
| rsn_getParam(pAPConnection->hPrivacy, ¶m); |
| |
| switch (param.content.rsnEncryptionStatus) |
| { |
| case RSN_CIPHER_NONE: |
| pList->encryptionType = OS_ENCRYPTION_TYPE_NONE; |
| break; |
| case RSN_CIPHER_WEP: |
| case RSN_CIPHER_WEP104: |
| pList->encryptionType = OS_ENCRYPTION_TYPE_WEP; |
| break; |
| case RSN_CIPHER_TKIP: |
| case RSN_CIPHER_CKIP: |
| pList->encryptionType = OS_ENCRYPTION_TYPE_TKIP; |
| break; |
| case RSN_CIPHER_AES_WRAP: |
| case RSN_CIPHER_AES_CCMP: |
| pList->encryptionType = OS_ENCRYPTION_TYPE_AES; |
| break; |
| default: |
| pList->encryptionType = OS_ENCRYPTION_TYPE_NONE; |
| break; |
| } |
| |
| /* Get supported rates */ |
| param.paramType = SITE_MGR_DESIRED_SUPPORTED_RATE_SET_PARAM; |
| siteMgr_getParam(pAPConnection->hSiteMgr, ¶m); |
| os_memoryCopy(pAPConnection->hOs, (void *)param.content.siteMgrDesiredSupportedRateSet.ratesString, pList->rateMask, sizeof(OS_802_11_RATES_EX)); |
| |
| /* Get mode: 2.4G, 5G or Dual */ |
| param.paramType = SITE_MGR_DESIRED_DOT11_MODE_PARAM; |
| siteMgr_getParam(pAPConnection->hSiteMgr, ¶m); |
| pList->networkType = (OS_802_11_NETWORK_TYPE)param.content.siteMgrDot11Mode; |
| switch(param.content.siteMgrDot11Mode) |
| { |
| case DOT11_B_MODE: |
| pList->networkType = os802_11DS; |
| break; |
| case DOT11_A_MODE: |
| pList->networkType = os802_11OFDM5; |
| break; |
| case DOT11_G_MODE: |
| pList->networkType = os802_11OFDM24; |
| break; |
| case DOT11_DUAL_MODE: |
| pList->networkType = os802_11Automode; |
| break; |
| default: |
| pList->networkType = os802_11DS; |
| break; |
| } |
| |
| |
| /* Get EXC status */ |
| #ifdef EXC_MODULE_INCLUDED |
| param.paramType = EXC_ENABLED; |
| excMngr_getParam(pAPConnection->hExcMngr, ¶m); |
| pList->excEnabled = (param.content.excEnabled==EXC_MODE_ENABLED)? TRUE : FALSE; |
| #else |
| pList->excEnabled = FALSE; |
| #endif |
| |
| /* Get QoS type */ |
| param.paramType = QOS_MNGR_ACTIVE_PROTOCOL; |
| qosMngr_getParams(pAPConnection->hQos, ¶m); |
| pList->qosEnabled = (param.content.qosSiteProtocol==NONE_QOS)? FALSE : TRUE; |
| |
| pList->regDomain = REG_DOMAIN_FIXED; |
| /* Get regulatory domain type */ |
| param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; |
| regulatoryDomain_getParam(pAPConnection->hRegulatoryDomain, ¶m); |
| if (param.content.spectrumManagementEnabled) |
| { /* 802.11h is enabled (802.11h includes 802.11d) */ |
| pList->regDomain = REG_DOMAIN_80211H; |
| } |
| else |
| { |
| param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM; |
| regulatoryDomain_getParam(pAPConnection->hRegulatoryDomain, ¶m); |
| if (param.content.regulatoryDomainEnabled) |
| { /* 802.11d is enabled */ |
| pList->regDomain = REG_DOMAIN_80211D; |
| } |
| } |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_connectToAP |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function when it has completed the process of selection |
| * of new AP candidate for roaming. In addition, Roaming manager informs AP Connection |
| * module whether this is new AP or the current one, and whether to perform full |
| * roaming procedure or just to retain to current AP. |
| * |
| * \b ARGS: |
| * |
| * I - requestType - Connect to new AP, current AP (retain to current AP or re-connect) \n |
| * I - newAP - Pointer to parameters list of AP candidate for roaming \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_connectToAP(TI_HANDLE hAPConnection, |
| bssEntry_t *newAP, |
| apConn_connRequest_t *request, |
| BOOL reNegotiateTspec) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pAPConnection->requestType = request->requestType; |
| |
| switch (request->requestType) |
| { |
| case AP_CONNECT_RETAIN_CURR_AP: |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_RETAIN_CURRENT_AP, pAPConnection); |
| break; |
| |
| case AP_CONNECT_FULL_TO_AP: |
| pAPConnection->removeKeys = TRUE; |
| pAPConnection->newAP = newAP; |
| pAPConnection->roamingFailedHandoverNum++; |
| pAPConnection->reNegotiateTSPEC = reNegotiateTspec; |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_ROAM, pAPConnection); |
| break; |
| |
| case AP_CONNECT_FAST_TO_AP: |
| case AP_CONNECT_RECONNECT_CURR_AP: |
| pAPConnection->removeKeys = FALSE; |
| pAPConnection->newAP = newAP; |
| pAPConnection->roamingFailedHandoverNum++; |
| pAPConnection->reNegotiateTSPEC = reNegotiateTspec; |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_ROAM, pAPConnection); |
| break; |
| |
| default: |
| break; |
| } |
| |
| /* If there is vendor specific IE to attach to Assoc req, store it now */ |
| if (request->dataBufLength > 0) |
| { |
| pAPConnection->vsIEbuf = request->dataBuf; |
| pAPConnection->vsIElength = request->dataBufLength; |
| } |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_getBSSParams |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function in order to evaluate the quality of new |
| * AP candidates for roaming against the quality of current AP. |
| * The function returns parameters of current AP. |
| * |
| * \b ARGS: |
| * |
| * O - currentAP - Pointer to parameters list of current AP \n |
| * |
| * \b RETURNS: |
| * |
| * Pointer to current BSS parameters database if successful, NULL otherwise. |
| * |
| * \sa |
| */ |
| bssEntry_t *apConn_getBSSParams(TI_HANDLE hAPConnection) |
| { |
| #ifdef TI_DBG |
| if (hAPConnection == NULL) /* Failed to allocate control block */ |
| { |
| WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n")); |
| return NULL; |
| } |
| #endif |
| |
| return currBSS_getBssInfo(((apConn_t *)hAPConnection)->hCurrBSS); |
| } |
| |
| |
| /** |
| * |
| * apConn_isSiteBanned |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function during selection of new candidate for roaming. |
| * Only APs which are not marked as banned are allowed to be selected. |
| * |
| * \b ARGS: |
| * |
| * O - givenAp - Pointer to BSSID to check if banned \n |
| * |
| * \b RETURNS: |
| * |
| * TRUE if banned, FALSE otherwise. |
| * |
| * \sa |
| */ |
| BOOL apConn_isSiteBanned(TI_HANDLE hAPConnection, macAddress_t * givenAp) |
| { |
| apConn_t * pAPConnection = (apConn_t *) hAPConnection; |
| |
| return rsn_isSiteBanned(pAPConnection->hPrivacy, *givenAp); |
| } |
| |
| |
| /** |
| * |
| * apConn_getPreAuthAPStatus |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function during selection of new candidate for roaming. |
| * Among all APs with good quality, those who were pre-authenticated are preferred. |
| * |
| * \b ARGS: |
| * |
| * O - givenAp - Pointer to BSSID to check the pre-authenticated status for \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| BOOL apConn_getPreAuthAPStatus(TI_HANDLE hAPConnection, |
| macAddress_t *givenAp) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| paramInfoPartial_t param; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| param.paramType = RSN_PRE_AUTH_STATUS; |
| os_memoryCopy(pAPConnection->hOs, (void *)param.content.rsnApMac.addr, (void *)givenAp->addr, MAC_ADDR_LEN); |
| rsn_getParamPartial(pAPConnection->hPrivacy, ¶m); |
| |
| return param.content.rsnPreAuthStatus; |
| } |
| |
| |
| /** |
| * |
| * apConn_preAuthenticate |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function periodically in order to update the list |
| * of pre-authenticated APs. The list is managed by WLAN driver and required |
| * by Roaming Manager during selection of roaming candidate process. |
| * |
| * \b ARGS: |
| * |
| * I - listAPs - List of APs to pre-authenticate \n |
| * I - sizeOfList - Size of list of APs to pre-authenticate \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_preAuthenticate(TI_HANDLE hAPConnection, bssList_t *listAPs, UINT8 listAPs_numOfEntries) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| bssidList4PreAuth_t apList; |
| UINT32 listIndex, apListIndex; |
| bssEntry_t *pCurrentAP; |
| UINT8 *pRsnIEs; |
| |
| #ifdef TI_DBG |
| if ((hAPConnection == NULL) || (listAPs == NULL)) |
| { |
| WLAN_OS_REPORT(("FATAL ERROR: AP Connection context is not initiated\n")); |
| return NOK; |
| } |
| |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, SITE_MGR_MODULE_LOG, ("apConn_reserveResources \n")); |
| #endif |
| |
| if (listAPs_numOfEntries != 0) { |
| for (listIndex=0, apListIndex=0; listIndex<listAPs->numOfEntries; listIndex++) |
| { |
| os_memoryCopy(pAPConnection->hOs, &(apList.bssidList[apListIndex].bssId), |
| (void *)listAPs->BSSList[listIndex].BSSID.addr, MAC_ADDR_LEN); |
| |
| /* search in the buffer pointer to the beginning of the |
| RSN IE according to the IE ID */ |
| if (!parseIeBuffer(pAPConnection->hOs, listAPs->BSSList[listIndex].pBuffer, listAPs->BSSList[listIndex].bufferLength, RSN_IE_ID, &pRsnIEs, NULL, 0)) |
| { |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("apConn_preAuthenticate, no RSN IE was found \n")); |
| WLAN_REPORT_HEX_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| listAPs->BSSList[listIndex].pBuffer, listAPs->BSSList[listIndex].bufferLength); |
| |
| continue; |
| } |
| |
| apList.bssidList[apListIndex].pRsnIEs = (dot11_RSN_t*)pRsnIEs; |
| apList.bssidList[apListIndex].rsnIeLen = apList.bssidList[apListIndex].pRsnIEs->hdr.eleLen+2; |
| apListIndex++; |
| } |
| } |
| else |
| { |
| listIndex=0; |
| apListIndex=0; |
| } |
| |
| /* Start pre-auth after any Conn succ (including first), |
| and not only when a New BSSID was added, in order to save/refresh |
| PMKID of the current AP.*/ |
| { |
| /* Add the current BSSID to the list */ |
| pCurrentAP = apConn_getBSSParams(pAPConnection); |
| os_memoryCopy(pAPConnection->hOs, &(apList.bssidList[apListIndex].bssId), |
| (void *)pCurrentAP->BSSID.addr, MAC_ADDR_LEN); |
| /* search in the buffer pointer to the beginning of the |
| RSN IE according to the IE ID */ |
| |
| if (!parseIeBuffer(pAPConnection->hOs, pCurrentAP->pBuffer, pCurrentAP->bufferLength, RSN_IE_ID, &pRsnIEs, NULL, 0)) |
| { |
| WLAN_REPORT_ERROR(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("apConn_preAuthenticate, no RSN IE was found in the current BSS, BSSID=0x%x-0x%x-0x%x-0x%x-0x%x-0x%x \n", |
| pCurrentAP->BSSID.addr[0], pCurrentAP->BSSID.addr[1], pCurrentAP->BSSID.addr[2], |
| pCurrentAP->BSSID.addr[3], pCurrentAP->BSSID.addr[4], pCurrentAP->BSSID.addr[5])); |
| HexDumpData(pCurrentAP->pBuffer, pCurrentAP->bufferLength); |
| apList.bssidList[apListIndex].pRsnIEs = NULL; |
| apList.bssidList[apListIndex].rsnIeLen = 0; |
| } |
| else |
| { |
| apList.bssidList[apListIndex].pRsnIEs = (dot11_RSN_t*)pRsnIEs; |
| apList.bssidList[apListIndex].rsnIeLen = apList.bssidList[apListIndex].pRsnIEs->hdr.eleLen+2; |
| } |
| apList.NumOfItems = apListIndex+1; |
| rsn_startPreAuth(pAPConnection->hPrivacy, &apList); |
| } |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_prepareToRoaming |
| * |
| * \b Description: |
| * |
| * Roaming Manager calls this function when roaming event is received and Roaming Manager |
| * wishes to start the roaming process, thus want to prevent scan and measurement in the |
| * system. The function will return OK if the allocation is performed, PEND if the |
| * allocation is started, NOK in case the allocation is not possible. |
| * In case of successful allocation, Roaming Manager will be informed via callback about |
| * the end of the allocation. |
| * |
| * \b ARGS: |
| * |
| * I - reason - the reason for roaming \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_prepareToRoaming(TI_HANDLE hAPConnection, apConn_roamingTrigger_e reason) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pAPConnection->roamReason = reason; |
| |
| return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_PREPARE_FOR_ROAMING, pAPConnection); |
| } |
| |
| /** |
| * |
| * apConn_indicateSwitchChannelInProgress |
| * |
| * \b Description: |
| * |
| * This function is called when switch channel process is started; it will trigger |
| * AP Connection state machine from 'Wait for roaming start' to 'Switch channel in progress' |
| * state. |
| * |
| * \b ARGS: |
| * |
| * I - reason - the reason for roaming \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_indicateSwitchChannelInProgress(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_SWITCH_CHANNEL, pAPConnection); |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_indicateSwitchChannelFinished |
| * |
| * \b Description: |
| * |
| * This function is called when switch channel process is finished |
| * |
| * \b ARGS: |
| * |
| * I - reason - the reason for roaming \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_indicateSwitchChannelFinished(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_SWITCH_CH, pAPConnection); |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_start |
| * |
| * \b Description: |
| * |
| * Called by SME module when new connection has been successfully established (first time connection) |
| * |
| * \b ARGS: |
| * |
| * I - isValidBSS - if FALSE, no roaming shall be performed, disconnect upon any roaming event; |
| * other parameters of current AP can be received from Current BSS module |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_start(TI_HANDLE hAPConnection, BOOLEAN roamingEnabled) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| pAPConnection->roamingEnabled = roamingEnabled; |
| |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START, pAPConnection); |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_stop |
| * |
| * \b Description: |
| * |
| * Called by SME module when current connection must be taken down |
| * (due to driver download, connection failure or any other reason) |
| * |
| * \b ARGS: |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_stop(TI_HANDLE hAPConnection, BOOLEAN removeKeys, BOOLEAN immediateShutdown) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| pAPConnection->stopFromSmeNum++; |
| pAPConnection->removeKeys = removeKeys; |
| pAPConnection->sendDeauthPacket = !(immediateShutdown); /* If immediateShutdown is TRUE, no need to send DISASSOC frame - used during unload process */ |
| pAPConnection->reNegotiateTSPEC = FALSE; |
| pAPConnection->voiceTspecConfigured = FALSE; |
| pAPConnection->videoTspecConfigured = FALSE; |
| |
| /* Mark that the connection is stopped due to reason outside the scope of this module */ |
| pAPConnection->bNonRoamingDisAssocReason = TRUE; |
| |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection); |
| return OK; |
| } |
| |
| /** |
| * |
| * apConn_reportRoamingEventDisconnect |
| * |
| * \b Description: |
| * |
| * Called by Roaming Manager to inform of Disconnect |
| * uStatusCode - status code of deauth/disassoc packet |
| * bDeAuthenticate - Whether this packet is DeAuth ( if |
| * DisAssoc than FALSE) |
| * |
| * \b ARGS: |
| * |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_reportRoamingEventDisconnect(TI_HANDLE hAPConnection,UINT16 uStatusCode,BOOLEAN bDeAuthenticate ) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| roamingEventData_u RoamingEventData; |
| |
| RoamingEventData.APDisconnect.uStatusCode = uStatusCode ; /* status code of deauth/disassoc packet */ |
| RoamingEventData.APDisconnect.bDeAuthenticate = bDeAuthenticate; /* TRUE state that it is DeAuth packet */ |
| apConn_reportRoamingEvent(pAPConnection, ROAMING_TRIGGER_AP_DISCONNECT, &RoamingEventData); |
| return( TI_OK ); |
| } |
| |
| |
| /** |
| * |
| * apConn_reportRoamingEvent |
| * |
| * \b Description: |
| * |
| * Called when one of roaming events occur |
| * |
| * \b ARGS: |
| * |
| * I - roamingEventType |
| * I - pRoamingEventData - in case of 'Tx rate' event, or AP disconnect |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_reportRoamingEvent(TI_HANDLE hAPConnection, |
| apConn_roamingTrigger_e roamingEventType, |
| roamingEventData_u *pRoamingEventData) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| paramInfo_t param; /* parameter for retrieving BSSID */ |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("apConn_reportRoamingEvent, type=%d, cur_state=%d, roamingEnabled=%d, roamEventCallb=%p \n", |
| roamingEventType, pAPConnection->currentState, |
| pAPConnection->roamingEnabled, pAPConnection->roamEventCallb)); |
| |
| /* 1. Check if this is Rogue AP test case */ |
| if (roamingEventType == ROAMING_TRIGGER_AP_DISCONNECT) |
| { |
| if (pRoamingEventData != NULL) |
| { /* Save the disconnect reason for future use */ |
| pAPConnection->APDisconnect.uStatusCode = pRoamingEventData->APDisconnect.uStatusCode; |
| pAPConnection->APDisconnect.bDeAuthenticate = pRoamingEventData->APDisconnect.bDeAuthenticate; |
| } |
| if ((pAPConnection->ignoreDeauthReason0) && (pRoamingEventData!=NULL) && |
| (pAPConnection->APDisconnect.uStatusCode == 0)) |
| { /* This is required for Rogue AP test, |
| When Rogue AP due to invalid User name, deauth with reason 0 arrives before the Rogue AP, |
| and this EXC test fails.*/ |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("apConn_reportRoamingEvent, Ignore DeAuth with reason 0 \n")); |
| return OK; |
| } |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("apConn_reportRoamingEvent, DeAuth with reason %d \n", pAPConnection->APDisconnect.uStatusCode)); |
| |
| if (pAPConnection->APDisconnect.uStatusCode == STATUS_CODE_802_1X_AUTHENTICATION_FAILED) |
| { |
| #ifdef EXC_MODULE_INCLUDED |
| TI_STATUS status; |
| |
| /* Raise the EAP-Failure as event */ |
| status = excMngr_rogueApDetected (pAPConnection->hExcMngr, RSN_AUTH_STATUS_CHALLENGE_FROM_AP_FAILED); |
| #endif |
| |
| |
| /* Remove AP from candidate list for a specified amount of time */ |
| param.paramType = SITE_MGR_CURRENT_BSSID_PARAM; |
| siteMgr_getParam(pAPConnection->hSiteMgr, ¶m); |
| |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("current station is banned from the roaming candidates list for %d Ms\n", |
| RSN_AUTH_FAILURE_TIMEOUT)); |
| |
| rsn_banSite(pAPConnection->hPrivacy, param.content.siteMgrDesiredBSSID, RSN_SITE_BAN_LEVEL_FULL, RSN_AUTH_FAILURE_TIMEOUT); |
| } |
| |
| } |
| |
| /* 2. Check if received trigger is masked out */ |
| if (((pAPConnection->isConsTxFailureMaskedOut) && (roamingEventType == ROAMING_TRIGGER_MAX_TX_RETRIES)) || |
| ((pAPConnection->isRssiTriggerMaskedOut) && (roamingEventType == ROAMING_TRIGGER_LOW_QUALITY)) || |
| ((pAPConnection->isSnrTriggerMaskedOut) && (roamingEventType == ROAMING_TRIGGER_LOW_SNR)) || |
| ((pAPConnection->islowRateTriggerMaskedOut)&& (roamingEventType == ROAMING_TRIGGER_LOW_TX_RATE))) |
| { |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("apConn_reportRoamingEvent, trigger ignored \n")); |
| return OK; |
| } |
| |
| /* 3. Valid trigger received: */ |
| /* 3a. Update statistics */ |
| pAPConnection->roamingTriggerEvents[roamingEventType]++; |
| |
| /* 3b. Store the most severe trigger */ |
| if (pAPConnection->roamReason < roamingEventType) |
| { |
| pAPConnection->roamReason = roamingEventType; |
| } |
| |
| /* 3c. Check if Roaming Manager is available */ |
| if (((!pAPConnection->roamingEnabled) || (pAPConnection->roamEventCallb == NULL) || |
| (pAPConnection->currentState == AP_CONNECT_STATE_IDLE)) |
| && (roamingEventType > ROAMING_TRIGGER_LOW_QUALITY) |
| && (roamingEventType != ROAMING_TRIGGER_MAX_TX_RETRIES)) |
| /* |
| * The last condition was added so that MAX_TX_RETRIES would not cause a disconnect. |
| * This is done because the current default value for max TX retries is good enough for |
| * roaming (i.e. it indicates a low quality AP), but would cause unnecessary disconnects |
| * if used when roaming is disabled |
| */ |
| { |
| /* 'Any SSID' configured, meaning Roaming Manager is not allowed to perform roaming, |
| or Roaming Manager is not registered for roaming events; |
| unless this is trigger to change parameters of background scan, disconnect the link */ |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("Disconnecting link due to roaming event: ev = %d\n", roamingEventType)); |
| |
| /* Handle IBSS case TBD to remove |
| Handle also the case where A first connection is in progress, and |
| de-auth arrived. */ |
| if (pAPConnection->currentState == AP_CONNECT_STATE_IDLE) |
| { |
| apConn_reportConnStatusToSME(pAPConnection); |
| } |
| else |
| { |
| /* Infra-structure BSS case - disconnect the link */ |
| if (roamingEventType >= ROAMING_TRIGGER_AP_DISCONNECT) |
| { |
| pAPConnection->removeKeys = TRUE; |
| } |
| else |
| { |
| pAPConnection->removeKeys = FALSE; |
| } |
| UPDATE_SEND_DEAUTH_PACKET_FLAG(roamingEventType); |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection); |
| } |
| return OK; |
| } |
| |
| /* 4. Check if we are in the middle of switching channel */ |
| if (pAPConnection->currentState == AP_CONNECT_STATE_SWITCHING_CHANNEL) |
| { |
| /* Trigger received in the middle of switch channel, continue without reporting Roaming Manager */ |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("Roaming event during switch channel: ev = %d\n", roamingEventType)); |
| return OK; |
| } |
| |
| /* 5. Report Roaming Manager */ |
| if ((pAPConnection->roamingEnabled == TRUE) && (pAPConnection->roamEventCallb != NULL)) |
| { |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("Roaming event raised: ev = %d\n", roamingEventType)); |
| if (roamingEventType == ROAMING_TRIGGER_LOW_QUALITY) |
| { |
| EvHandlerSendEvent(pAPConnection->hEvHandler, IPC_EVENT_LOW_RSSI, NULL,0); |
| } |
| /* Report to Roaming Manager */ |
| pAPConnection->roamEventCallb(pAPConnection->hRoamMng, &roamingEventType); |
| } |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_RoamHandoffFinished |
| * |
| * \b Description: |
| * |
| * Called when EXC module receives response from the supplicant or recognizes |
| * timeout while waiting for the response |
| * |
| * \b ARGS: |
| * |
| * \b RETURNS: |
| * |
| * \sa |
| */ |
| void apConn_RoamHandoffFinished(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| #ifdef TI_DBG |
| if (hAPConnection == NULL) /* Failed to allocate control block */ |
| { |
| WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n")); |
| return; |
| } |
| #endif |
| |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_HAND_OVER, pAPConnection); |
| } |
| |
| |
| /** |
| * |
| * apConn_DisconnCompleteInd |
| * |
| * \b Description: |
| * |
| * DISASSOCIATE Packet was sent - proceed with stopping the module |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_DisconnCompleteInd(TI_HANDLE hAPConnection, mgmtStatus_e status, UINT32 uStatusCode) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| AP_CONN_VALIDATE_HANDLE(hAPConnection); |
| |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection); |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_updateNeighborAPsList |
| * |
| * \b Description: |
| * |
| * Called by EXC Manager when Priority APs are found |
| * |
| * \b ARGS: |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| void apConn_updateNeighborAPsList(TI_HANDLE hAPConnection, neighborAPList_t *pListOfpriorityAps) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| if (pAPConnection->returnNeighborApsCallb != NULL ) |
| { |
| pAPConnection->returnNeighborApsCallb(pAPConnection->hRoamMng, pListOfpriorityAps); |
| } |
| } |
| |
| |
| /** |
| * |
| * apConn_getRoamingStatistics |
| * |
| * \b Description: |
| * |
| * Called from Measurement EXC sub-module when preparing TSM report to the AP. |
| * |
| * \b ARGS: AP Connection handle |
| * |
| * \b RETURNS: |
| * |
| * total number of successful roams |
| * delay of the latest successful roam |
| * |
| * \sa |
| */ |
| void apConn_getRoamingStatistics(TI_HANDLE hAPConnection, UINT8 *roamingCount, UINT16 *roamingDelay) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| /* Get (and clear) total number of successful roams */ |
| *roamingCount = pAPConnection->roamingSuccesfulHandoverNum; |
| pAPConnection->roamingSuccesfulHandoverNum = 0; |
| |
| /* Get delay of the latest roam */ |
| *roamingDelay = pAPConnection->lastRoamingDelay; |
| pAPConnection->lastRoamingDelay = 0; |
| } |
| |
| |
| |
| |
| /** |
| * |
| * apConn_resetRoamingStatistics |
| * |
| * \b Description: |
| * |
| * Called from Measurement EXC sub-module in order to re-start roaming statistics. |
| * |
| * \b ARGS: AP Connection handle |
| * |
| * \b RETURNS: |
| * |
| * total number of successful roams |
| * delay of the latest successful roam |
| * |
| * \sa |
| */ |
| void apConn_resetRoamingStatistics(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| pAPConnection->resetReportedRoamingStatistics = TRUE; |
| pAPConnection->roamingSuccesfulHandoverNum = 0; |
| pAPConnection->lastRoamingDelay = 0; |
| } |
| |
| |
| /** |
| * |
| * apConn_stopRoamingStatistics |
| * |
| * \b Description: |
| * |
| * Called from Measurement CCX sub-module in order to stop roaming statistics. |
| * |
| * \b ARGS: AP Connection handle |
| * |
| * \b RETURNS: |
| * |
| * \sa |
| */ |
| void apConn_stopRoamingStatistics(TI_HANDLE hAPConnection) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| pAPConnection->resetReportedRoamingStatistics = FALSE; |
| } |
| |
| |
| /** |
| * |
| * apConn_printStatistics |
| * |
| * \b Description: |
| * |
| * Called by Site Manager when request to print statistics is requested from CLI |
| * |
| * \b ARGS: AP Connection handle |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| void apConn_printStatistics(TI_HANDLE hAPConnection) |
| { |
| WLAN_OS_REPORT(("-------------- Roaming Statistics ---------------\n\n")); |
| WLAN_OS_REPORT(("- Low TX rate = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_TX_RATE])); |
| WLAN_OS_REPORT(("- Low SNR = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_SNR])); |
| WLAN_OS_REPORT(("- Low Quality = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_QUALITY])); |
| WLAN_OS_REPORT(("- MAX TX retries = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_MAX_TX_RETRIES])); |
| WLAN_OS_REPORT(("- BSS Loss TX = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_BSS_LOSS])); |
| WLAN_OS_REPORT(("- Switch Channel = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_SWITCH_CHANNEL])); |
| WLAN_OS_REPORT(("- AP Disconnect = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_AP_DISCONNECT])); |
| WLAN_OS_REPORT(("- SEC attack = %d\n", ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_SECURITY_ATTACK])); |
| WLAN_OS_REPORT(("\n")); |
| WLAN_OS_REPORT(("- Succesfull Total roaming = %d\n", ((apConn_t *)hAPConnection)->roamingSuccesfulHandoverTotalNum)); |
| WLAN_OS_REPORT(("- Unsuccesfull roaming = %d\n", ((apConn_t *)hAPConnection)->roamingFailedHandoverNum)); |
| WLAN_OS_REPORT(("- Giving up roaming = %d\n", ((apConn_t *)hAPConnection)->retainCurrAPNum)); |
| WLAN_OS_REPORT(("- Disconnect cmd from roaming manager = %d\n", ((apConn_t *)hAPConnection)->disconnectFromRoamMngrNum)); |
| WLAN_OS_REPORT(("- Disconnect cmd from SME = %d\n", ((apConn_t *)hAPConnection)->stopFromSmeNum)); |
| WLAN_OS_REPORT(("\n")); |
| } |
| |
| |
| |
| /** |
| * |
| * apConn_getVendorSpecificIE |
| * |
| * \b Description: |
| * |
| * Called by Association SM when request to associate is built and sent to AP; |
| * returns request updated with vendor specific info-element |
| * |
| * \b ARGS: |
| * |
| * I - hAPConnection - AP Connection handle\n |
| * O - pRequest - pointer to request buffer\n |
| * O - len - size of returned IE\n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * \sa |
| */ |
| TI_STATUS apConn_getVendorSpecificIE(TI_HANDLE hAPConnection, UINT8 *pRequest, UINT32 *len) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hAPConnection; |
| |
| if (pAPConnection->vsIElength > 0) |
| { |
| *len = pAPConnection->vsIElength; |
| os_memoryCopy(pAPConnection->hOs, pRequest, pAPConnection->vsIEbuf, pAPConnection->vsIElength); |
| } |
| else |
| { |
| *len = 0; |
| } |
| return OK; |
| } |
| |
| |
| /* Internal functions implementation */ |
| |
| |
| /** |
| * |
| * apConn_smEvent |
| * |
| * \b Description: |
| * |
| * AP Connection state machine transition function |
| * |
| * \b ARGS: |
| * |
| * I/O - currentState - current state in the state machine\n |
| * I - event - specific event for the state machine\n |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_smEvent(apConn_smStates *currState, UINT8 event, void* data) |
| { |
| TI_STATUS status; |
| UINT8 nextState; |
| apConn_t *pAPConnection; |
| |
| pAPConnection = (apConn_t *)data; |
| status = fsm_GetNextState(pAPConnection->apConnSM, (UINT8)*currState, event, &nextState); |
| if (status == OK) |
| { |
| WLAN_REPORT_SM(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("<%s, %s> --> %s\n\n", |
| apConn_stateDesc[*currState], |
| apConn_eventDesc[event], |
| apConn_stateDesc[nextState])); |
| |
| status = fsm_Event(pAPConnection->apConnSM, (UINT8 *)currState, event, pAPConnection); |
| return status; |
| } |
| else |
| { |
| WLAN_REPORT_ERROR(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("apConn_smEvent, fsm_GetNextState error\n")); |
| return status; |
| } |
| } |
| |
| |
| /** |
| * |
| * apConn_smNop - Do nothing |
| * |
| * \b Description: |
| * |
| * Do nothing in the SM. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * |
| */ |
| static TI_STATUS apConn_smNop(void *pData) |
| { |
| WLAN_REPORT_INFORMATION((((apConn_t *)pData)->hReport), ROAMING_MANAGER_MODULE_LOG, ("apConn_smNop\n")); |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_smUnexpected - Unexpected event |
| * |
| * \b Description: |
| * |
| * Unexpected event in the SM. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context \n |
| * |
| * \b RETURNS: |
| * |
| * OK if successful, NOK otherwise. |
| * |
| * |
| */ |
| static TI_STATUS apConn_smUnexpected(void *pData) |
| { |
| WLAN_REPORT_INFORMATION(((apConn_t *)pData)->hReport, ROAMING_MANAGER_MODULE_LOG, ("apConn_smUnexpected\n")); |
| return NOK; |
| } |
| |
| |
| /** |
| * |
| * apConn_startWaitingForTriggers |
| * |
| * \b Description: |
| * |
| * SME informs AP Connection module about successfull link establishment; start wiating for roaming triggers |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context \n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_startWaitingForTriggers(void *pData) |
| { |
| apConn_t *pAPConnection; |
| apConn_connStatus_t reportStatus; |
| paramInfoPartial_t param; |
| |
| pAPConnection = (apConn_t *)pData; |
| |
| if ((pAPConnection->roamingEnabled) && (pAPConnection->reportStatusCallb != NULL)) |
| { |
| param.paramType = ASSOC_ASSOCIATION_RESP_PARAM; |
| |
| assoc_getParamPartial(pAPConnection->hAssoc, ¶m); |
| reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer); |
| reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize; |
| |
| reportStatus.status = CONN_STATUS_CONNECTED; |
| pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus); |
| } |
| pAPConnection->firstAttempt2Roam = TRUE; |
| pAPConnection->roamReason = ROAMING_TRIGGER_NONE; |
| pAPConnection->removeKeys = TRUE; |
| pAPConnection->sendDeauthPacket = TRUE; |
| pAPConnection->reNegotiateTSPEC = FALSE; |
| pAPConnection->voiceTspecConfigured = FALSE; |
| pAPConnection->videoTspecConfigured = FALSE; |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_connectedToNewAP |
| * |
| * \b Description: |
| * |
| * After roaming was requested, Connection SM informs AP Connection module about |
| * successful link re-establishment; start waiting for roaming triggers |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context \n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_connectedToNewAP(void *pData) |
| { |
| apConn_t *pAPConnection; |
| apConn_connStatus_t reportStatus; |
| paramInfoPartial_t param; |
| |
| pAPConnection = (apConn_t *)pData; |
| |
| /* Configure SCR group back to connection */ |
| scr_setGroup (pAPConnection->hScr, SCR_GID_CONNECTED); |
| |
| /* Erase vendor specific info-element if was defined for last AP Assoc request */ |
| pAPConnection->vsIElength = 0; |
| |
| /* TBD Notify Curr BSS module about update of current AP database */ |
| |
| if (pAPConnection->roamingFailedHandoverNum>0) |
| { |
| pAPConnection->roamingFailedHandoverNum--; |
| } |
| /* Report Roaming Manager */ |
| if (pAPConnection->reportStatusCallb != NULL) |
| { |
| param.paramType = ASSOC_ASSOCIATION_RESP_PARAM; |
| |
| assoc_getParamPartial(pAPConnection->hAssoc, ¶m); |
| reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer); |
| reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize; |
| |
| reportStatus.status = CONN_STATUS_HANDOVER_SUCCESS; |
| |
| pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus); |
| } |
| pAPConnection->firstAttempt2Roam = TRUE; |
| pAPConnection->roamReason = ROAMING_TRIGGER_NONE; |
| pAPConnection->roamingSuccesfulHandoverTotalNum++; |
| pAPConnection->removeKeys = TRUE; |
| pAPConnection->sendDeauthPacket = TRUE; |
| pAPConnection->reNegotiateTSPEC = FALSE; |
| pAPConnection->voiceTspecConfigured = FALSE; |
| pAPConnection->videoTspecConfigured = FALSE; |
| |
| |
| if (!pAPConnection->resetReportedRoamingStatistics) |
| { |
| pAPConnection->roamingSuccesfulHandoverNum++; |
| pAPConnection->lastRoamingDelay = |
| (UINT16)os_timeStampMs(pAPConnection->hOs) - pAPConnection->roamingStartedTimestamp; |
| } |
| else |
| { |
| pAPConnection->resetReportedRoamingStatistics = FALSE; |
| } |
| |
| /* Raise event of Roaming Completion */ |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("EvHandlerSendEvent -ROAMING_COMPLETE\n" )); |
| EvHandlerSendEvent(pAPConnection->hEvHandler, IPC_EVENT_ROAMING_COMPLETE, NULL, 0); |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_stopConnection |
| * |
| * \b Description: |
| * |
| * Stop required before roaming was started |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_stopConnection(void *pData) |
| { |
| apConn_t *pAPConnection; |
| disConnType_e disConnType; |
| pAPConnection = (apConn_t *)pData; |
| |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("apConn_stopConnection, calls conn_stop, removeKeys=%d, sendDeauthPacket=%d \n", pAPConnection->removeKeys, pAPConnection->sendDeauthPacket)); |
| |
| /* Erase vendor specific info-element if was defined for last AP Assoc request */ |
| pAPConnection->vsIElength = 0; |
| |
| /* In case AP connection was stopped by SME, and radioOn is false, meaning immidiate shutdown is required without disassoc frame */ |
| /* Otherwise, ask for normal disconnection with disassoc frame */ |
| disConnType = (pAPConnection->sendDeauthPacket == TRUE) ? DISCONN_TYPE_DEAUTH : DISCONN_TYPE_IMMEDIATE; |
| |
| /* Stop Connection state machine - always immediate TBD */ |
| conn_stop(pAPConnection->hConnSm, |
| disConnType, |
| STATUS_UNSPECIFIED, |
| FALSE, /* pAPConnection->removeKeys - for Roaming, do not remove the keys */ |
| apConn_DisconnCompleteInd, |
| pAPConnection); |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_reportDisconnected |
| * |
| * \b Description: |
| * |
| * Moving from 'Disconnecting' state to 'Idle': |
| * RoamMgr.status("not-connected") |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_reportDisconnected(void *pData) |
| { |
| apConn_t *pAPConnection; |
| apConn_connStatus_t reportStatus; |
| |
| pAPConnection = (apConn_t *)pData; |
| |
| if (pAPConnection->reportStatusCallb != NULL) |
| { |
| reportStatus.status = CONN_STATUS_NOT_CONNECTED; |
| pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus); |
| } |
| |
| pAPConnection->firstAttempt2Roam = TRUE; |
| |
| /* Notify SME */ |
| apConn_reportConnStatusToSME(pAPConnection); |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_retainAP |
| * |
| * \b Description: |
| * |
| * Roaming Manager gives up on roaming. |
| * Moving from 'Wait for connection command' back to 'Wait for roam started. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_retainAP(void *data) |
| { |
| apConn_t *pAPConnection; |
| apConn_connStatus_t reportStatus; |
| paramInfo_t param; |
| |
| pAPConnection = (apConn_t *)data; |
| |
| /* Configure SCR group back to connection */ |
| scr_setGroup (pAPConnection->hScr, SCR_GID_CONNECTED); |
| |
| /* Report Roaming Manager */ |
| if (pAPConnection->reportStatusCallb != NULL) |
| { |
| param.paramType = ASSOC_ASSOCIATION_RESP_PARAM; |
| |
| assoc_getParam(pAPConnection->hAssoc, ¶m); |
| reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer); |
| reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize; |
| |
| reportStatus.status = CONN_STATUS_HANDOVER_SUCCESS; |
| |
| pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus); |
| } |
| pAPConnection->retainCurrAPNum++; |
| |
| pAPConnection->roamReason = ROAMING_TRIGGER_NONE; |
| pAPConnection->removeKeys = TRUE; |
| pAPConnection->sendDeauthPacket = TRUE; |
| pAPConnection->reNegotiateTSPEC = FALSE; |
| pAPConnection->voiceTspecConfigured = FALSE; |
| pAPConnection->videoTspecConfigured = FALSE; |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_requestCCKM |
| * |
| * \b Description: |
| * |
| * Roaming Manager requests to roaming. |
| * Get CCKM (prepare hand-off). |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_requestCCKM(void *data) |
| { |
| apConn_t *pAPConnection; |
| TI_STATUS status; |
| |
| pAPConnection = (apConn_t *)data; |
| |
| #ifdef EXC_MODULE_INCLUDED |
| /* Send request to EXC module */ |
| apConn_calcNewTsf(pAPConnection, (UINT8 *)&(pAPConnection->newAP->lastRxTSF), pAPConnection->newAP->lastRxHostTimestamp, pAPConnection->newAP->beaconInterval); |
| status = excMngr_startCckm(pAPConnection->hExcMngr, &(pAPConnection->newAP->BSSID), (UINT8 *)&(pAPConnection->newAP->lastRxTSF)); |
| #else |
| status = OK; |
| apConn_RoamHandoffFinished(pAPConnection); |
| #endif |
| return status; |
| } |
| |
| |
| #ifdef EXC_MODULE_INCLUDED |
| /** |
| * |
| * calcNewTsfTimestamp - Calculates the TSF |
| * |
| * \b Description: |
| * |
| * Calculates the TSF according to the delta of the TSF from the last Beacon/Probe Resp and the current time. |
| * |
| * \b ARGS: |
| * |
| * I - hRoamingMngr - pointer to the roamingMngr SM context \n |
| * I/O - tsfTimeStamp - the TSF field in the site entry of the roaming candidate AP |
| * I - newSiteOsTimeStamp - the TS field in the site entry of the roaming candidate AP |
| * |
| * \b RETURNS: |
| * |
| * Nothing. |
| * |
| * |
| */ |
| static void apConn_calcNewTsf(apConn_t *hAPConnection, UINT8 *tsfTimeStamp, UINT32 newSiteOsTimeStamp, UINT32 beaconInterval) |
| { |
| apConn_t *pAPConnection = hAPConnection; |
| UINT32 osTimeStamp = os_timeStampMs(pAPConnection->hOs); |
| UINT32 deltaTimeStamp; |
| UINT32 tsfLsdw,tsfMsdw, newOsTimeStamp; |
| UINT32 remainder; |
| UINT8 newTsfTimestamp[TIME_STAMP_LEN]; |
| |
| /* get the delta TS between the TS of the last Beacon/ProbeResp-from the site table |
| and the current TS */ |
| deltaTimeStamp = osTimeStamp - newSiteOsTimeStamp; |
| tsfLsdw = *((UINT32*)&tsfTimeStamp[0]); |
| tsfMsdw = *((UINT32*)&tsfTimeStamp[4]); |
| |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| (" TSF time LSDW reversed=%x, TSF time MSDW reversed=%x\n", |
| tsfLsdw, tsfMsdw)); |
| |
| deltaTimeStamp = deltaTimeStamp*1000;/* from mSec to uSec*/ |
| /* Before adding, save remainder */ |
| remainder = tsfTimeStamp[3] + ((deltaTimeStamp & 0xff000000) >> 24); |
| |
| /* The LS DW of the TS is the TSF taken from the last Beacon/Probe Resp |
| + the delta TS from the time the Beacon/Probe Resp arrive till now. */ |
| newOsTimeStamp = deltaTimeStamp+tsfLsdw; |
| |
| /* substracting one beacon interval */ |
| newOsTimeStamp -= (beaconInterval * 1024); /* im usec */ |
| |
| /* save just for debug printout */ |
| deltaTimeStamp +=osTimeStamp; /* uMsec */ |
| /* update the LSB of the TSF */ |
| newTsfTimestamp[0] = newOsTimeStamp & 0x000000ff; |
| newTsfTimestamp[1] = (newOsTimeStamp & 0x0000ff00) >> 8; |
| newTsfTimestamp[2] = (newOsTimeStamp & 0x00ff0000) >> 16; |
| newTsfTimestamp[3] = (newOsTimeStamp & 0xff000000) >> 24; |
| |
| /* increase the MSB in case of overflow */ |
| if (remainder > 0xff) |
| { |
| tsfMsdw++; |
| |
| } |
| /* update the MSB of the TSF */ |
| newTsfTimestamp[4] = tsfMsdw & 0x000000ff; |
| newTsfTimestamp[5] = (tsfMsdw & 0x0000ff00) >> 8; |
| newTsfTimestamp[6] = (tsfMsdw & 0x00ff0000) >> 16; |
| newTsfTimestamp[7] = (tsfMsdw & 0xff000000) >> 24; |
| |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| (" NEW TSF time: reversedTsfTimeStamp= 0x%x, New deltaTimeStamp= 0x%x, \n remainder=0x%x, new tsfTimeStamp=%x-%x-%x-%x-%x-%x-%x-%x\n", |
| newOsTimeStamp, deltaTimeStamp, remainder, |
| newTsfTimestamp[0], newTsfTimestamp[1], newTsfTimestamp[2], newTsfTimestamp[3], |
| newTsfTimestamp[4], newTsfTimestamp[5], newTsfTimestamp[6], newTsfTimestamp[7])); |
| |
| os_memoryCopy(pAPConnection->hOs, tsfTimeStamp, newTsfTimestamp, TIME_STAMP_LEN); |
| } |
| #endif |
| |
| |
| /** |
| * |
| * apConn_invokeConnectionToNewAp |
| * |
| * \b Description: |
| * |
| * Got CCKM (hand-off), start re-connection to another AP |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_invokeConnectionToNewAp(void *data) |
| { |
| apConn_t *pAPConnection; |
| connType_e connType; |
| paramInfoPartial_t param; |
| UINT8 staPrivacySupported, apPrivacySupported; |
| BOOL renegotiateTspec = FALSE; |
| |
| pAPConnection = (apConn_t *)data; |
| |
| pAPConnection->roamingStartedTimestamp = os_timeStampMs(pAPConnection->hOs); |
| |
| /* Check privacy compatibility */ |
| param.paramType = RSN_ENCRYPTION_STATUS_PARAM; |
| rsn_getParamPartial(pAPConnection->hPrivacy, ¶m); |
| |
| staPrivacySupported = (param.content.rsnEncryptionStatus == RSN_CIPHER_NONE) ? FALSE : TRUE; |
| apPrivacySupported = ((pAPConnection->newAP->capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TRUE : FALSE; |
| |
| if (staPrivacySupported != apPrivacySupported) |
| { |
| param.paramType = RSN_MIXED_MODE; |
| rsn_getParamPartial(pAPConnection->hPrivacy, ¶m); |
| |
| if (apPrivacySupported || |
| (!param.content.rsnMixedMode && staPrivacySupported)) |
| { |
| WLAN_REPORT_WARNING(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("%s: failed privacy comparison %d vs. %d\n", __FUNCTION__, staPrivacySupported, apPrivacySupported)); |
| return (apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection)); |
| } |
| } |
| |
| /* Update data info of desired AP; in case of first attempt to roam, |
| store previous primary site info */ |
| if (siteMgr_overwritePrimarySite(pAPConnection->hSiteMgr, pAPConnection->newAP, pAPConnection->firstAttempt2Roam) != OK) |
| { |
| WLAN_REPORT_WARNING(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("%s: failed to ovewrite Primary Site\n", __FUNCTION__)); |
| return (apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection)); |
| } |
| |
| /* Update re-associate parameter of MLME */ |
| if (pAPConnection->requestType == AP_CONNECT_FAST_TO_AP) |
| { |
| connType = CONN_TYPE_ROAM; |
| } |
| else |
| { |
| connType = CONN_TYPE_FIRST_CONN; |
| } |
| |
| #ifdef EXC_MODULE_INCLUDED |
| /* Check the need in TSPEC re-negotiation */ |
| if ( (pAPConnection->voiceTspecConfigured || pAPConnection->videoTspecConfigured) |
| && pAPConnection->reNegotiateTSPEC ) |
| { |
| /* If the candidate AP is at least EXCver4 AP, try to re-negotiate TSPECs */ |
| if (excMngr_parseExcVer(pAPConnection->hExcMngr, |
| pAPConnection->newAP->pBuffer, |
| pAPConnection->newAP->bufferLength) >= 4) |
| { |
| renegotiateTspec = TRUE; |
| } |
| } |
| #endif |
| |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("%s: calls conn_start, removeKeys=%d, renegotiateTSPEC=%d\n", __FUNCTION__, |
| pAPConnection->removeKeys, renegotiateTspec)); |
| |
| /* Start Connection state machine */ |
| return conn_start(pAPConnection->hConnSm, |
| connType, |
| apConn_ConnCompleteInd, |
| pAPConnection, |
| pAPConnection->removeKeys, |
| renegotiateTspec); |
| } |
| |
| |
| /** |
| * |
| * apConn_reportConnFail |
| * |
| * \b Description: |
| * |
| * Got 'Failed' indication from Connection state machine - inform Roaming Manager Module |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_reportConnFail(void *data) |
| { |
| apConn_t *pAPConnection; |
| apConn_connStatus_t reportStatus; |
| paramInfoPartial_t param; |
| |
| pAPConnection = (apConn_t *)data; |
| |
| pAPConnection->firstAttempt2Roam = FALSE; |
| pAPConnection->resetReportedRoamingStatistics = FALSE; |
| |
| /* Erase vendor specific info-element if was defined for last AP Assoc request */ |
| pAPConnection->vsIElength = 0; |
| |
| /* Report to Roaming Manager */ |
| if (pAPConnection->reportStatusCallb != NULL) |
| { |
| param.paramType = ASSOC_ASSOCIATION_RESP_PARAM; |
| |
| assoc_getParamPartial(pAPConnection->hAssoc, ¶m); |
| reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer); |
| reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize; |
| |
| reportStatus.status = CONN_STATUS_HANDOVER_FAILURE; |
| |
| pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus); |
| } |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_configureSCR |
| * |
| * \b Description: |
| * |
| * Got 'Failed' indication from Connection state machine - inform Roaming Manager Module |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_configureDriverBeforeRoaming(void *pData) |
| { |
| apConn_t *pAPConnection = (apConn_t*)pData; |
| paramInfoPartial_t param; |
| |
| /* Configure SCR group of allowed clients according to 'Roaming' rule */ |
| scr_setGroup (pAPConnection->hScr, SCR_GID_ROAMING); |
| param.paramType = QOS_MNGR_VOICE_RE_NEGOTIATE_TSPEC; |
| qosMngr_getParamsPatial(pAPConnection->hQos, ¶m); |
| pAPConnection->voiceTspecConfigured = param.content.TspecConfigure.voiceTspecConfigure; |
| pAPConnection->videoTspecConfigured = param.content.TspecConfigure.videoTspecConfigure; |
| pAPConnection->resetReportedRoamingStatistics = FALSE; |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_swChFinished |
| * |
| * \b Description: |
| * |
| * Switch channel completed; if there were roaming Manager triggers meanwhile, |
| * inform Roaming Manager Module |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_swChFinished(void *pData) |
| { |
| apConn_t *pAPConnection = (apConn_t *)pData; |
| |
| /* Inform Current BSS module */ |
| currBSS_restartRssiCounting(pAPConnection->hCurrBSS); |
| |
| /* If there are unreported roaming triggers of 'No AP' type, |
| report them now to roaming manager */ |
| if (pAPConnection->roamReason >= ROAMING_TRIGGER_MAX_TX_RETRIES) |
| { |
| if ((pAPConnection->roamingEnabled == TRUE) && |
| (pAPConnection->roamEventCallb != NULL)) |
| { |
| /* Report to Roaming Manager */ |
| pAPConnection->roamEventCallb(pAPConnection->hRoamMng, &pAPConnection->roamReason); |
| } |
| } |
| else |
| { |
| pAPConnection->roamReason = ROAMING_TRIGGER_NONE; |
| } |
| |
| return OK; |
| } |
| |
| |
| /** |
| * |
| * apConn_handleTspecReneg |
| * |
| * \b Description: |
| * |
| * This function will be called when moving from CONNECTING state to |
| * START_TSPEC_RENEGOTIATION state. It checks if TSPEC re-negotiation was requested |
| * by roaming manager, if the TSPEC for voice was defined by user application, |
| * if the re-negotiation was performed during hand-over. |
| * If so, it will trigger moving to WAIT_ROAM state, otherwise it will start |
| * TSPEC negotiation, staying in the REESTABLISHING_VOICE state and waiting |
| * for results. |
| * |
| * \b ARGS: |
| * |
| * I - pData - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_handleTspecReneg (void *pData) |
| { |
| apConn_t *pAPConnection = (apConn_t *)pData; |
| paramInfo_t param; |
| |
| if (pAPConnection->voiceTspecConfigured && pAPConnection->reNegotiateTSPEC) |
| { |
| param.paramType = QOS_MNGR_VOICE_RE_NEGOTIATE_TSPEC; |
| qosMngr_getParams(pAPConnection->hQos, ¶m); |
| |
| if (param.content.TspecConfigure.voiceTspecConfigure == TRUE) |
| { |
| /* TSPEC is already configured, move to CONNECTED */ |
| return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection); |
| } |
| else |
| { |
| param.paramType = QOS_MNGR_RESEND_TSPEC_REQUEST; |
| param.content.qosRenegotiateTspecRequest.callback = (void *)apConn_qosMngrReportResultCallb; |
| param.content.qosRenegotiateTspecRequest.handler = pData; |
| |
| if (qosMngr_setParams(pAPConnection->hQos, ¶m) != OK) |
| { |
| /* Re-negotiation of TSPEC cannot be performed */ |
| return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection); |
| } |
| return OK; |
| } |
| } |
| else |
| { |
| /* No need to re-negotiate TSPEC, move to CONNECTED */ |
| return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection); |
| } |
| } |
| |
| |
| /** |
| * |
| * apConn_qosMngrReportResultCallb |
| * |
| * \b Description: |
| * |
| * This function will be transferred to QoS manager upon request to start negotiation |
| * of the TSPEC for voice and signaling, and will be called when the voice TSPEC |
| * renegotiation is completed. The function will generate FINISHED_OK or |
| * FINISHED_NOK events to the state machine of AP Connection, triggering change of |
| * the current state. |
| * |
| * \b ARGS: |
| * |
| * I - hApConn - pointer to AP Connection context\n |
| * I - result - returned by Traffic admission control\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static TI_STATUS apConn_qosMngrReportResultCallb (TI_HANDLE hApConn, trafficAdmRequestStatus_e result) |
| { |
| apConn_t *pAPConnection = (apConn_t *)hApConn; |
| |
| AP_CONN_VALIDATE_HANDLE(hApConn); |
| |
| if (result == STATUS_TRAFFIC_ADM_REQUEST_ACCEPT) |
| { |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection); |
| } |
| else |
| { |
| apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection); |
| } |
| return OK; |
| } |
| |
| /** |
| * |
| * apConn_reportConnStatusToSME |
| * |
| * \b Description: |
| * |
| * Sends report to SME regarding the connection status |
| * |
| * \b ARGS: |
| * |
| * I - pAPConnection - pointer to AP Connection context\n |
| * |
| * \b RETURNS: |
| * |
| * OK on success, NOK otherwise. |
| * |
| * \sa |
| */ |
| static void apConn_reportConnStatusToSME (apConn_t *pAPConnection) |
| { |
| WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, |
| ("%s roamingTrigger = %d, APDisconnectStatusCode = %d, bNonRoamingDisAssocReason = %d\n", |
| __FUNCTION__, pAPConnection->roamReason, pAPConnection->APDisconnect.uStatusCode, |
| pAPConnection->bNonRoamingDisAssocReason)); |
| |
| /* Check if an outside reason caused the disconnection. */ |
| if (pAPConnection->bNonRoamingDisAssocReason) |
| { |
| pAPConnection->bNonRoamingDisAssocReason = FALSE; |
| smeSm_reportConnStatus(pAPConnection->hSme, STATUS_UNSPECIFIED, 0); |
| } |
| /* DisAssociation happened due to roaming trigger */ |
| else if (pAPConnection->roamReason == ROAMING_TRIGGER_AP_DISCONNECT) |
| { /* AP disconnect is a special case of the status delivered to SME */ |
| mgmtStatus_e mgmtStatus = ( pAPConnection->APDisconnect.bDeAuthenticate ? STATUS_AP_DEAUTHENTICATE : STATUS_AP_DISASSOCIATE ); |
| smeSm_reportConnStatus(pAPConnection->hSme, mgmtStatus, pAPConnection->APDisconnect.uStatusCode); |
| } |
| else /* Finally, just send the last roaming trigger */ |
| { |
| smeSm_reportConnStatus(pAPConnection->hSme, STATUS_ROAMING_TRIGGER, (UINT32)pAPConnection->roamReason); |
| } |
| } |
| |
| |