1/****************************************************************************
2**+-----------------------------------------------------------------------+**
3**|                                                                       |**
4**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
5**| All rights reserved.                                                  |**
6**|                                                                       |**
7**| Redistribution and use in source and binary forms, with or without    |**
8**| modification, are permitted provided that the following conditions    |**
9**| are met:                                                              |**
10**|                                                                       |**
11**|  * Redistributions of source code must retain the above copyright     |**
12**|    notice, this list of conditions and the following disclaimer.      |**
13**|  * Redistributions in binary form must reproduce the above copyright  |**
14**|    notice, this list of conditions and the following disclaimer in    |**
15**|    the documentation and/or other materials provided with the         |**
16**|    distribution.                                                      |**
17**|  * Neither the name Texas Instruments nor the names of its            |**
18**|    contributors may be used to endorse or promote products derived    |**
19**|    from this software without specific prior written permission.      |**
20**|                                                                       |**
21**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
22**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
23**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
24**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
25**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
26**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
27**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
28**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
29**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
30**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
31**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
32**|                                                                       |**
33**+-----------------------------------------------------------------------+**
34****************************************************************************/
35
36
37/** \file apConn.c
38 *  \brief AP Connection
39 *
40 *  \see apConn.h
41 */
42
43/****************************************************************************
44 *                                                                          *
45 *   MODULE:  AP Connection                                                 *
46 *   PURPOSE:                                                               *
47 *   Roaming ability of eSTA is implemented by Roaming Manager Component and
48 *   described in "Roaming Manager module LLD" document, and by
49 *   AP Connection module. AP Connection module implemented as two sub-modules:
50 *   The major one is AP Connection, that is responsible for:
51 *   - providing Roaming Manager with access to other parts of WLAN Driver,
52 *   - implementing low levels of roaming mechanism.
53 *   Current BSS sub-module takes care of:
54 *   - maintaining database of current AP info,
55 *   - providing access to database of current AP info.
56 *                                                                          *
57 ****************************************************************************/
58
59#include "osApi.h"
60
61#include "paramIn.h"
62#include "report.h"
63#include "utils.h"
64
65#include "smeSmApi.h"
66#include "siteMgrApi.h"
67#include "smeApi.h"
68#include "PowerMgr_API.h"
69#include "TrafficMonitorAPI.h"
70#include "RateAdaptation.h"
71#include "qosMngr_API.h"
72#ifdef EXC_MODULE_INCLUDED
73 #include "excMngr.h"
74#endif
75#include "measurementMgrApi.h"
76#include "connApi.h"
77#include "EvHandler.h"
78#include "apConn.h"
79#include "currBss.h"
80#include "Ctrl.h"
81#include "fsm.h"
82#include "scrApi.h"
83#include "regulatoryDomainApi.h"
84
85/* Constants and macros */
86#ifdef TI_DBG
87 #define    AP_CONN_VALIDATE_HANDLE(hAPConnection)  \
88    if (hAPConnection == NULL)  \
89    {   \
90        WLAN_OS_REPORT(("FATAL ERROR: AP Connection context is not initiated\n"));  \
91        return NOK; \
92    }
93#else
94 #define    AP_CONN_VALIDATE_HANDLE(hAPConnection)
95#endif
96
97#define MAX_ROAMING_TRIGGERS  ROAMING_TRIGGER_LAST
98
99#define UPDATE_SEND_DEAUTH_PACKET_FLAG(roamingEventType) \
100            if ((roamingEventType >= ROAMING_TRIGGER_MAX_TX_RETRIES) && \
101                (roamingEventType != ROAMING_TRIGGER_SECURITY_ATTACK)) \
102            { \
103                pAPConnection->sendDeauthPacket = FALSE; \
104            }
105
106/* Init bits */
107
108
109/* Enumerations */
110
111/**
112* AP Connection state machine states
113*/
114typedef enum
115{
116    AP_CONNECT_STATE_IDLE = 0,          /**< Initial state */
117    AP_CONNECT_STATE_WAIT_ROAM,         /**< Connected to AP, waiting for start roaming command */
118    AP_CONNECT_STATE_SWITCHING_CHANNEL, /**< Connected to AP, switch channel in progress */
119    AP_CONNECT_STATE_WAIT_CONNECT_CMD,  /**< SCR allocated, PS mode entered; wait for cmd from Roam Mngr */
120    AP_CONNECT_STATE_PREPARE_HAND_OFF,  /**< Request CCKM for new AP, wait for response */
121    AP_CONNECT_STATE_CONNECTING,        /**< Performing Connection to new AP; wait for response from Conn SM */
122    AP_CONNECT_STATE_DISCONNECTING,     /**< Wait for completion of current link disconnection */
123    AP_CONNECT_STATE_REESTABLISH_VOICE, /**< Wait for completion of voice TSPEC re-negotiation */
124    AP_CONNECT_STATE_LAST
125} apConn_smStates;
126
127
128/**
129* AP Connection state machine events
130*/
131typedef enum
132{
133    AP_CONNECT_EVENT_PREPARE_FOR_ROAMING= 0,/**< Sent by Roam MNGR when roaming event occurs */
134    AP_CONNECT_EVENT_FINISHED_OK,           /**< Indicates successful completion of request sent to Conn SM */
135    AP_CONNECT_EVENT_FINISHED_NOT_OK,       /**< Indicates unsuccessful completion of request sent to Conn SM */
136    AP_CONNECT_EVENT_RETAIN_CURRENT_AP,     /**< Sent by Roam MNGR when it wishes to give-up roaming */
137    AP_CONNECT_EVENT_START,                 /**< Sent by SME when first time link to AP is established */
138    AP_CONNECT_EVENT_START_ROAM,            /**< Sent by Roam MNGR when it wishes to roam to new AP */
139    AP_CONNECT_EVENT_START_SWITCH_CHANNEL,  /**< Sent by Switch channel module when starting switch channel process (tx enabled) */
140    AP_CONNECT_EVENT_FINISHED_SWITCH_CH,    /**< Sent by Switch channel module when finishing switch channel process (tx enabled) */
141    AP_CONNECT_EVENT_FINISHED_HAND_OVER,    /**< Sent by EXC module when finishing hand-over */
142    AP_CONNECT_EVENT_STOP,                  /**< Disconnect current link, send stop indication to other modules */
143    AP_CONNECT_EVENT_LAST
144} apConn_smEvents;
145
146#define AP_CONNECT_NUM_STATES       AP_CONNECT_STATE_LAST
147#define AP_CONNECT_NUM_EVENTS       AP_CONNECT_EVENT_LAST
148
149
150#ifdef REPORT_LOG
151
152/* Global variables */
153static char *apConn_stateDesc[AP_CONNECT_NUM_STATES] = {
154        "APC_STATE_IDLE",
155        "APC_STATE_WAIT_ROAM",
156        "APC_STATE_SWITCHING_CHANNEL",
157        "APC_STATE_WAIT_CONNECT_CMD",
158        "APC_STATE_PREPARE_HAND_OFF",
159        "APC_STATE_CONNECTING",
160        "APC_STATE_DISCONNECTING",
161        "APC_STATE_REESTABLISH_VOICE"
162    };
163
164static char *apConn_eventDesc[AP_CONNECT_NUM_EVENTS] = {
165        "APC_EVENT_PREPARE_FOR_ROAMING",
166        "APC_EVENT_FINISHED_OK",
167        "APC_EVENT_FINISHED_NOT_OK",
168        "APC_EVENT_RETAIN_CURRENT_AP",
169        "APC_EVENT_START",
170        "APC_EVENT_START_ROAM",
171        "APC_EVENT_START_SWITCH_CHANNEL",
172        "APC_EVENT_FINISHED_SWITCH_CHANNEL",
173        "APC_EVENT_FINISHED_HAND_OVER",
174        "APC_EVENT_STOP"
175    };
176
177#endif
178
179
180/* Typedefs */
181
182/* Structures */
183
184/**
185* AP Connection control block
186* Following structure defines parameters that can be configured externally,
187* internal variables, AP Connection state machine and handlers of other modules
188* used by AP Connection module
189*/
190typedef struct _apConn_t
191{
192    /* AP Connection state machine */
193    fsm_stateMachine_t      *apConnSM;          /**< AP Connection module state machine */
194    apConn_smStates         currentState;       /**< AP Connection state machine current state */
195
196    /* Internal parameters */
197    BOOL                    firstAttempt2Roam;  /**< TRUE if still connected to original AP, FALSE otherwise */
198    BOOL                    roamingEnabled;     /**< If FALSE, act like if no roaming callback registered. */
199    apConn_roamingTrigger_e roamReason;         /**< The most severe and recent reason for roaming */
200    APDisconnect_t          APDisconnect;       /**< The AP disconnect trigger extra information */
201    bssEntry_t              *newAP;             /**< Stores parameters of roaming candidate */
202    apConn_connRequest_e    requestType;        /**< Stores type of roaming request */
203    INT8                    rssiThreshold;      /**< Stores recently configured RSSI threshold */
204    UINT8                   snrThreshold;       /**< Stores recently configured SNR threshold */
205    UINT8                   txFailureThreshold; /**< Stores recently configured consec. no ack threshold */
206    UINT8                   lowRateThreshold;   /**< Stores recently configured consec. no ack threshold */
207    UINT32                  vsIElength;         /**< Length of vendor specific info-element for assoc req (if defined) */
208    char                    *vsIEbuf;           /**< Pointer to vendor specific info-element for assoc req (if defined) */
209    BOOL                    isRssiTriggerMaskedOut;
210    BOOL                    isSnrTriggerMaskedOut;
211    BOOL                    isConsTxFailureMaskedOut;
212    BOOL                    islowRateTriggerMaskedOut;
213    BOOL                    removeKeys;         /**< Indicates whether keys should be removed after disconnect or not */
214    BOOL                    ignoreDeauthReason0;/**< Indicates whether to ignore DeAuth with reason 0, required for Rogue AP test EXC-V2 */
215    BOOL                    sendDeauthPacket;   /**< Indicates whether to send DEAUTH packet when discommecting or not */
216    BOOL                    voiceTspecConfigured;/**< Shall be set to TRUE before roaming in case the TSPEC is configured */
217	BOOL                    videoTspecConfigured;/**< Shall be set to TRUE before roaming in case the TSPEC is configured */
218    BOOL                    reNegotiateTSPEC;   /**< Shall be set to TRUE before hand-over if requested by Roaming Manager */
219    BOOL                    resetReportedRoamingStatistics; /**< Shall be set to TRUE if starting to measure traffic */
220    UINT16                  lastRoamingDelay;
221    UINT32                  roamingStartedTimestamp;
222    UINT8                   roamingSuccesfulHandoverNum;
223    BOOL                    bNonRoamingDisAssocReason; /**< Indicate whether last disconnection was called from outside (SME) */
224    /** Callback functions, registered by Roaming manager */
225    apConn_roamMngrCallb_t  roamEventCallb;         /**< roam event triggers */
226    apConn_roamMngrCallb_t  reportStatusCallb;      /**< connection status events  */
227    apConn_roamMngrCallb_t  returnNeighborApsCallb; /**< neighbor APs list update */
228
229    /* Handlers of other modules used by AP Connection */
230    TI_HANDLE               hOs;
231    TI_HANDLE               hReport;
232    TI_HANDLE               hCurrBSS;
233    TI_HANDLE               hRoamMng;
234    TI_HANDLE               hSme;
235    TI_HANDLE               hSiteMgr;
236    TI_HANDLE               hExcMngr;
237    TI_HANDLE               hConnSm;
238    TI_HANDLE               hPrivacy;
239    TI_HANDLE               hQos;
240    TI_HANDLE               hRateAdapt;
241    TI_HANDLE               hEvHandler;
242    TI_HANDLE               hScr;
243    TI_HANDLE               hAssoc;
244    TI_HANDLE               hRegulatoryDomain;
245
246    /* Counters for statistics */
247    UINT32                  roamingTriggerEvents[MAX_ROAMING_TRIGGERS];
248    UINT32                  roamingSuccesfulHandoverTotalNum;
249    UINT32                  roamingFailedHandoverNum;
250    UINT32                  retainCurrAPNum;
251    UINT32                  disconnectFromRoamMngrNum;
252    UINT32                  stopFromSmeNum;
253} apConn_t;
254
255
256/* Internal functions prototypes */
257
258/* SM functions */
259static TI_STATUS apConn_smEvent(apConn_smStates *currState, UINT8 event, void* data);
260static TI_STATUS apConn_smNop(void *pData);
261static TI_STATUS apConn_smUnexpected(void *pData);
262static TI_STATUS apConn_startWaitingForTriggers(void *pData);
263static TI_STATUS apConn_connectedToNewAP(void *pData);
264static TI_STATUS apConn_configureDriverBeforeRoaming(void *pData);
265static TI_STATUS apConn_stopConnection(void *pData);
266static TI_STATUS apConn_invokeConnectionToNewAp(void *pData);
267static TI_STATUS apConn_reportDisconnected(void *pData);
268static TI_STATUS apConn_retainAP(void *pData);
269static TI_STATUS apConn_requestCCKM(void *pData);
270static TI_STATUS apConn_reportConnFail(void *pData);
271static TI_STATUS apConn_swChFinished(void *pData);
272static TI_STATUS apConn_handleTspecReneg (void *pData);
273
274/* other functions */
275#ifdef EXC_MODULE_INCLUDED
276static void apConn_calcNewTsf(apConn_t *hAPConnection, UINT8 *tsfTimeStamp, UINT32 newSiteOsTimeStamp, UINT32 beaconInterval);
277#endif
278static TI_STATUS apConn_qosMngrReportResultCallb (TI_HANDLE hApConn, trafficAdmRequestStatus_e result);
279static void      apConn_reportConnStatusToSME    (apConn_t *pAPConnection);
280
281
282/* Public functions implementation */
283
284/**
285*
286* apConn_create
287*
288* \b Description:
289*
290* Create the AP Connection context:
291* allocate memory for internal variables;
292* create state machine.
293*
294* \b ARGS:
295*
296*  I   - hOs - OS handler
297*
298* \b RETURNS:
299*
300* Pointer to the AP Connection on success, NULL on failure
301* (unable to allocate memory or other error).
302*
303* \sa
304*/
305TI_HANDLE apConn_create(TI_HANDLE hOs)
306{
307    TI_STATUS   status;
308    apConn_t    *pAPConnection;
309
310    if ((pAPConnection = os_memoryAlloc(hOs, sizeof(apConn_t))) != NULL)
311    {
312        pAPConnection->hOs = hOs;
313
314        status = fsm_Create(hOs, &(pAPConnection->apConnSM), AP_CONNECT_NUM_STATES, AP_CONNECT_NUM_EVENTS);
315        if (status == OK)
316        {
317            /* Succeeded to create AP Connection module context - return pointer to it */
318            return pAPConnection;
319        }
320        else /* Failed to create state machine */
321        {
322            WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error creating apConnSM - aborting\n"));
323            /* Free pre-allocated control block */
324            utils_nullMemoryFree(hOs, pAPConnection, sizeof(apConn_t));
325            return NULL;
326        }
327    }
328    else /* Failed to allocate control block */
329    {
330        WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n"));
331        return NULL;
332    }
333}
334
335/**
336*
337* apConn_unload
338*
339* \b Description:
340*
341* Finish AP Connection module work:
342* release the allocation for state machine and internal variables.
343*
344* \b ARGS:
345*
346*
347* \b RETURNS:
348*
349*  OK if successful, NOK otherwise.
350*
351* \sa
352*/
353TI_STATUS apConn_unload(TI_HANDLE hAPConnection)
354{
355    apConn_t *pAPConnection;
356
357    AP_CONN_VALIDATE_HANDLE(hAPConnection);
358
359    pAPConnection = (apConn_t *)hAPConnection;
360
361    /* Unload state machine */
362    fsm_Unload(pAPConnection->hOs, pAPConnection->apConnSM);
363
364    /* Free pre-allocated control block */
365    utils_nullMemoryFree(pAPConnection->hOs, pAPConnection, sizeof(apConn_t));
366
367    return OK;
368}
369
370/**
371*
372* apConn_config
373*
374* \b Description:
375*
376* Prepare AP Connection module to work: initiate internal variables, start state machine
377*
378* \b ARGS:
379*
380*  I   - hCurrAP - Current BSS handle \n
381*  I   - hRoamMng - Roaming Manager handle  \n
382*  I   - hSme - SME context  \n
383*  I   - hPowerMgr - Power Manager context  \n
384*
385* \b RETURNS:
386*
387*  OK on success, NOK on failure.
388*
389* \sa
390*/
391TI_STATUS apConn_config(TI_HANDLE hAPConnection,
392                        TI_HANDLE hReport,
393                        TI_HANDLE hCurrAP,
394                        TI_HANDLE hRoamMng,
395                        TI_HANDLE hSme,
396                        TI_HANDLE hSiteMgr,
397                        TI_HANDLE hExcMngr,
398                        TI_HANDLE hConnSm,
399                        TI_HANDLE hPrivacy,
400                        TI_HANDLE hQos,
401                        TI_HANDLE hCtrl,
402                        TI_HANDLE hEvHandler,
403                        TI_HANDLE hScr,
404                        TI_HANDLE hAssoc,
405                        TI_HANDLE hRegulatoryDomain,
406                        apConnParams_t *pApConnParams)
407{
408    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
409    TI_STATUS status;
410    UINT32  index;
411
412    /** State Machine matrix */
413    fsm_actionCell_t apConn_matrix[AP_CONNECT_NUM_STATES][AP_CONNECT_NUM_EVENTS] =
414    {
415        /* next state and actions for IDLE state */
416        {   {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* PREPARE_FOR_ROAMING  */
417            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* FINISHED_OK          */
418            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* FINISHED_NOT_OK      */
419            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* RETAIN_CURRENT_AP    */
420            {AP_CONNECT_STATE_WAIT_ROAM,apConn_startWaitingForTriggers},/* START                */
421            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* START_ROAM           */
422            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* START_SWITCH_CHANNEL */
423            {AP_CONNECT_STATE_IDLE, apConn_smNop},                      /* FINISHED_SWITCH_CH   */
424            {AP_CONNECT_STATE_IDLE, apConn_smNop},                      /* FINISHED_HAND_OVER   */
425            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}                /* STOP                 */
426        },
427        /* next state and actions for WAIT_ROAM state */
428        {   {AP_CONNECT_STATE_WAIT_CONNECT_CMD,apConn_configureDriverBeforeRoaming},/* PREPARE_FOR_ROAMING  */
429            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_OK          */
430            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_NOT_OK      */
431            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* RETAIN_CURRENT_AP    */
432            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* START                */
433            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* START_ROAM           */
434            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smNop},     /* START_SWITCH_CHANNEL */
435            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_SWITCH_CH   */
436            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_HAND_OVER   */
437            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP                 */
438        },
439        /* next state and actions for SWITCHING_CHANNEL state */
440        {   {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* PREPARE_FOR_ROAMING  */
441            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* FINISHED_OK          */
442            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* FINISHED_NOT_OK      */
443            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* RETAIN_CURRENT_AP    */
444            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* START                */
445            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* START_ROAM           */
446            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_swChFinished},  /* START_SWITCH_CHANNEL */
447            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smNop},                 /* FINISHED_SWITCH_CH   */
448            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* FINISHED_HAND_OVER   */
449            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
450        },
451        /* next state and actions for WAIT_CONNECT_CMD state */
452        {   {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* PREPARE_FOR_ROAMING  */
453            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_OK          */
454            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_NOT_OK      */
455            {AP_CONNECT_STATE_WAIT_ROAM, apConn_retainAP},              /* RETAIN_CURRENT_AP    */
456            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* START                */
457            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_requestCCKM},    /* START_ROAM           */
458            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* START_SWITCH_CHANNEL */
459            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_SWITCH_CH   */
460            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_HAND_OVER   */
461            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
462        },
463        /* next state and actions for PREPARE_HAND_OFF state */
464        {   {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* PREPARE_FOR_ROAMING  */
465            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* FINISHED_OK          */
466            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* FINISHED_NOT_OK      */
467            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* RETAIN_CURRENT_AP    */
468            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* START                */
469            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* START_ROAM           */
470            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* START_SWITCH_CHANNEL */
471            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* FINISHED_SWITCH_CH   */
472            {AP_CONNECT_STATE_CONNECTING, apConn_invokeConnectionToNewAp},/* FINISHED_HAND_OVER */
473            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
474        },
475        /* next state and actions for CONNECTING state */
476        {   {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* PREPARE_FOR_ROAMING  */
477            {AP_CONNECT_STATE_REESTABLISH_VOICE,apConn_handleTspecReneg},/* FINISHED_OK             */
478            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_reportConnFail}, /* FINISHED_NOT_OK      */
479            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* RETAIN_CURRENT_AP    */
480            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* START                */
481            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* START_ROAM           */
482            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* START_SWITCH_CHANNEL */
483            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* FINISHED_SWITCH_CH   */
484            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* FINISHED_HAND_OVER   */
485            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
486        },
487        /* next state and actions for DISCONNECTING state */
488        {   {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* PREPARE_FOR_ROAMING  */
489            {AP_CONNECT_STATE_IDLE, apConn_reportDisconnected},     /* FINISHED_OK          */
490            {AP_CONNECT_STATE_IDLE, apConn_reportDisconnected},     /* FINISHED_NOT_OK      */
491            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* RETAIN_CURRENT_AP    */
492            {AP_CONNECT_STATE_DISCONNECTING, apConn_smUnexpected},  /* START                */
493            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* START_ROAM           */
494            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* START_SWITCH_CHANNEL */
495            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* FINISHED_SWITCH_CH   */
496            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* FINISHED_HAND_OVER   */
497            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* STOP                 */
498        },
499        /* next state and actions for REESTABLISH_VOICE state */
500        {   {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* PREPARE_FOR_ROAMING  */
501            {AP_CONNECT_STATE_WAIT_ROAM,apConn_connectedToNewAP},       /* FINISHED_OK          */
502            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_reportConnFail}, /* FINISHED_NOT_OK      */
503            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* RETAIN_CURRENT_AP    */
504            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* START                */
505            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* START_ROAM           */
506            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* START_SWITCH_CHANNEL */
507            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* FINISHED_SWITCH_CH   */
508            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* FINISHED_HAND_OVER   */
509            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
510        }
511    };
512
513    AP_CONN_VALIDATE_HANDLE(hAPConnection);
514
515    status = fsm_Config(pAPConnection->apConnSM,
516                        (fsm_Matrix_t)&apConn_matrix[0][0],
517                        AP_CONNECT_NUM_STATES,
518                        AP_CONNECT_NUM_EVENTS,
519                        (fsm_eventActivation_t)apConn_smEvent,
520                        pAPConnection->hOs);
521
522
523    if (status == OK)
524    {
525        pAPConnection->currentState = AP_CONNECT_STATE_IDLE;
526        pAPConnection->firstAttempt2Roam = TRUE;
527        pAPConnection->hReport = hReport;
528        pAPConnection->hCurrBSS = hCurrAP;
529        pAPConnection->hRoamMng = hRoamMng;
530        pAPConnection->hSme = hSme;
531        pAPConnection->hSiteMgr = hSiteMgr;
532        pAPConnection->hExcMngr = hExcMngr;
533        pAPConnection->hConnSm = hConnSm;
534        pAPConnection->hPrivacy = hPrivacy;
535        pAPConnection->hQos = hQos;
536        pAPConnection->hRateAdapt = ((ctrlData_t *)hCtrl)->pRateAdaptation;
537        pAPConnection->hEvHandler = hEvHandler;
538        pAPConnection->hScr = hScr;
539        pAPConnection->hAssoc = hAssoc;
540        pAPConnection->hRegulatoryDomain = hRegulatoryDomain;
541
542        pAPConnection->roamingEnabled = TRUE;
543        pAPConnection->reportStatusCallb = NULL;
544        pAPConnection->roamEventCallb = NULL;
545        pAPConnection->returnNeighborApsCallb = NULL;
546        pAPConnection->ignoreDeauthReason0 = pApConnParams->ignoreDeauthReason0;
547
548        for (index=ROAMING_TRIGGER_NONE; index<ROAMING_TRIGGER_LAST; index++)
549        {
550            pAPConnection->roamingTriggerEvents[index] = 0;
551        }
552        pAPConnection->roamingSuccesfulHandoverNum = 0;
553        pAPConnection->roamingSuccesfulHandoverTotalNum = 0;
554        pAPConnection->roamingFailedHandoverNum = 0;
555        pAPConnection->retainCurrAPNum = 0;
556        pAPConnection->disconnectFromRoamMngrNum = 0;
557        pAPConnection->stopFromSmeNum = 0;
558        pAPConnection->txFailureThreshold = NO_ACK_DEFAULT_THRESHOLD;
559        pAPConnection->lowRateThreshold = LOW_RATE_DEFAULT_THRESHOLD;
560        pAPConnection->rssiThreshold = RSSI_DEFAULT_THRESHOLD;
561        pAPConnection->snrThreshold = SNR_DEFAULT_THRESHOLD;
562        pAPConnection->vsIElength = 0;
563        pAPConnection->isRssiTriggerMaskedOut = FALSE;
564        pAPConnection->isSnrTriggerMaskedOut = TRUE;
565        pAPConnection->islowRateTriggerMaskedOut = FALSE;
566        pAPConnection->isConsTxFailureMaskedOut = FALSE;
567        pAPConnection->removeKeys = TRUE;
568        pAPConnection->sendDeauthPacket = TRUE;       /* Default behavior is radio On - send DISASSOC frame */
569        pAPConnection->voiceTspecConfigured = FALSE;
570		pAPConnection->videoTspecConfigured = FALSE;
571        pAPConnection->resetReportedRoamingStatistics = FALSE;
572        pAPConnection->reNegotiateTSPEC = FALSE;
573        pAPConnection->bNonRoamingDisAssocReason = FALSE;
574
575        pAPConnection->roamingStartedTimestamp = 0;
576        pAPConnection->lastRoamingDelay = 0;
577        pAPConnection->roamingSuccesfulHandoverNum = 0;
578
579        return OK;
580    }
581    else/* Unable to configure State Machine */
582    {
583        WLAN_REPORT_ERROR(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("FATAL ERROR: apConn_config(): Failed to configure sm\n"));
584        return status;
585    }
586}
587
588
589/**
590*
591* apConn_isPsRequiredBeforeScan
592*
593* \b Description:
594*
595* verify if the PS required before scan according if roaming triger is part of ROAMING_TRIGGER_LOW_QUALITY_GROUP
596*
597* \b ARGS:
598*
599*  I   - hAPConnection - pointer to module\n
600*
601* \b RETURNS:
602*
603*  TRUE or FALSE.
604*
605* \sa
606*/
607BOOLEAN apConn_isPsRequiredBeforeScan(TI_HANDLE hAPConnection)
608{
609    apConn_t * pAPConnection = (apConn_t *) hAPConnection;
610
611	/* check if part of ROAMING_TRIGGER_LOW_QUALITY_GROUP */
612	if (pAPConnection->roamReason <= ROAMING_TRIGGER_MAX_TX_RETRIES)
613		return TRUE;
614	else
615		return FALSE;
616}
617
618/**
619*
620* apConn_ConnCompleteInd
621*
622* \b Description:
623*
624* Inform AP Connection about successful / unsuccessful completion
625* of link establishing
626*
627* \b ARGS:
628*
629*  I   - result - OK if successfully connected, NOK otherwise  \n
630*
631* \b RETURNS:
632*
633*  OK if successful, NOK otherwise.
634*
635* \sa
636*/
637TI_STATUS apConn_ConnCompleteInd(TI_HANDLE hAPConnection, mgmtStatus_e status, UINT32 uStatusCode)
638{
639    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
640
641    AP_CONN_VALIDATE_HANDLE(hAPConnection);
642
643    if (status == STATUS_SUCCESSFUL)
644    {
645        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
646    }
647    else
648    {
649        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection);
650    }
651    return OK;
652}
653
654
655/**
656*
657* apConn_getRoamThresholds
658*
659* \b Description:
660*
661* Used to query for the current roaming thresholds configuration
662*
663* \b ARGS:
664*
665*  I   - hAPConnection - pointer to module\n
666*  O   - pParam - pointer to buffer to store the thresholds\n
667*
668* \b RETURNS:
669*
670*  OK if successful, NOK otherwise.
671*
672* \sa
673*/
674TI_STATUS apConn_getRoamThresholds(TI_HANDLE hAPConnection, roamingMngrThresholdsConfig_t *pParam)
675{
676    apConn_t * pAPConnection = (apConn_t *) hAPConnection;
677
678    pParam->lowRssiThreshold = pAPConnection->rssiThreshold;
679    pParam->lowSnrThreshold = pAPConnection->snrThreshold;
680    pParam->txRateThreshold = pAPConnection->lowRateThreshold;
681    pParam->dataRetryThreshold = pAPConnection->txFailureThreshold;
682
683    currBSS_getRoamingParams(pAPConnection->hCurrBSS,
684                             &pParam->numExpectedTbttForBSSLoss,
685                             &pParam->lowQualityForBackgroungScanCondition,
686                             &pParam->normalQualityForBackgroungScanCondition,
687                             &pParam->rssiFilterWeight,
688                             &pParam->snrFilterWeight);
689
690    return OK;
691}
692
693
694/**
695*
696* apConn_setRoamThresholds
697*
698* \b Description:
699*
700* Used to configure roaming thresholds
701*
702* \b ARGS:
703*
704*  I   - pParam - pointer to type and details of configuration request\n
705*
706* \b RETURNS:
707*
708*  OK if successful, NOK otherwise.
709*
710* \sa
711*/
712TI_STATUS apConn_setRoamThresholds(TI_HANDLE hAPConnection, roamingMngrThresholdsConfig_t *pParam)
713{
714    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
715
716    AP_CONN_VALIDATE_HANDLE(hAPConnection);
717
718    /* If low quality trigger threshold is set to 0 - this is the request to ignore this trigger */
719    /* Otherwise store it */
720    if (pParam->lowRssiThreshold == (INT8)AP_CONNECT_TRIGGER_IGNORED)
721    {
722        pAPConnection->isRssiTriggerMaskedOut = TRUE;
723        pParam->lowRssiThreshold = pAPConnection->rssiThreshold;
724    }
725    else
726    {
727        pAPConnection->isRssiTriggerMaskedOut = FALSE;
728        pAPConnection->rssiThreshold = pParam->lowRssiThreshold;
729    }
730
731    if (pParam->txRateThreshold == AP_CONNECT_TRIGGER_IGNORED)
732    {
733        pAPConnection->islowRateTriggerMaskedOut = TRUE;
734        pParam->txRateThreshold = pAPConnection->lowRateThreshold;
735    }
736    else
737    {
738        pAPConnection->islowRateTriggerMaskedOut = FALSE;
739        pAPConnection->lowRateThreshold = pParam->txRateThreshold;
740    }
741
742    if (pParam->dataRetryThreshold == AP_CONNECT_TRIGGER_IGNORED)
743    {
744        pAPConnection->isConsTxFailureMaskedOut = TRUE;
745        pParam->dataRetryThreshold = pAPConnection->txFailureThreshold;
746    }
747    else
748    {
749        pAPConnection->isConsTxFailureMaskedOut = FALSE;
750        pAPConnection->txFailureThreshold = pParam->dataRetryThreshold;
751    }
752
753    if (pParam->rssiFilterWeight == (UINT8)AP_CONNECT_TRIGGER_IGNORED)
754    {
755        pParam->rssiFilterWeight = RSSI_DEFAULT_WEIGHT;
756    }
757
758    if (pParam->snrFilterWeight == (UINT8)AP_CONNECT_TRIGGER_IGNORED)
759    {
760        pParam->snrFilterWeight = SNR_DEFAULT_WEIGHT;
761    }
762
763    pAPConnection->isSnrTriggerMaskedOut = FALSE;
764    pAPConnection->snrThreshold = pParam->lowSnrThreshold;
765
766    currBSS_updateRoamingTriggers(pAPConnection->hCurrBSS, pParam);
767
768    rateAdaptation_configLowRateThrsh(pAPConnection->hRateAdapt,pParam->txRateThreshold);
769
770    return OK;
771}
772
773/**
774*
775* apConn_registerRoamMngrCallb
776*
777* \b Description:
778*
779* Used to store method of Roaming Manager in the internal database of AP Connection Module.
780* If this function was never called, any roaming event would cause disconnect.
781*
782* \b ARGS:
783*
784*  I   - callbackType - type of callback \n
785*  I   - callbackFunction - pointer to callback \n
786*
787* \b RETURNS:
788*
789*  OK if successful, NOK otherwise.
790*
791* \sa
792*/
793TI_STATUS apConn_registerRoamMngrCallb(TI_HANDLE hAPConnection,
794                                       apConn_roamMngrCallb_t roamEventCallb,
795                                       apConn_roamMngrCallb_t reportStatusCallb,
796                                       apConn_roamMngrCallb_t returnNeighborApsCallb)
797{
798    apConn_t *pAPConnection;
799    apConn_connStatus_t reportStatus;
800    paramInfo_t param;
801
802    AP_CONN_VALIDATE_HANDLE(hAPConnection);
803
804    pAPConnection = (apConn_t *)hAPConnection;
805
806    pAPConnection->roamEventCallb = roamEventCallb;
807    pAPConnection->reportStatusCallb = reportStatusCallb;
808    if ((pAPConnection->roamingEnabled) && (pAPConnection->currentState != AP_CONNECT_STATE_IDLE))
809    {
810        param.paramType   = ASSOC_ASSOCIATION_RESP_PARAM;
811
812        assoc_getParam(pAPConnection->hAssoc, &param);
813        reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer);
814        reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize;
815
816        reportStatus.status = CONN_STATUS_CONNECTED;
817        reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
818    }
819    ((apConn_t *)hAPConnection)->returnNeighborApsCallb = returnNeighborApsCallb;
820
821    return OK;
822}
823
824
825/**
826*
827* apConn_unregisterRoamMngrCallb
828*
829* \b Description:
830*
831* Used to Erase methods of Roaming Manager from the internal database of AP Connection
832* module. From the moment this function was called, any roaming event would cause disconnect.
833*
834* \b ARGS:
835*
836* \b RETURNS:
837*
838*  OK if successful, NOK otherwise.
839*
840* \sa
841*/
842TI_STATUS apConn_unregisterRoamMngrCallb(TI_HANDLE hAPConnection)
843{
844    apConn_t *pAPConnection;
845
846    AP_CONN_VALIDATE_HANDLE(hAPConnection);
847
848        pAPConnection = (apConn_t *)hAPConnection;
849
850        pAPConnection->roamEventCallb = NULL;
851        pAPConnection->reportStatusCallb = NULL;
852        pAPConnection->returnNeighborApsCallb = NULL;
853
854    if ((pAPConnection->currentState != AP_CONNECT_STATE_IDLE) && (pAPConnection->currentState != AP_CONNECT_STATE_WAIT_ROAM))
855    {
856        /* Roaming Manager is unregistering it's callbacks in the middle of roaming - disconnect */
857        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
858    }
859    return OK;
860}
861
862
863/**
864*
865* apConn_disconnect
866*
867* \b Description:
868*
869* Roaming Manager calls this function when it fails to find candidate for roaming from
870* one hand, and the connection with current AP is not possible from another.
871*
872* \b ARGS:
873*
874* \b RETURNS:
875*
876*  OK if successful, NOK otherwise.
877*
878* \sa
879*/
880TI_STATUS apConn_disconnect(TI_HANDLE hAPConnection)
881{
882    apConn_t *pAPConnection;
883
884    AP_CONN_VALIDATE_HANDLE(hAPConnection);
885
886    pAPConnection = (apConn_t *)hAPConnection;
887
888    UPDATE_SEND_DEAUTH_PACKET_FLAG(pAPConnection->roamReason);
889    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
890    pAPConnection->disconnectFromRoamMngrNum++;
891
892    return OK;
893}
894
895
896/**
897*
898* apConn_getStaCapabilities
899*
900* \b Description:
901*
902* Roaming Manager calls this function during selection of new candidate for roaming.
903* Returned are local Station capabilities (IEs) of quality and privacy, needed to
904* evaluate AP sites as suitable for roaming.
905*
906* \b ARGS:
907*
908*  O   - ie_list - station capabilities \n
909*
910* \b RETURNS:
911*
912*  OK if successful, NOK otherwise.
913*
914* \sa
915*/
916TI_STATUS apConn_getStaCapabilities(TI_HANDLE hAPConnection,
917                                    apConn_staCapabilities_t *ie_list)
918{
919    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
920    apConn_staCapabilities_t *pList;
921    paramInfo_t param;
922
923    AP_CONN_VALIDATE_HANDLE(hAPConnection);
924
925        pList = ie_list;
926
927    /* Get authentication suite type */
928    param.paramType = RSN_EXT_AUTHENTICATION_MODE;
929    rsn_getParam(pAPConnection->hPrivacy, &param);
930
931    switch (param.content.rsnExtAuthneticationMode)
932    {
933        case RSN_EXT_AUTH_MODE_OPEN:
934            pList->authMode = os802_11AuthModeOpen;
935            break;
936        case RSN_EXT_AUTH_MODE_SHARED_KEY:
937            pList->authMode = os802_11AuthModeShared;
938            break;
939        case RSN_EXT_AUTH_MODE_AUTO_SWITCH:
940            pList->authMode = os802_11AuthModeAutoSwitch;
941            break;
942        case RSN_EXT_AUTH_MODE_WPA:
943            pList->authMode = os802_11AuthModeWPA;
944            break;
945        case RSN_EXT_AUTH_MODE_WPAPSK:
946            pList->authMode = os802_11AuthModeWPAPSK;
947            break;
948        case RSN_EXT_AUTH_MODE_WPANONE:
949            pList->authMode = os802_11AuthModeWPANone;
950            break;
951        case RSN_EXT_AUTH_MODE_WPA2:
952            pList->authMode = os802_11AuthModeWPA2;
953            break;
954        case RSN_EXT_AUTH_MODE_WPA2PSK:
955            pList->authMode = os802_11AuthModeWPA2PSK;
956            break;
957        default:
958            pList->authMode = os802_11AuthModeOpen;
959            break;
960    }
961
962    /* Get encryption type */
963    param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
964    rsn_getParam(pAPConnection->hPrivacy, &param);
965
966    switch (param.content.rsnEncryptionStatus)
967    {
968        case RSN_CIPHER_NONE:
969            pList->encryptionType = OS_ENCRYPTION_TYPE_NONE;
970            break;
971        case RSN_CIPHER_WEP:
972        case RSN_CIPHER_WEP104:
973            pList->encryptionType = OS_ENCRYPTION_TYPE_WEP;
974            break;
975        case RSN_CIPHER_TKIP:
976        case RSN_CIPHER_CKIP:
977            pList->encryptionType = OS_ENCRYPTION_TYPE_TKIP;
978            break;
979        case RSN_CIPHER_AES_WRAP:
980        case RSN_CIPHER_AES_CCMP:
981            pList->encryptionType = OS_ENCRYPTION_TYPE_AES;
982            break;
983        default:
984            pList->encryptionType = OS_ENCRYPTION_TYPE_NONE;
985            break;
986    }
987
988    /* Get supported rates */
989    param.paramType = SITE_MGR_DESIRED_SUPPORTED_RATE_SET_PARAM;
990    siteMgr_getParam(pAPConnection->hSiteMgr, &param);
991    os_memoryCopy(pAPConnection->hOs, (void *)param.content.siteMgrDesiredSupportedRateSet.ratesString, pList->rateMask, sizeof(OS_802_11_RATES_EX));
992
993    /* Get mode: 2.4G, 5G or Dual */
994    param.paramType = SITE_MGR_DESIRED_DOT11_MODE_PARAM;
995    siteMgr_getParam(pAPConnection->hSiteMgr, &param);
996    pList->networkType = (OS_802_11_NETWORK_TYPE)param.content.siteMgrDot11Mode;
997    switch(param.content.siteMgrDot11Mode)
998    {
999        case DOT11_B_MODE:
1000            pList->networkType = os802_11DS;
1001            break;
1002        case DOT11_A_MODE:
1003            pList->networkType = os802_11OFDM5;
1004            break;
1005        case DOT11_G_MODE:
1006            pList->networkType = os802_11OFDM24;
1007            break;
1008        case DOT11_DUAL_MODE:
1009            pList->networkType = os802_11Automode;
1010            break;
1011        default:
1012            pList->networkType = os802_11DS;
1013            break;
1014    }
1015
1016
1017    /* Get EXC status */
1018#ifdef EXC_MODULE_INCLUDED
1019    param.paramType = EXC_ENABLED;
1020    excMngr_getParam(pAPConnection->hExcMngr, &param);
1021    pList->excEnabled = (param.content.excEnabled==EXC_MODE_ENABLED)? TRUE : FALSE;
1022#else
1023    pList->excEnabled = FALSE;
1024#endif
1025
1026    /* Get QoS type */
1027    param.paramType = QOS_MNGR_ACTIVE_PROTOCOL;
1028    qosMngr_getParams(pAPConnection->hQos, &param);
1029    pList->qosEnabled = (param.content.qosSiteProtocol==NONE_QOS)? FALSE : TRUE;
1030
1031    pList->regDomain = REG_DOMAIN_FIXED;
1032    /* Get regulatory domain type */
1033    param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
1034    regulatoryDomain_getParam(pAPConnection->hRegulatoryDomain, &param);
1035    if (param.content.spectrumManagementEnabled)
1036    {   /* 802.11h is enabled (802.11h includes 802.11d) */
1037        pList->regDomain = REG_DOMAIN_80211H;
1038    }
1039    else
1040    {
1041    param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM;
1042    regulatoryDomain_getParam(pAPConnection->hRegulatoryDomain, &param);
1043        if (param.content.regulatoryDomainEnabled)
1044        {   /* 802.11d is enabled */
1045            pList->regDomain = REG_DOMAIN_80211D;
1046        }
1047    }
1048    return OK;
1049}
1050
1051
1052/**
1053*
1054* apConn_connectToAP
1055*
1056* \b Description:
1057*
1058* Roaming Manager calls this function when it has completed the process of selection
1059* of new AP candidate for roaming. In addition, Roaming manager informs AP Connection
1060* module whether this is new AP or the current one, and whether to perform full
1061* roaming procedure or just to retain to current AP.
1062*
1063* \b ARGS:
1064*
1065*  I   - requestType - Connect to new AP, current AP (retain to current AP or re-connect) \n
1066*  I   - newAP - Pointer to parameters list of AP candidate for roaming \n
1067*
1068* \b RETURNS:
1069*
1070*  OK if successful, NOK otherwise.
1071*
1072* \sa
1073*/
1074TI_STATUS apConn_connectToAP(TI_HANDLE hAPConnection,
1075                             bssEntry_t *newAP,
1076                             apConn_connRequest_t *request,
1077                             BOOL reNegotiateTspec)
1078{
1079    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1080
1081    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1082
1083    pAPConnection->requestType = request->requestType;
1084
1085    switch (request->requestType)
1086    {
1087        case AP_CONNECT_RETAIN_CURR_AP:
1088            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_RETAIN_CURRENT_AP, pAPConnection);
1089            break;
1090
1091        case AP_CONNECT_FULL_TO_AP:
1092            pAPConnection->removeKeys = TRUE;
1093            pAPConnection->newAP = newAP;
1094            pAPConnection->roamingFailedHandoverNum++;
1095            pAPConnection->reNegotiateTSPEC = reNegotiateTspec;
1096            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_ROAM, pAPConnection);
1097            break;
1098
1099        case AP_CONNECT_FAST_TO_AP:
1100        case AP_CONNECT_RECONNECT_CURR_AP:
1101            pAPConnection->removeKeys = FALSE;
1102            pAPConnection->newAP = newAP;
1103            pAPConnection->roamingFailedHandoverNum++;
1104            pAPConnection->reNegotiateTSPEC = reNegotiateTspec;
1105            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_ROAM, pAPConnection);
1106            break;
1107
1108        default:
1109            break;
1110    }
1111
1112    /* If there is vendor specific IE to attach to Assoc req, store it now */
1113    if (request->dataBufLength > 0)
1114    {
1115        pAPConnection->vsIEbuf = request->dataBuf;
1116        pAPConnection->vsIElength = request->dataBufLength;
1117    }
1118
1119    return OK;
1120}
1121
1122
1123/**
1124*
1125* apConn_getBSSParams
1126*
1127* \b Description:
1128*
1129* Roaming Manager calls this function in order to evaluate the quality of new
1130* AP candidates for roaming against the quality of current AP.
1131* The function returns parameters of current AP.
1132*
1133* \b ARGS:
1134*
1135*  O   - currentAP - Pointer to parameters list of current AP \n
1136*
1137* \b RETURNS:
1138*
1139*  Pointer to current BSS parameters database if successful, NULL otherwise.
1140*
1141* \sa
1142*/
1143bssEntry_t *apConn_getBSSParams(TI_HANDLE hAPConnection)
1144{
1145#ifdef TI_DBG
1146    if (hAPConnection == NULL) /* Failed to allocate control block */
1147    {
1148        WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n"));
1149        return NULL;
1150    }
1151#endif
1152
1153    return currBSS_getBssInfo(((apConn_t *)hAPConnection)->hCurrBSS);
1154}
1155
1156
1157/**
1158 *
1159 * apConn_isSiteBanned
1160 *
1161 * \b Description:
1162 *
1163 * Roaming Manager calls this function during selection of new candidate for roaming.
1164 * Only APs which are not marked as banned are allowed to be selected.
1165 *
1166 * \b ARGS:
1167 *
1168 *  O   - givenAp - Pointer to BSSID to check if banned \n
1169 *
1170 * \b RETURNS:
1171 *
1172 *  TRUE if banned, FALSE otherwise.
1173 *
1174 * \sa
1175 */
1176BOOL apConn_isSiteBanned(TI_HANDLE hAPConnection, macAddress_t * givenAp)
1177{
1178    apConn_t * pAPConnection = (apConn_t *) hAPConnection;
1179
1180    return rsn_isSiteBanned(pAPConnection->hPrivacy, *givenAp);
1181}
1182
1183
1184/**
1185*
1186* apConn_getPreAuthAPStatus
1187*
1188* \b Description:
1189*
1190* Roaming Manager calls this function during selection of new candidate for roaming.
1191* Among all APs with good quality, those who were pre-authenticated are preferred.
1192*
1193* \b ARGS:
1194*
1195*  O   - givenAp - Pointer to BSSID to check the pre-authenticated status for \n
1196*
1197* \b RETURNS:
1198*
1199*  OK if successful, NOK otherwise.
1200*
1201* \sa
1202*/
1203BOOL apConn_getPreAuthAPStatus(TI_HANDLE hAPConnection,
1204                              macAddress_t *givenAp)
1205{
1206    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1207    paramInfoPartial_t   param;
1208
1209    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1210
1211    param.paramType = RSN_PRE_AUTH_STATUS;
1212    os_memoryCopy(pAPConnection->hOs, (void *)param.content.rsnApMac.addr, (void *)givenAp->addr, MAC_ADDR_LEN);
1213    rsn_getParamPartial(pAPConnection->hPrivacy, &param);
1214
1215    return param.content.rsnPreAuthStatus;
1216}
1217
1218
1219/**
1220*
1221* apConn_preAuthenticate
1222*
1223* \b Description:
1224*
1225* Roaming Manager calls this function periodically in order to update the list
1226* of pre-authenticated APs. The list is managed by WLAN driver and required
1227* by Roaming Manager during selection of roaming candidate process.
1228*
1229* \b ARGS:
1230*
1231*  I   - listAPs - List of APs to pre-authenticate \n
1232*  I   - sizeOfList - Size of list of APs to pre-authenticate \n
1233*
1234* \b RETURNS:
1235*
1236*  OK if successful, NOK otherwise.
1237*
1238* \sa
1239*/
1240TI_STATUS apConn_preAuthenticate(TI_HANDLE hAPConnection, bssList_t *listAPs, UINT8 listAPs_numOfEntries)
1241{
1242    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1243    bssidList4PreAuth_t apList;
1244    UINT32              listIndex, apListIndex;
1245    bssEntry_t          *pCurrentAP;
1246    UINT8               *pRsnIEs;
1247
1248#ifdef TI_DBG
1249    if ((hAPConnection == NULL) || (listAPs == NULL))
1250    {
1251        WLAN_OS_REPORT(("FATAL ERROR: AP Connection context is not initiated\n"));
1252        return NOK;
1253    }
1254
1255        WLAN_REPORT_INFORMATION(pAPConnection->hReport, SITE_MGR_MODULE_LOG, ("apConn_reserveResources \n"));
1256#endif
1257
1258	if (listAPs_numOfEntries != 0) {
1259		for (listIndex=0, apListIndex=0; listIndex<listAPs->numOfEntries; listIndex++)
1260		{
1261			os_memoryCopy(pAPConnection->hOs, &(apList.bssidList[apListIndex].bssId),
1262						  (void *)listAPs->BSSList[listIndex].BSSID.addr, MAC_ADDR_LEN);
1263
1264			/* search in the buffer pointer to the beginning of the
1265				RSN IE according to the IE ID */
1266			if (!parseIeBuffer(pAPConnection->hOs, listAPs->BSSList[listIndex].pBuffer, listAPs->BSSList[listIndex].bufferLength, RSN_IE_ID, &pRsnIEs, NULL, 0))
1267			{
1268				WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1269									  ("apConn_preAuthenticate, no RSN IE was found \n"));
1270				WLAN_REPORT_HEX_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1271									  listAPs->BSSList[listIndex].pBuffer, listAPs->BSSList[listIndex].bufferLength);
1272
1273				continue;
1274			}
1275
1276			apList.bssidList[apListIndex].pRsnIEs = (dot11_RSN_t*)pRsnIEs;
1277			apList.bssidList[apListIndex].rsnIeLen = apList.bssidList[apListIndex].pRsnIEs->hdr.eleLen+2;
1278			apListIndex++;
1279		}
1280	}
1281        else
1282        {
1283           listIndex=0;
1284           apListIndex=0;
1285         }
1286
1287    /* Start pre-auth after any Conn succ (including first),
1288    and not only when a New BSSID was added, in order to save/refresh
1289    PMKID of the current AP.*/
1290    {
1291        /* Add the current BSSID to the list */
1292        pCurrentAP = apConn_getBSSParams(pAPConnection);
1293        os_memoryCopy(pAPConnection->hOs, &(apList.bssidList[apListIndex].bssId),
1294                      (void *)pCurrentAP->BSSID.addr, MAC_ADDR_LEN);
1295        /* search in the buffer pointer to the beginning of the
1296            RSN IE according to the IE ID */
1297
1298        if (!parseIeBuffer(pAPConnection->hOs, pCurrentAP->pBuffer, pCurrentAP->bufferLength, RSN_IE_ID, &pRsnIEs, NULL, 0))
1299        {
1300            WLAN_REPORT_ERROR(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1301                                  ("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",
1302                                   pCurrentAP->BSSID.addr[0], pCurrentAP->BSSID.addr[1], pCurrentAP->BSSID.addr[2],
1303                                   pCurrentAP->BSSID.addr[3], pCurrentAP->BSSID.addr[4], pCurrentAP->BSSID.addr[5]));
1304            HexDumpData(pCurrentAP->pBuffer, pCurrentAP->bufferLength);
1305            apList.bssidList[apListIndex].pRsnIEs = NULL;
1306            apList.bssidList[apListIndex].rsnIeLen = 0;
1307        }
1308        else
1309        {
1310            apList.bssidList[apListIndex].pRsnIEs = (dot11_RSN_t*)pRsnIEs;
1311            apList.bssidList[apListIndex].rsnIeLen = apList.bssidList[apListIndex].pRsnIEs->hdr.eleLen+2;
1312        }
1313        apList.NumOfItems = apListIndex+1;
1314        rsn_startPreAuth(pAPConnection->hPrivacy, &apList);
1315    }
1316    return OK;
1317}
1318
1319
1320/**
1321*
1322* apConn_prepareToRoaming
1323*
1324* \b Description:
1325*
1326* Roaming Manager calls this function when roaming event is received and Roaming Manager
1327* wishes to start the roaming process, thus want to prevent scan and measurement in the
1328* system. The function will return OK if the allocation is performed, PEND if the
1329* allocation is started, NOK in case the allocation is not possible.
1330* In case of successful allocation, Roaming Manager will be informed via callback about
1331* the end of the allocation.
1332*
1333* \b ARGS:
1334*
1335*  I   - reason - the reason for roaming \n
1336*
1337* \b RETURNS:
1338*
1339*  OK if successful, NOK otherwise.
1340*
1341* \sa
1342*/
1343TI_STATUS apConn_prepareToRoaming(TI_HANDLE hAPConnection, apConn_roamingTrigger_e reason)
1344{
1345    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1346
1347    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1348
1349    pAPConnection->roamReason = reason;
1350
1351    return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_PREPARE_FOR_ROAMING, pAPConnection);
1352}
1353
1354/**
1355*
1356* apConn_indicateSwitchChannelInProgress
1357*
1358* \b Description:
1359*
1360* This function is called when switch channel process is started; it will trigger
1361* AP Connection state machine from 'Wait for roaming start' to 'Switch channel in progress'
1362* state.
1363*
1364* \b ARGS:
1365*
1366*  I   - reason - the reason for roaming \n
1367*
1368* \b RETURNS:
1369*
1370*  OK if successful, NOK otherwise.
1371*
1372* \sa
1373*/
1374TI_STATUS apConn_indicateSwitchChannelInProgress(TI_HANDLE hAPConnection)
1375{
1376    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1377
1378    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1379
1380    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_SWITCH_CHANNEL, pAPConnection);
1381    return OK;
1382}
1383
1384
1385/**
1386*
1387* apConn_indicateSwitchChannelFinished
1388*
1389* \b Description:
1390*
1391* This function is called when switch channel process is finished
1392*
1393* \b ARGS:
1394*
1395*  I   - reason - the reason for roaming \n
1396*
1397* \b RETURNS:
1398*
1399*  OK if successful, NOK otherwise.
1400*
1401* \sa
1402*/
1403TI_STATUS apConn_indicateSwitchChannelFinished(TI_HANDLE hAPConnection)
1404{
1405    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1406
1407    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1408
1409    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_SWITCH_CH, pAPConnection);
1410
1411    return OK;
1412}
1413
1414
1415/**
1416*
1417* apConn_start
1418*
1419* \b Description:
1420*
1421* Called by SME module when new connection has been successfully established (first time connection)
1422*
1423* \b ARGS:
1424*
1425*  I   - isValidBSS - if FALSE, no roaming shall be performed, disconnect upon any roaming event;
1426*                   other parameters of current AP can be received from Current BSS module
1427*
1428* \b RETURNS:
1429*
1430*  OK if successful, NOK otherwise.
1431*
1432* \sa
1433*/
1434TI_STATUS apConn_start(TI_HANDLE hAPConnection, BOOLEAN roamingEnabled)
1435{
1436    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1437
1438    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1439
1440    pAPConnection->roamingEnabled = roamingEnabled;
1441
1442    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START, pAPConnection);
1443    return OK;
1444}
1445
1446
1447/**
1448*
1449* apConn_stop
1450*
1451* \b Description:
1452*
1453* Called by SME module when current connection must be taken down
1454* (due to driver download, connection failure or any other reason)
1455*
1456* \b ARGS:
1457*
1458* \b RETURNS:
1459*
1460*  OK if successful, NOK otherwise.
1461*
1462* \sa
1463*/
1464TI_STATUS apConn_stop(TI_HANDLE hAPConnection, BOOLEAN removeKeys, BOOLEAN immediateShutdown)
1465{
1466    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1467
1468    pAPConnection->stopFromSmeNum++;
1469    pAPConnection->removeKeys = removeKeys;
1470    pAPConnection->sendDeauthPacket = !(immediateShutdown); /* If immediateShutdown is TRUE, no need to send DISASSOC frame - used during unload process */
1471    pAPConnection->reNegotiateTSPEC = FALSE;
1472    pAPConnection->voiceTspecConfigured = FALSE;
1473	pAPConnection->videoTspecConfigured = FALSE;
1474
1475    /* Mark that the connection is stopped due to reason outside the scope of this module */
1476    pAPConnection->bNonRoamingDisAssocReason = TRUE;
1477
1478    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
1479    return OK;
1480}
1481
1482/**
1483*
1484* apConn_reportRoamingEventDisconnect
1485*
1486* \b Description:
1487*
1488* Called by Roaming Manager to inform of Disconnect
1489*   uStatusCode - status code of deauth/disassoc packet
1490*   bDeAuthenticate - Whether this packet is DeAuth ( if
1491*                     DisAssoc than FALSE)
1492*
1493* \b ARGS:
1494*
1495*
1496* \b RETURNS:
1497*
1498*  OK if successful, NOK otherwise.
1499*
1500* \sa
1501*/
1502TI_STATUS apConn_reportRoamingEventDisconnect(TI_HANDLE hAPConnection,UINT16 uStatusCode,BOOLEAN  bDeAuthenticate )
1503{
1504	apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1505	roamingEventData_u RoamingEventData;
1506
1507	RoamingEventData.APDisconnect.uStatusCode = uStatusCode ; /* status code of deauth/disassoc packet */
1508	RoamingEventData.APDisconnect.bDeAuthenticate = bDeAuthenticate; /* TRUE state that it is DeAuth packet */
1509	apConn_reportRoamingEvent(pAPConnection, ROAMING_TRIGGER_AP_DISCONNECT, &RoamingEventData);
1510	return( TI_OK );
1511}
1512
1513
1514/**
1515*
1516* apConn_reportRoamingEvent
1517*
1518* \b Description:
1519*
1520* Called when one of roaming events occur
1521*
1522* \b ARGS:
1523*
1524*  I   - roamingEventType
1525*  I   - pRoamingEventData - in case of 'Tx rate' event, or AP disconnect
1526*
1527* \b RETURNS:
1528*
1529*  OK if successful, NOK otherwise.
1530*
1531* \sa
1532*/
1533TI_STATUS apConn_reportRoamingEvent(TI_HANDLE hAPConnection,
1534                                    apConn_roamingTrigger_e roamingEventType,
1535                                    roamingEventData_u *pRoamingEventData)
1536{
1537    apConn_t    *pAPConnection = (apConn_t *)hAPConnection;
1538    paramInfo_t  param;  /* parameter for retrieving BSSID */
1539
1540    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1541
1542    WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1543                          ("apConn_reportRoamingEvent, type=%d, cur_state=%d, roamingEnabled=%d, roamEventCallb=%p  \n",
1544                           roamingEventType, pAPConnection->currentState,
1545                           pAPConnection->roamingEnabled, pAPConnection->roamEventCallb));
1546
1547    /* 1. Check if this is Rogue AP test case */
1548    if (roamingEventType == ROAMING_TRIGGER_AP_DISCONNECT)
1549    {
1550        if (pRoamingEventData != NULL)
1551        {   /* Save the disconnect reason for future use */
1552            pAPConnection->APDisconnect.uStatusCode     = pRoamingEventData->APDisconnect.uStatusCode;
1553            pAPConnection->APDisconnect.bDeAuthenticate = pRoamingEventData->APDisconnect.bDeAuthenticate;
1554        }
1555        if ((pAPConnection->ignoreDeauthReason0) && (pRoamingEventData!=NULL) &&
1556               (pAPConnection->APDisconnect.uStatusCode == 0))
1557        {   /* This is required for Rogue AP test,
1558                When Rogue AP due to invalid User name, deauth with reason 0 arrives before the Rogue AP,
1559                and this EXC test fails.*/
1560            WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1561                  ("apConn_reportRoamingEvent, Ignore DeAuth with reason 0 \n"));
1562            return OK;
1563        }
1564        WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1565              ("apConn_reportRoamingEvent, DeAuth with reason %d \n", pAPConnection->APDisconnect.uStatusCode));
1566
1567        if (pAPConnection->APDisconnect.uStatusCode == STATUS_CODE_802_1X_AUTHENTICATION_FAILED)
1568        {
1569          #ifdef EXC_MODULE_INCLUDED
1570            TI_STATUS    status;
1571
1572            /* Raise the EAP-Failure as event */
1573            status = excMngr_rogueApDetected (pAPConnection->hExcMngr, RSN_AUTH_STATUS_CHALLENGE_FROM_AP_FAILED);
1574          #endif
1575
1576
1577            /* Remove AP from candidate list for a specified amount of time */
1578            param.paramType = SITE_MGR_CURRENT_BSSID_PARAM;
1579            siteMgr_getParam(pAPConnection->hSiteMgr, &param);
1580
1581            WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1582                 ("current station is banned from the roaming candidates list for %d Ms\n",
1583                  RSN_AUTH_FAILURE_TIMEOUT));
1584
1585            rsn_banSite(pAPConnection->hPrivacy, param.content.siteMgrDesiredBSSID, RSN_SITE_BAN_LEVEL_FULL, RSN_AUTH_FAILURE_TIMEOUT);
1586        }
1587
1588    }
1589
1590    /* 2. Check if received trigger is masked out */
1591    if (((pAPConnection->isConsTxFailureMaskedOut) && (roamingEventType == ROAMING_TRIGGER_MAX_TX_RETRIES)) ||
1592        ((pAPConnection->isRssiTriggerMaskedOut)   && (roamingEventType == ROAMING_TRIGGER_LOW_QUALITY)) ||
1593        ((pAPConnection->isSnrTriggerMaskedOut)    && (roamingEventType == ROAMING_TRIGGER_LOW_SNR)) ||
1594        ((pAPConnection->islowRateTriggerMaskedOut)&& (roamingEventType == ROAMING_TRIGGER_LOW_TX_RATE)))
1595    {
1596        WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("apConn_reportRoamingEvent, trigger ignored \n"));
1597        return OK;
1598    }
1599
1600    /* 3.  Valid trigger received: */
1601    /* 3a. Update statistics */
1602    pAPConnection->roamingTriggerEvents[roamingEventType]++;
1603
1604    /* 3b. Store the most severe trigger */
1605    if (pAPConnection->roamReason < roamingEventType)
1606    {
1607        pAPConnection->roamReason = roamingEventType;
1608    }
1609
1610    /* 3c. Check if Roaming Manager is available */
1611    if (((!pAPConnection->roamingEnabled) || (pAPConnection->roamEventCallb == NULL) ||
1612          (pAPConnection->currentState == AP_CONNECT_STATE_IDLE))
1613        && (roamingEventType > ROAMING_TRIGGER_LOW_QUALITY)
1614        && (roamingEventType != ROAMING_TRIGGER_MAX_TX_RETRIES))
1615        /*
1616         * The last condition was added so that MAX_TX_RETRIES would not cause a disconnect.
1617         * This is done because the current default value for max TX retries is good enough for
1618         * roaming (i.e. it indicates a low quality AP), but would cause unnecessary disconnects
1619         * if used when roaming is disabled
1620         */
1621    {
1622        /* 'Any SSID' configured, meaning Roaming Manager is not allowed to perform roaming,
1623           or Roaming Manager is not registered for roaming events;
1624           unless this is trigger to change parameters of background scan, disconnect the link */
1625        WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("Disconnecting link due to roaming event: ev = %d\n", roamingEventType));
1626
1627        /*  Handle IBSS case TBD to remove
1628            Handle also the case where A first connection is in progress, and
1629            de-auth arrived. */
1630        if (pAPConnection->currentState == AP_CONNECT_STATE_IDLE)
1631        {
1632            apConn_reportConnStatusToSME(pAPConnection);
1633        }
1634        else
1635        {
1636            /* Infra-structure BSS case - disconnect the link */
1637            if (roamingEventType >= ROAMING_TRIGGER_AP_DISCONNECT)
1638            {
1639                pAPConnection->removeKeys = TRUE;
1640            }
1641            else
1642            {
1643                pAPConnection->removeKeys = FALSE;
1644            }
1645            UPDATE_SEND_DEAUTH_PACKET_FLAG(roamingEventType);
1646            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
1647        }
1648        return OK;
1649    }
1650
1651    /* 4. Check if we are in the middle of switching channel */
1652    if (pAPConnection->currentState == AP_CONNECT_STATE_SWITCHING_CHANNEL)
1653    {
1654        /* Trigger received in the middle of switch channel, continue without reporting Roaming Manager */
1655        WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("Roaming event during switch channel: ev = %d\n", roamingEventType));
1656        return OK;
1657    }
1658
1659    /* 5. Report Roaming Manager */
1660    if ((pAPConnection->roamingEnabled == TRUE) && (pAPConnection->roamEventCallb != NULL))
1661    {
1662        WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("Roaming event raised: ev = %d\n", roamingEventType));
1663        if (roamingEventType == ROAMING_TRIGGER_LOW_QUALITY)
1664        {
1665            EvHandlerSendEvent(pAPConnection->hEvHandler, IPC_EVENT_LOW_RSSI, NULL,0);
1666        }
1667        /* Report to Roaming Manager */
1668        pAPConnection->roamEventCallb(pAPConnection->hRoamMng, &roamingEventType);
1669    }
1670
1671    return OK;
1672}
1673
1674
1675/**
1676*
1677* apConn_RoamHandoffFinished
1678*
1679* \b Description:
1680*
1681* Called when EXC module receives response from the supplicant or recognizes
1682* timeout while waiting for the response
1683*
1684* \b ARGS:
1685*
1686* \b RETURNS:
1687*
1688* \sa
1689*/
1690void apConn_RoamHandoffFinished(TI_HANDLE hAPConnection)
1691{
1692    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1693
1694#ifdef TI_DBG
1695    if (hAPConnection == NULL) /* Failed to allocate control block */
1696    {
1697        WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n"));
1698        return;
1699    }
1700#endif
1701
1702    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_HAND_OVER, pAPConnection);
1703}
1704
1705
1706/**
1707*
1708* apConn_DisconnCompleteInd
1709*
1710* \b Description:
1711*
1712* DISASSOCIATE Packet was sent - proceed with stopping the module
1713*
1714* \b ARGS:
1715*
1716*  I   - pData - pointer to AP Connection context\n
1717*
1718* \b RETURNS:
1719*
1720*  OK on success, NOK otherwise.
1721*
1722* \sa
1723*/
1724TI_STATUS apConn_DisconnCompleteInd(TI_HANDLE hAPConnection, mgmtStatus_e status, UINT32 uStatusCode)
1725{
1726    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1727
1728    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1729
1730    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
1731
1732    return OK;
1733}
1734
1735
1736/**
1737*
1738* apConn_updateNeighborAPsList
1739*
1740* \b Description:
1741*
1742* Called by EXC Manager when Priority APs are found
1743*
1744* \b ARGS:
1745*
1746* \b RETURNS:
1747*
1748*  OK if successful, NOK otherwise.
1749*
1750* \sa
1751*/
1752void apConn_updateNeighborAPsList(TI_HANDLE hAPConnection, neighborAPList_t *pListOfpriorityAps)
1753{
1754    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1755
1756    if (pAPConnection->returnNeighborApsCallb != NULL )
1757    {
1758        pAPConnection->returnNeighborApsCallb(pAPConnection->hRoamMng, pListOfpriorityAps);
1759    }
1760}
1761
1762
1763/**
1764*
1765* apConn_getRoamingStatistics
1766*
1767* \b Description:
1768*
1769* Called from Measurement EXC sub-module when preparing TSM report to the AP.
1770*
1771* \b ARGS: AP Connection handle
1772*
1773* \b RETURNS:
1774*
1775*  total number of successful roams
1776*  delay of the latest successful roam
1777*
1778* \sa
1779*/
1780void apConn_getRoamingStatistics(TI_HANDLE hAPConnection, UINT8 *roamingCount, UINT16 *roamingDelay)
1781{
1782    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1783
1784    /* Get (and clear) total number of successful roams */
1785    *roamingCount = pAPConnection->roamingSuccesfulHandoverNum;
1786    pAPConnection->roamingSuccesfulHandoverNum = 0;
1787
1788    /* Get delay of the latest roam */
1789    *roamingDelay = pAPConnection->lastRoamingDelay;
1790    pAPConnection->lastRoamingDelay = 0;
1791}
1792
1793
1794
1795
1796/**
1797*
1798* apConn_resetRoamingStatistics
1799*
1800* \b Description:
1801*
1802* Called from Measurement EXC sub-module in order to re-start roaming statistics.
1803*
1804* \b ARGS: AP Connection handle
1805*
1806* \b RETURNS:
1807*
1808*  total number of successful roams
1809*  delay of the latest successful roam
1810*
1811* \sa
1812*/
1813void apConn_resetRoamingStatistics(TI_HANDLE hAPConnection)
1814{
1815    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1816
1817    pAPConnection->resetReportedRoamingStatistics = TRUE;
1818    pAPConnection->roamingSuccesfulHandoverNum = 0;
1819    pAPConnection->lastRoamingDelay = 0;
1820}
1821
1822
1823/**
1824*
1825* apConn_stopRoamingStatistics
1826*
1827* \b Description:
1828*
1829* Called from Measurement CCX sub-module in order to stop roaming statistics.
1830*
1831* \b ARGS: AP Connection handle
1832*
1833* \b RETURNS:
1834*
1835* \sa
1836*/
1837void apConn_stopRoamingStatistics(TI_HANDLE hAPConnection)
1838{
1839    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1840
1841    pAPConnection->resetReportedRoamingStatistics = FALSE;
1842}
1843
1844
1845/**
1846*
1847* apConn_printStatistics
1848*
1849* \b Description:
1850*
1851* Called by Site Manager when request to print statistics is requested from CLI
1852*
1853* \b ARGS: AP Connection handle
1854*
1855* \b RETURNS:
1856*
1857*  OK if successful, NOK otherwise.
1858*
1859* \sa
1860*/
1861void apConn_printStatistics(TI_HANDLE hAPConnection)
1862{
1863    WLAN_OS_REPORT(("-------------- Roaming Statistics ---------------\n\n"));
1864    WLAN_OS_REPORT(("- Low TX rate = %d\n",     ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_TX_RATE]));
1865    WLAN_OS_REPORT(("- Low SNR = %d\n",         ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_SNR]));
1866    WLAN_OS_REPORT(("- Low Quality = %d\n",     ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_QUALITY]));
1867    WLAN_OS_REPORT(("- MAX TX retries = %d\n",  ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_MAX_TX_RETRIES]));
1868    WLAN_OS_REPORT(("- BSS Loss TX = %d\n",     ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_BSS_LOSS]));
1869    WLAN_OS_REPORT(("- Switch Channel = %d\n",  ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_SWITCH_CHANNEL]));
1870    WLAN_OS_REPORT(("- AP Disconnect = %d\n",   ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_AP_DISCONNECT]));
1871    WLAN_OS_REPORT(("- SEC attack = %d\n",      ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_SECURITY_ATTACK]));
1872    WLAN_OS_REPORT(("\n"));
1873    WLAN_OS_REPORT(("- Succesfull Total roaming = %d\n",                  ((apConn_t *)hAPConnection)->roamingSuccesfulHandoverTotalNum));
1874    WLAN_OS_REPORT(("- Unsuccesfull roaming = %d\n",                ((apConn_t *)hAPConnection)->roamingFailedHandoverNum));
1875    WLAN_OS_REPORT(("- Giving up roaming = %d\n",                   ((apConn_t *)hAPConnection)->retainCurrAPNum));
1876    WLAN_OS_REPORT(("- Disconnect cmd from roaming manager = %d\n", ((apConn_t *)hAPConnection)->disconnectFromRoamMngrNum));
1877    WLAN_OS_REPORT(("- Disconnect cmd from SME = %d\n",             ((apConn_t *)hAPConnection)->stopFromSmeNum));
1878    WLAN_OS_REPORT(("\n"));
1879}
1880
1881
1882
1883/**
1884*
1885* apConn_getVendorSpecificIE
1886*
1887* \b Description:
1888*
1889* Called by Association SM when request to associate is built and sent to AP;
1890* returns request updated with vendor specific info-element
1891*
1892* \b ARGS:
1893*
1894*  I   - hAPConnection - AP Connection handle\n
1895*  O   - pRequest - pointer to request buffer\n
1896*  O   - len - size of returned IE\n
1897*
1898* \b RETURNS:
1899*
1900*  OK if successful, NOK otherwise.
1901*
1902* \sa
1903*/
1904TI_STATUS apConn_getVendorSpecificIE(TI_HANDLE hAPConnection, UINT8 *pRequest, UINT32 *len)
1905{
1906    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1907
1908    if (pAPConnection->vsIElength > 0)
1909    {
1910        *len = pAPConnection->vsIElength;
1911        os_memoryCopy(pAPConnection->hOs, pRequest, pAPConnection->vsIEbuf, pAPConnection->vsIElength);
1912    }
1913    else
1914    {
1915        *len = 0;
1916    }
1917    return OK;
1918}
1919
1920
1921/* Internal functions implementation */
1922
1923
1924/**
1925*
1926* apConn_smEvent
1927*
1928* \b Description:
1929*
1930* AP Connection state machine transition function
1931*
1932* \b ARGS:
1933*
1934*  I/O - currentState - current state in the state machine\n
1935*  I   - event - specific event for the state machine\n
1936*  I   - pData - pointer to AP Connection context\n
1937*
1938* \b RETURNS:
1939*
1940*  OK on success, NOK otherwise.
1941*
1942* \sa
1943*/
1944static TI_STATUS apConn_smEvent(apConn_smStates *currState, UINT8 event, void* data)
1945{
1946    TI_STATUS   status;
1947    UINT8       nextState;
1948    apConn_t    *pAPConnection;
1949
1950    pAPConnection = (apConn_t *)data;
1951    status = fsm_GetNextState(pAPConnection->apConnSM, (UINT8)*currState, event, &nextState);
1952    if (status == OK)
1953    {
1954        WLAN_REPORT_SM(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
1955                                  ("<%s, %s> --> %s\n\n",
1956                                   apConn_stateDesc[*currState],
1957                                   apConn_eventDesc[event],
1958                                   apConn_stateDesc[nextState]));
1959
1960        status = fsm_Event(pAPConnection->apConnSM, (UINT8 *)currState, event, pAPConnection);
1961        return status;
1962    }
1963    else
1964    {
1965        WLAN_REPORT_ERROR(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG, ("apConn_smEvent, fsm_GetNextState error\n"));
1966        return status;
1967    }
1968}
1969
1970
1971/**
1972*
1973* apConn_smNop - Do nothing
1974*
1975* \b Description:
1976*
1977* Do nothing in the SM.
1978*
1979* \b ARGS:
1980*
1981*  I   - pData - pointer to AP Connection context \n
1982*
1983* \b RETURNS:
1984*
1985*  OK if successful, NOK otherwise.
1986*
1987*
1988*/
1989static TI_STATUS apConn_smNop(void *pData)
1990{
1991        WLAN_REPORT_INFORMATION((((apConn_t *)pData)->hReport), ROAMING_MANAGER_MODULE_LOG, ("apConn_smNop\n"));
1992        return OK;
1993    }
1994
1995
1996/**
1997*
1998* apConn_smUnexpected - Unexpected event
1999*
2000* \b Description:
2001*
2002* Unexpected event in the SM.
2003*
2004* \b ARGS:
2005*
2006*  I   - pData - pointer to AP Connection context \n
2007*
2008* \b RETURNS:
2009*
2010*  OK if successful, NOK otherwise.
2011*
2012*
2013*/
2014static TI_STATUS apConn_smUnexpected(void *pData)
2015{
2016    WLAN_REPORT_INFORMATION(((apConn_t *)pData)->hReport, ROAMING_MANAGER_MODULE_LOG, ("apConn_smUnexpected\n"));
2017    return NOK;
2018}
2019
2020
2021/**
2022*
2023* apConn_startWaitingForTriggers
2024*
2025* \b Description:
2026*
2027* SME informs AP Connection module about successfull link establishment; start wiating for roaming triggers
2028*
2029* \b ARGS:
2030*
2031*  I   - pData - pointer to AP Connection context \n
2032*
2033* \b RETURNS:
2034*
2035*  OK on success, NOK otherwise.
2036*
2037* \sa
2038*/
2039static TI_STATUS apConn_startWaitingForTriggers(void *pData)
2040{
2041    apConn_t    *pAPConnection;
2042    apConn_connStatus_t reportStatus;
2043    paramInfoPartial_t param;
2044
2045    pAPConnection = (apConn_t *)pData;
2046
2047    if ((pAPConnection->roamingEnabled) && (pAPConnection->reportStatusCallb != NULL))
2048    {
2049        param.paramType   = ASSOC_ASSOCIATION_RESP_PARAM;
2050
2051        assoc_getParamPartial(pAPConnection->hAssoc, &param);
2052        reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer);
2053        reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize;
2054
2055        reportStatus.status = CONN_STATUS_CONNECTED;
2056        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
2057    }
2058    pAPConnection->firstAttempt2Roam = TRUE;
2059    pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
2060    pAPConnection->removeKeys = TRUE;
2061    pAPConnection->sendDeauthPacket = TRUE;
2062    pAPConnection->reNegotiateTSPEC = FALSE;
2063    pAPConnection->voiceTspecConfigured = FALSE;
2064	pAPConnection->videoTspecConfigured = FALSE;
2065    return OK;
2066}
2067
2068
2069/**
2070*
2071* apConn_connectedToNewAP
2072*
2073* \b Description:
2074*
2075* After roaming was requested, Connection SM informs AP Connection module about
2076* successful link re-establishment; start waiting for roaming triggers
2077*
2078* \b ARGS:
2079*
2080*  I   - pData - pointer to AP Connection context \n
2081*
2082* \b RETURNS:
2083*
2084*  OK on success, NOK otherwise.
2085*
2086* \sa
2087*/
2088static TI_STATUS apConn_connectedToNewAP(void *pData)
2089{
2090    apConn_t    *pAPConnection;
2091    apConn_connStatus_t reportStatus;
2092    paramInfoPartial_t param;
2093
2094    pAPConnection = (apConn_t *)pData;
2095
2096    /* Configure SCR group back to connection */
2097    scr_setGroup (pAPConnection->hScr, SCR_GID_CONNECTED);
2098
2099    /* Erase vendor specific info-element if was defined for last AP Assoc request */
2100    pAPConnection->vsIElength = 0;
2101
2102    /* TBD Notify Curr BSS module about update of current AP database */
2103
2104    if (pAPConnection->roamingFailedHandoverNum>0)
2105    {
2106        pAPConnection->roamingFailedHandoverNum--;
2107    }
2108    /* Report Roaming Manager */
2109    if (pAPConnection->reportStatusCallb != NULL)
2110    {
2111        param.paramType   = ASSOC_ASSOCIATION_RESP_PARAM;
2112
2113        assoc_getParamPartial(pAPConnection->hAssoc, &param);
2114        reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer);
2115        reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize;
2116
2117        reportStatus.status = CONN_STATUS_HANDOVER_SUCCESS;
2118
2119        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
2120    }
2121    pAPConnection->firstAttempt2Roam = TRUE;
2122    pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
2123    pAPConnection->roamingSuccesfulHandoverTotalNum++;
2124    pAPConnection->removeKeys = TRUE;
2125    pAPConnection->sendDeauthPacket = TRUE;
2126    pAPConnection->reNegotiateTSPEC = FALSE;
2127    pAPConnection->voiceTspecConfigured = FALSE;
2128	pAPConnection->videoTspecConfigured = FALSE;
2129
2130
2131    if (!pAPConnection->resetReportedRoamingStatistics)
2132    {
2133        pAPConnection->roamingSuccesfulHandoverNum++;
2134        pAPConnection->lastRoamingDelay =
2135            (UINT16)os_timeStampMs(pAPConnection->hOs) - pAPConnection->roamingStartedTimestamp;
2136    }
2137    else
2138    {
2139        pAPConnection->resetReportedRoamingStatistics = FALSE;
2140    }
2141
2142    /* Raise event of Roaming Completion */
2143    WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2144                            ("EvHandlerSendEvent -ROAMING_COMPLETE\n" ));
2145    EvHandlerSendEvent(pAPConnection->hEvHandler, IPC_EVENT_ROAMING_COMPLETE, NULL, 0);
2146
2147    return OK;
2148}
2149
2150
2151/**
2152*
2153* apConn_stopConnection
2154*
2155* \b Description:
2156*
2157* Stop required before roaming was started
2158*
2159* \b ARGS:
2160*
2161*  I   - pData - pointer to AP Connection context\n
2162*
2163* \b RETURNS:
2164*
2165*  OK on success, NOK otherwise.
2166*
2167* \sa
2168*/
2169static TI_STATUS apConn_stopConnection(void *pData)
2170{
2171    apConn_t *pAPConnection;
2172    disConnType_e disConnType;
2173    pAPConnection = (apConn_t *)pData;
2174
2175    WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2176                    ("apConn_stopConnection, calls conn_stop, removeKeys=%d, sendDeauthPacket=%d \n", pAPConnection->removeKeys, pAPConnection->sendDeauthPacket));
2177
2178    /* Erase vendor specific info-element if was defined for last AP Assoc request */
2179    pAPConnection->vsIElength = 0;
2180
2181    /* In case AP connection was stopped by SME, and radioOn is false, meaning immidiate shutdown is required without disassoc frame */
2182    /* Otherwise, ask for normal disconnection with disassoc frame */
2183    disConnType = (pAPConnection->sendDeauthPacket == TRUE) ? DISCONN_TYPE_DEAUTH : DISCONN_TYPE_IMMEDIATE;
2184
2185    /* Stop Connection state machine - always immediate TBD */
2186    conn_stop(pAPConnection->hConnSm,
2187              disConnType,
2188              STATUS_UNSPECIFIED,
2189              FALSE,   /* pAPConnection->removeKeys - for Roaming, do not remove the keys */
2190              apConn_DisconnCompleteInd,
2191              pAPConnection);
2192
2193    return OK;
2194}
2195
2196
2197/**
2198*
2199* apConn_reportDisconnected
2200*
2201* \b Description:
2202*
2203* Moving from 'Disconnecting' state to 'Idle':
2204*   RoamMgr.status("not-connected")
2205*
2206* \b ARGS:
2207*
2208*  I   - pData - pointer to AP Connection context\n
2209*
2210* \b RETURNS:
2211*
2212*  OK on success, NOK otherwise.
2213*
2214* \sa
2215*/
2216static TI_STATUS apConn_reportDisconnected(void *pData)
2217{
2218    apConn_t    *pAPConnection;
2219    apConn_connStatus_t reportStatus;
2220
2221    pAPConnection = (apConn_t *)pData;
2222
2223    if (pAPConnection->reportStatusCallb != NULL)
2224    {
2225        reportStatus.status = CONN_STATUS_NOT_CONNECTED;
2226        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
2227    }
2228
2229    pAPConnection->firstAttempt2Roam = TRUE;
2230
2231    /* Notify SME */
2232    apConn_reportConnStatusToSME(pAPConnection);
2233
2234    return OK;
2235}
2236
2237
2238/**
2239*
2240* apConn_retainAP
2241*
2242* \b Description:
2243*
2244* Roaming Manager gives up on roaming.
2245* Moving from 'Wait for connection command' back to 'Wait for roam started.
2246*
2247* \b ARGS:
2248*
2249*  I   - pData - pointer to AP Connection context\n
2250*
2251* \b RETURNS:
2252*
2253*  OK on success, NOK otherwise.
2254*
2255* \sa
2256*/
2257static TI_STATUS apConn_retainAP(void *data)
2258{
2259    apConn_t    *pAPConnection;
2260    apConn_connStatus_t reportStatus;
2261    paramInfo_t param;
2262
2263    pAPConnection = (apConn_t *)data;
2264
2265    /* Configure SCR group back to connection */
2266    scr_setGroup (pAPConnection->hScr, SCR_GID_CONNECTED);
2267
2268    /* Report Roaming Manager */
2269    if (pAPConnection->reportStatusCallb != NULL)
2270    {
2271        param.paramType   = ASSOC_ASSOCIATION_RESP_PARAM;
2272
2273        assoc_getParam(pAPConnection->hAssoc, &param);
2274        reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer);
2275        reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize;
2276
2277        reportStatus.status = CONN_STATUS_HANDOVER_SUCCESS;
2278
2279        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
2280    }
2281    pAPConnection->retainCurrAPNum++;
2282
2283    pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
2284    pAPConnection->removeKeys = TRUE;
2285    pAPConnection->sendDeauthPacket = TRUE;
2286    pAPConnection->reNegotiateTSPEC = FALSE;
2287    pAPConnection->voiceTspecConfigured = FALSE;
2288	pAPConnection->videoTspecConfigured = FALSE;
2289
2290    return OK;
2291}
2292
2293
2294/**
2295*
2296* apConn_requestCCKM
2297*
2298* \b Description:
2299*
2300* Roaming Manager requests to roaming.
2301* Get CCKM (prepare hand-off).
2302*
2303* \b ARGS:
2304*
2305*  I   - pData - pointer to AP Connection context\n
2306*
2307* \b RETURNS:
2308*
2309*  OK on success, NOK otherwise.
2310*
2311* \sa
2312*/
2313static TI_STATUS apConn_requestCCKM(void *data)
2314{
2315    apConn_t    *pAPConnection;
2316    TI_STATUS   status;
2317
2318        pAPConnection = (apConn_t *)data;
2319
2320#ifdef EXC_MODULE_INCLUDED
2321        /* Send request to EXC module */
2322    apConn_calcNewTsf(pAPConnection, (UINT8 *)&(pAPConnection->newAP->lastRxTSF), pAPConnection->newAP->lastRxHostTimestamp, pAPConnection->newAP->beaconInterval);
2323    status = excMngr_startCckm(pAPConnection->hExcMngr, &(pAPConnection->newAP->BSSID), (UINT8 *)&(pAPConnection->newAP->lastRxTSF));
2324#else
2325        status  = OK;
2326        apConn_RoamHandoffFinished(pAPConnection);
2327#endif
2328        return status;
2329    }
2330
2331
2332#ifdef EXC_MODULE_INCLUDED
2333/**
2334*
2335* calcNewTsfTimestamp - Calculates the TSF
2336*
2337* \b Description:
2338*
2339* Calculates the TSF according to the delta of the TSF from the last Beacon/Probe Resp and the current time.
2340*
2341* \b ARGS:
2342*
2343*  I   - hRoamingMngr - pointer to the roamingMngr SM context  \n
2344*  I/O - tsfTimeStamp - the TSF field in the site entry of the roaming candidate AP
2345*  I   - newSiteOsTimeStamp - the TS field in the site entry of the roaming candidate AP
2346*
2347* \b RETURNS:
2348*
2349*  Nothing.
2350*
2351*
2352*/
2353static void apConn_calcNewTsf(apConn_t *hAPConnection, UINT8 *tsfTimeStamp, UINT32 newSiteOsTimeStamp, UINT32 beaconInterval)
2354{
2355    apConn_t    *pAPConnection = hAPConnection;
2356    UINT32      osTimeStamp = os_timeStampMs(pAPConnection->hOs);
2357    UINT32      deltaTimeStamp;
2358    UINT32      tsfLsdw,tsfMsdw, newOsTimeStamp;
2359    UINT32      remainder;
2360    UINT8       newTsfTimestamp[TIME_STAMP_LEN];
2361
2362    /* get the delta TS between the TS of the last Beacon/ProbeResp-from the site table
2363    and the current TS */
2364    deltaTimeStamp = osTimeStamp - newSiteOsTimeStamp;
2365    tsfLsdw = *((UINT32*)&tsfTimeStamp[0]);
2366    tsfMsdw = *((UINT32*)&tsfTimeStamp[4]);
2367
2368    WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2369                            (" TSF time LSDW reversed=%x, TSF time MSDW reversed=%x\n",
2370                             tsfLsdw, tsfMsdw));
2371
2372    deltaTimeStamp = deltaTimeStamp*1000;/* from mSec to uSec*/
2373    /* Before adding, save remainder */
2374    remainder = tsfTimeStamp[3] + ((deltaTimeStamp & 0xff000000) >> 24);
2375
2376    /* The LS DW of the TS is the TSF taken from the last Beacon/Probe Resp
2377        + the delta TS from the time the Beacon/Probe Resp arrive till now. */
2378    newOsTimeStamp = deltaTimeStamp+tsfLsdw;
2379
2380    /* substracting one beacon interval */
2381    newOsTimeStamp -= (beaconInterval * 1024); /* im usec */
2382
2383    /* save just for debug printout */
2384    deltaTimeStamp +=osTimeStamp; /* uMsec */
2385    /* update the LSB of the TSF */
2386    newTsfTimestamp[0] = newOsTimeStamp & 0x000000ff;
2387    newTsfTimestamp[1] = (newOsTimeStamp & 0x0000ff00) >> 8;
2388    newTsfTimestamp[2] = (newOsTimeStamp & 0x00ff0000) >> 16;
2389    newTsfTimestamp[3] = (newOsTimeStamp & 0xff000000) >> 24;
2390
2391    /* increase the MSB in case of overflow */
2392    if (remainder > 0xff)
2393    {
2394        tsfMsdw++;
2395
2396    }
2397    /* update the MSB of the TSF */
2398    newTsfTimestamp[4] = tsfMsdw & 0x000000ff;
2399    newTsfTimestamp[5] = (tsfMsdw & 0x0000ff00) >> 8;
2400    newTsfTimestamp[6] = (tsfMsdw & 0x00ff0000) >> 16;
2401    newTsfTimestamp[7] = (tsfMsdw & 0xff000000) >> 24;
2402
2403    WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2404                            (" 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",
2405                             newOsTimeStamp, deltaTimeStamp, remainder,
2406                             newTsfTimestamp[0], newTsfTimestamp[1], newTsfTimestamp[2], newTsfTimestamp[3],
2407                             newTsfTimestamp[4], newTsfTimestamp[5], newTsfTimestamp[6], newTsfTimestamp[7]));
2408
2409    os_memoryCopy(pAPConnection->hOs, tsfTimeStamp, newTsfTimestamp, TIME_STAMP_LEN);
2410}
2411#endif
2412
2413
2414/**
2415*
2416* apConn_invokeConnectionToNewAp
2417*
2418* \b Description:
2419*
2420* Got CCKM (hand-off), start re-connection to another AP
2421*
2422* \b ARGS:
2423*
2424*  I   - pData - pointer to AP Connection context\n
2425*
2426* \b RETURNS:
2427*
2428*  OK on success, NOK otherwise.
2429*
2430* \sa
2431*/
2432static TI_STATUS apConn_invokeConnectionToNewAp(void *data)
2433{
2434    apConn_t    *pAPConnection;
2435    connType_e  connType;
2436    paramInfoPartial_t param;
2437    UINT8   staPrivacySupported, apPrivacySupported;
2438    BOOL    renegotiateTspec = FALSE;
2439
2440    pAPConnection = (apConn_t *)data;
2441
2442    pAPConnection->roamingStartedTimestamp = os_timeStampMs(pAPConnection->hOs);
2443
2444    /* Check privacy compatibility */
2445    param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
2446    rsn_getParamPartial(pAPConnection->hPrivacy, &param);
2447
2448    staPrivacySupported = (param.content.rsnEncryptionStatus == RSN_CIPHER_NONE) ? FALSE : TRUE;
2449    apPrivacySupported  = ((pAPConnection->newAP->capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TRUE : FALSE;
2450
2451    if (staPrivacySupported != apPrivacySupported)
2452    {
2453        param.paramType = RSN_MIXED_MODE;
2454        rsn_getParamPartial(pAPConnection->hPrivacy, &param);
2455
2456        if (apPrivacySupported ||
2457            (!param.content.rsnMixedMode && staPrivacySupported))
2458        {
2459            WLAN_REPORT_WARNING(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2460                                ("%s: failed privacy comparison %d vs. %d\n", __FUNCTION__, staPrivacySupported, apPrivacySupported));
2461            return (apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection));
2462        }
2463    }
2464
2465    /* Update data info of desired AP; in case of first attempt to roam,
2466       store previous primary site info */
2467    if (siteMgr_overwritePrimarySite(pAPConnection->hSiteMgr, pAPConnection->newAP, pAPConnection->firstAttempt2Roam) != OK)
2468    {
2469        WLAN_REPORT_WARNING(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2470                            ("%s: failed to ovewrite Primary Site\n", __FUNCTION__));
2471        return (apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection));
2472    }
2473
2474    /* Update re-associate parameter of MLME */
2475    if (pAPConnection->requestType == AP_CONNECT_FAST_TO_AP)
2476    {
2477        connType = CONN_TYPE_ROAM;
2478    }
2479    else
2480    {
2481        connType = CONN_TYPE_FIRST_CONN;
2482    }
2483
2484#ifdef EXC_MODULE_INCLUDED
2485    /* Check the need in TSPEC re-negotiation */
2486    if ( (pAPConnection->voiceTspecConfigured || pAPConnection->videoTspecConfigured)
2487		 && pAPConnection->reNegotiateTSPEC )
2488    {
2489        /* If the candidate AP is at least EXCver4 AP, try to re-negotiate TSPECs */
2490        if (excMngr_parseExcVer(pAPConnection->hExcMngr,
2491                                pAPConnection->newAP->pBuffer,
2492                                pAPConnection->newAP->bufferLength) >= 4)
2493        {
2494            renegotiateTspec = TRUE;
2495        }
2496    }
2497#endif
2498
2499    WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2500                            ("%s: calls conn_start, removeKeys=%d, renegotiateTSPEC=%d\n", __FUNCTION__,
2501                             pAPConnection->removeKeys, renegotiateTspec));
2502
2503    /* Start Connection state machine */
2504    return conn_start(pAPConnection->hConnSm,
2505                      connType,
2506                      apConn_ConnCompleteInd,
2507                      pAPConnection,
2508                      pAPConnection->removeKeys,
2509                      renegotiateTspec);
2510}
2511
2512
2513/**
2514*
2515* apConn_reportConnFail
2516*
2517* \b Description:
2518*
2519* Got 'Failed' indication from Connection state machine - inform Roaming Manager Module
2520*
2521* \b ARGS:
2522*
2523*  I   - pData - pointer to AP Connection context\n
2524*
2525* \b RETURNS:
2526*
2527*  OK on success, NOK otherwise.
2528*
2529* \sa
2530*/
2531static TI_STATUS apConn_reportConnFail(void *data)
2532{
2533    apConn_t *pAPConnection;
2534    apConn_connStatus_t reportStatus;
2535    paramInfoPartial_t param;
2536
2537    pAPConnection = (apConn_t *)data;
2538
2539    pAPConnection->firstAttempt2Roam = FALSE;
2540    pAPConnection->resetReportedRoamingStatistics = FALSE;
2541
2542    /* Erase vendor specific info-element if was defined for last AP Assoc request */
2543    pAPConnection->vsIElength = 0;
2544
2545    /* Report to Roaming Manager */
2546    if (pAPConnection->reportStatusCallb != NULL)
2547    {
2548        param.paramType   = ASSOC_ASSOCIATION_RESP_PARAM;
2549
2550        assoc_getParamPartial(pAPConnection->hAssoc, &param);
2551        reportStatus.dataBuf = (char *)(param.content.applicationConfigBuffer.buffer);
2552        reportStatus.dataBufLength = param.content.applicationConfigBuffer.bufferSize;
2553
2554        reportStatus.status = CONN_STATUS_HANDOVER_FAILURE;
2555
2556        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
2557    }
2558
2559    return OK;
2560}
2561
2562
2563/**
2564*
2565* apConn_configureSCR
2566*
2567* \b Description:
2568*
2569* Got 'Failed' indication from Connection state machine - inform Roaming Manager Module
2570*
2571* \b ARGS:
2572*
2573*  I   - pData - pointer to AP Connection context\n
2574*
2575* \b RETURNS:
2576*
2577*  OK on success, NOK otherwise.
2578*
2579* \sa
2580*/
2581static TI_STATUS apConn_configureDriverBeforeRoaming(void *pData)
2582{
2583    apConn_t    *pAPConnection = (apConn_t*)pData;
2584    paramInfoPartial_t param;
2585
2586    /* Configure SCR group of allowed clients according to 'Roaming' rule */
2587    scr_setGroup (pAPConnection->hScr, SCR_GID_ROAMING);
2588    param.paramType = QOS_MNGR_VOICE_RE_NEGOTIATE_TSPEC;
2589    qosMngr_getParamsPatial(pAPConnection->hQos, &param);
2590    pAPConnection->voiceTspecConfigured = param.content.TspecConfigure.voiceTspecConfigure;
2591	pAPConnection->videoTspecConfigured = param.content.TspecConfigure.videoTspecConfigure;
2592    pAPConnection->resetReportedRoamingStatistics = FALSE;
2593    return OK;
2594}
2595
2596
2597/**
2598*
2599* apConn_swChFinished
2600*
2601* \b Description:
2602*
2603* Switch channel completed; if there were roaming Manager triggers meanwhile,
2604* inform Roaming Manager Module
2605*
2606* \b ARGS:
2607*
2608*  I   - pData - pointer to AP Connection context\n
2609*
2610* \b RETURNS:
2611*
2612*  OK on success, NOK otherwise.
2613*
2614* \sa
2615*/
2616static TI_STATUS apConn_swChFinished(void *pData)
2617{
2618    apConn_t *pAPConnection = (apConn_t *)pData;
2619
2620    /* Inform Current BSS module */
2621    currBSS_restartRssiCounting(pAPConnection->hCurrBSS);
2622
2623    /* If there are unreported roaming triggers of 'No AP' type,
2624       report them now to roaming manager */
2625    if (pAPConnection->roamReason >= ROAMING_TRIGGER_MAX_TX_RETRIES)
2626    {
2627        if ((pAPConnection->roamingEnabled == TRUE) &&
2628            (pAPConnection->roamEventCallb != NULL))
2629        {
2630            /* Report to Roaming Manager */
2631            pAPConnection->roamEventCallb(pAPConnection->hRoamMng, &pAPConnection->roamReason);
2632        }
2633    }
2634    else
2635    {
2636        pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
2637    }
2638
2639    return OK;
2640}
2641
2642
2643/**
2644*
2645* apConn_handleTspecReneg
2646*
2647* \b Description:
2648*
2649* This function will be called when moving from CONNECTING state to
2650* START_TSPEC_RENEGOTIATION state. It checks if TSPEC re-negotiation was requested
2651* by roaming manager, if the TSPEC for voice was defined by user application,
2652* if the re-negotiation was performed during hand-over.
2653* If so, it will trigger moving to WAIT_ROAM state, otherwise it will start
2654* TSPEC negotiation, staying in the REESTABLISHING_VOICE state and waiting
2655* for results.
2656*
2657* \b ARGS:
2658*
2659*  I   - pData - pointer to AP Connection context\n
2660*
2661* \b RETURNS:
2662*
2663*  OK on success, NOK otherwise.
2664*
2665* \sa
2666*/
2667static TI_STATUS apConn_handleTspecReneg (void *pData)
2668{
2669    apConn_t *pAPConnection = (apConn_t *)pData;
2670    paramInfo_t param;
2671
2672    if (pAPConnection->voiceTspecConfigured && pAPConnection->reNegotiateTSPEC)
2673    {
2674        param.paramType = QOS_MNGR_VOICE_RE_NEGOTIATE_TSPEC;
2675        qosMngr_getParams(pAPConnection->hQos, &param);
2676
2677        if (param.content.TspecConfigure.voiceTspecConfigure == TRUE)
2678        {
2679            /* TSPEC is already configured, move to CONNECTED */
2680            return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
2681        }
2682        else
2683        {
2684            param.paramType = QOS_MNGR_RESEND_TSPEC_REQUEST;
2685            param.content.qosRenegotiateTspecRequest.callback = (void *)apConn_qosMngrReportResultCallb;
2686            param.content.qosRenegotiateTspecRequest.handler = pData;
2687
2688            if (qosMngr_setParams(pAPConnection->hQos, &param) != OK)
2689            {
2690                /* Re-negotiation of TSPEC cannot be performed */
2691                return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection);
2692            }
2693            return OK;
2694        }
2695    }
2696    else
2697    {
2698        /* No need to re-negotiate TSPEC, move to CONNECTED */
2699        return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
2700    }
2701}
2702
2703
2704/**
2705*
2706* apConn_qosMngrReportResultCallb
2707*
2708* \b Description:
2709*
2710* This function will be transferred to QoS manager upon request to start negotiation
2711* of the TSPEC for voice and signaling, and will be called when the voice TSPEC
2712* renegotiation is completed. The function will generate FINISHED_OK or
2713* FINISHED_NOK events to the state machine of AP Connection, triggering change of
2714* the current state.
2715*
2716* \b ARGS:
2717*
2718*  I   - hApConn - pointer to AP Connection context\n
2719*  I   - result - returned by Traffic admission control\n
2720*
2721* \b RETURNS:
2722*
2723*  OK on success, NOK otherwise.
2724*
2725* \sa
2726*/
2727static TI_STATUS apConn_qosMngrReportResultCallb (TI_HANDLE hApConn, trafficAdmRequestStatus_e result)
2728{
2729    apConn_t *pAPConnection = (apConn_t *)hApConn;
2730
2731    AP_CONN_VALIDATE_HANDLE(hApConn);
2732
2733    if (result == STATUS_TRAFFIC_ADM_REQUEST_ACCEPT)
2734    {
2735        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
2736    }
2737    else
2738    {
2739        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection);
2740    }
2741    return OK;
2742}
2743
2744/**
2745*
2746* apConn_reportConnStatusToSME
2747*
2748* \b Description:
2749*
2750* Sends report to SME regarding the connection status
2751*
2752* \b ARGS:
2753*
2754*  I   - pAPConnection  - pointer to AP Connection context\n
2755*
2756* \b RETURNS:
2757*
2758*  OK on success, NOK otherwise.
2759*
2760* \sa
2761*/
2762static void apConn_reportConnStatusToSME (apConn_t *pAPConnection)
2763{
2764    WLAN_REPORT_INFORMATION(pAPConnection->hReport, ROAMING_MANAGER_MODULE_LOG,
2765        ("%s roamingTrigger = %d, APDisconnectStatusCode = %d, bNonRoamingDisAssocReason = %d\n",
2766        __FUNCTION__, pAPConnection->roamReason, pAPConnection->APDisconnect.uStatusCode,
2767        pAPConnection->bNonRoamingDisAssocReason));
2768
2769    /* Check if an outside reason caused the disconnection. */
2770    if (pAPConnection->bNonRoamingDisAssocReason)
2771    {
2772        pAPConnection->bNonRoamingDisAssocReason = FALSE;
2773        smeSm_reportConnStatus(pAPConnection->hSme, STATUS_UNSPECIFIED, 0);
2774    }
2775    /* DisAssociation happened due to roaming trigger */
2776    else if (pAPConnection->roamReason == ROAMING_TRIGGER_AP_DISCONNECT)
2777    {   /* AP disconnect is a special case of the status delivered to SME */
2778        mgmtStatus_e mgmtStatus = ( pAPConnection->APDisconnect.bDeAuthenticate ? STATUS_AP_DEAUTHENTICATE : STATUS_AP_DISASSOCIATE );
2779        smeSm_reportConnStatus(pAPConnection->hSme, mgmtStatus, pAPConnection->APDisconnect.uStatusCode);
2780    }
2781    else    /* Finally, just send the last roaming trigger */
2782    {
2783        smeSm_reportConnStatus(pAPConnection->hSme, STATUS_ROAMING_TRIGGER, (UINT32)pAPConnection->roamReason);
2784    }
2785}
2786
2787
2788