1/*
2 * apConn.c
3 *
4 * Copyright(c) 1998 - 2009 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/** \file apConn.c
35 *  \brief AP Connection
36 *
37 *  \see apConn.h
38 */
39
40/****************************************************************************
41 *                                                                          *
42 *   MODULE:  AP Connection                                                 *
43 *   PURPOSE:                                                               *
44 *   Roaming ability of eSTA is implemented by Roaming Manager Component and
45 *   described in "Roaming Manager module LLD" document, and by
46 *   AP Connection module. AP Connection module implemented as two sub-modules:
47 *   The major one is AP Connection, that is responsible for:
48 *   - providing Roaming Manager with access to other parts of WLAN Driver,
49 *   - implementing low levels of roaming mechanism.
50 *   Current BSS sub-module takes care of:
51 *   - maintaining database of current AP info,
52 *   - providing access to database of current AP info.
53 *                                                                          *
54 ****************************************************************************/
55
56#define __FILE_ID__  FILE_ID_21
57#include "osApi.h"
58#include "report.h"
59#include "sme.h"
60#include "siteMgrApi.h"
61#include "smeApi.h"
62#include "PowerMgr_API.h"
63#include "TrafficMonitorAPI.h"
64#include "qosMngr_API.h"
65#ifdef XCC_MODULE_INCLUDED
66 #include "XCCMngr.h"
67#endif
68#include "measurementMgrApi.h"
69#include "connApi.h"
70#include "EvHandler.h"
71#include "apConn.h"
72#include "currBss.h"
73#include "fsm.h"
74#include "scrApi.h"
75#include "regulatoryDomainApi.h"
76#include "TWDriver.h"
77#include "DrvMainModules.h"
78
79
80/*----------------------*/
81/* Constants and macros */
82/*----------------------*/
83
84#ifdef TI_DBG
85 #define    AP_CONN_VALIDATE_HANDLE(hAPConnection)  \
86    if (hAPConnection == NULL)  \
87    {   \
88        WLAN_OS_REPORT(("FATAL ERROR: AP Connection context is not initiated\n"));  \
89        return TI_NOK; \
90    }
91#else
92 #define    AP_CONN_VALIDATE_HANDLE(hAPConnection)
93#endif
94
95#define MAX_ROAMING_TRIGGERS  ROAMING_TRIGGER_LAST
96
97#define UPDATE_SEND_DEAUTH_PACKET_FLAG(roamingEventType) \
98            if ((roamingEventType >= ROAMING_TRIGGER_MAX_TX_RETRIES) && \
99                (roamingEventType != ROAMING_TRIGGER_SECURITY_ATTACK)) \
100            { \
101                pAPConnection->sendDeauthPacket = TI_FALSE; \
102            }
103
104/* Init bits */
105
106
107/*--------------*/
108/* Enumerations */
109/*--------------*/
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 XCC 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/*----------*/
151/* Typedefs */
152/*----------*/
153
154/*------------*/
155/* Structures */
156/*------------*/
157
158/**
159* AP Connection control block
160* Following structure defines parameters that can be configured externally,
161* internal variables, AP Connection state machine and handlers of other modules
162* used by AP Connection module
163*/
164typedef struct _apConn_t
165{
166    /* AP Connection state machine */
167    fsm_stateMachine_t      *apConnSM;          /**< AP Connection module state machine */
168    TI_UINT8                currentState;       /**< AP Connection state machine current state */
169
170    /* Internal parameters */
171    TI_BOOL                 firstAttempt2Roam;  /**< TI_TRUE if still connected to original AP, TI_FALSE otherwise */
172    TI_BOOL                 roamingEnabled;     /**< If TI_FALSE, act like if no roaming callback registered. */
173    apConn_roamingTrigger_e roamReason;         /**< The most severe and recent reason for roaming */
174	APDisconnect_t			APDisconnect;		/**< The AP disconnect trigger extra information */
175    bssEntry_t              *newAP;             /**< Stores parameters of roaming candidate */
176    apConn_connRequest_e    requestType;        /**< Stores type of roaming request */
177    TI_INT8                 rssiThreshold;      /**< Stores recently configured RSSI threshold */
178    TI_UINT8                snrThreshold;       /**< Stores recently configured SNR threshold */
179    TI_UINT8                txFailureThreshold; /**< Stores recently configured consec. no ack threshold */
180    TI_UINT8                lowRateThreshold;   /**< Stores recently configured consec. no ack threshold */
181    TI_UINT32               vsIElength;         /**< Length of vendor specific info-element for assoc req (if defined) */
182    char                    *vsIEbuf;           /**< Pointer to vendor specific info-element for assoc req (if defined) */
183    TI_BOOL                 isRssiTriggerMaskedOut;
184    TI_BOOL                 isSnrTriggerMaskedOut;
185    TI_BOOL                 isConsTxFailureMaskedOut;
186    TI_BOOL                 islowRateTriggerMaskedOut;
187    TI_BOOL                 removeKeys;         /**< Indicates whether keys should be removed after disconnect or not */
188    TI_BOOL                 ignoreDeauthReason0;/**< Indicates whether to ignore DeAuth with reason 0, required for Rogue AP test XCC-V2 */
189    TI_BOOL                 sendDeauthPacket;   /**< Indicates whether to send DEAUTH packet when discommecting or not */
190    TI_UINT8                deauthPacketReasonCode;   /**< Indicates what error code to indicate in the DEAUTH packet  */
191    TI_BOOL                 voiceTspecConfigured;/**< Shall be set to TI_TRUE before roaming in case the TSPEC is configured */
192    TI_BOOL                 videoTspecConfigured;/**< Shall be set to TRUE before roaming in case the TSPEC is configured */
193    TI_BOOL                 reNegotiateTSPEC;   /**< Shall be set to TI_TRUE before hand-over if requested by Roaming Manager */
194    TI_BOOL                 resetReportedRoamingStatistics; /**< Shall be set to TI_TRUE if starting to measure traffic */
195    TI_UINT16               lastRoamingDelay;
196    TI_UINT32               roamingStartedTimestamp;
197    TI_UINT8                roamingSuccesfulHandoverNum;
198    TI_BOOL					bNonRoamingDisAssocReason; /**< Indicate whether last disconnection was called from outside (SME) */
199
200    /** Callback functions, registered by Roaming manager */
201    apConn_roamMngrEventCallb_t  roamEventCallb;         /**< roam event triggers */
202    apConn_roamMngrCallb_t       reportStatusCallb;      /**< connection status events  */
203    apConn_roamMngrCallb_t       returnNeighborApsCallb; /**< neighbor APs list update */
204
205    /* Handlers of other modules used by AP Connection */
206    TI_HANDLE               hOs;
207    TI_HANDLE               hReport;
208    TI_HANDLE               hCurrBSS;
209    TI_HANDLE               hRoamMng;
210    TI_HANDLE               hSme;
211    TI_HANDLE               hSiteMgr;
212    TI_HANDLE               hXCCMngr;
213    TI_HANDLE               hConnSm;
214    TI_HANDLE               hPrivacy;
215    TI_HANDLE               hQos;
216    TI_HANDLE               hEvHandler;
217    TI_HANDLE               hScr;
218    TI_HANDLE               hAssoc;
219    TI_HANDLE               hRegulatoryDomain;
220    TI_HANDLE               hMlme;
221
222    /* Counters for statistics */
223    TI_UINT32               roamingTriggerEvents[MAX_ROAMING_TRIGGERS];
224    TI_UINT32               roamingSuccesfulHandoverTotalNum;
225    TI_UINT32               roamingFailedHandoverNum;
226    TI_UINT32               retainCurrAPNum;
227    TI_UINT32               disconnectFromRoamMngrNum;
228    TI_UINT32               stopFromSmeNum;
229} apConn_t;
230
231
232/*-------------------------------*/
233/* Internal functions prototypes */
234/*-------------------------------*/
235
236/* SM functions */
237static TI_STATUS apConn_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data);
238static TI_STATUS apConn_smNop(void *pData);
239static TI_STATUS apConn_smUnexpected(void *pData);
240static TI_STATUS apConn_startWaitingForTriggers(void *pData);
241static TI_STATUS apConn_connectedToNewAP(void *pData);
242static TI_STATUS apConn_configureDriverBeforeRoaming(void *pData);
243static TI_STATUS apConn_stopConnection(void *pData);
244static TI_STATUS apConn_invokeConnectionToNewAp(void *pData);
245static TI_STATUS apConn_reportDisconnected(void *pData);
246static TI_STATUS apConn_retainAP(void *pData);
247static TI_STATUS apConn_requestCCKM(void *pData);
248static TI_STATUS apConn_reportConnFail(void *pData);
249static TI_STATUS apConn_swChFinished(void *pData);
250static TI_STATUS apConn_handleTspecReneg (void *pData);
251
252/* other functions */
253#ifdef XCC_MODULE_INCLUDED
254static void apConn_calcNewTsf(apConn_t *hAPConnection, TI_UINT8 *tsfTimeStamp, TI_UINT32 newSiteOsTimeStamp, TI_UINT32 beaconInterval);
255#endif
256static TI_STATUS apConn_qosMngrReportResultCallb (TI_HANDLE hApConn, trafficAdmRequestStatus_e result);
257static void		 apConn_reportConnStatusToSME	 (apConn_t *pAPConnection);
258
259
260/*-------------------------------*/
261/* Public functions prototypes 	 */
262/*-------------------------------*/
263
264/**
265*
266* apConn_create
267*
268* \b Description:
269*
270* Create the AP Connection context:
271* allocate memory for internal variables;
272* create state machine.
273*
274* \b ARGS:
275*
276*  I   - hOs - OS handler
277*
278* \b RETURNS:
279*
280* Pointer to the AP Connection on success, NULL on failure
281* (unable to allocate memory or other error).
282*
283* \sa
284*/
285TI_HANDLE apConn_create(TI_HANDLE hOs)
286{
287    TI_STATUS   status;
288    apConn_t    *pAPConnection;
289
290    if ((pAPConnection = os_memoryAlloc(hOs, sizeof(apConn_t))) != NULL)
291    {
292        pAPConnection->hOs = hOs;
293
294        status = fsm_Create(hOs, &(pAPConnection->apConnSM), AP_CONNECT_NUM_STATES, AP_CONNECT_NUM_EVENTS);
295        if (status == TI_OK)
296        {
297            /* Succeeded to create AP Connection module context - return pointer to it */
298            return pAPConnection;
299        }
300        else /* Failed to create state machine */
301        {
302            WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error creating apConnSM - aborting\n"));
303            /* Free pre-allocated control block */
304            os_memoryFree(hOs, pAPConnection, sizeof(apConn_t));
305            return NULL;
306        }
307    }
308    else /* Failed to allocate control block */
309    {
310        WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n"));
311        return NULL;
312    }
313}
314
315/**
316*
317* apConn_unload
318*
319* \b Description:
320*
321* Finish AP Connection module work:
322* release the allocation for state machine and internal variables.
323*
324* \b ARGS:
325*
326*
327* \b RETURNS:
328*
329*  TI_OK if successful, TI_NOK otherwise.
330*
331* \sa
332*/
333TI_STATUS apConn_unload(TI_HANDLE hAPConnection)
334{
335    apConn_t *pAPConnection;
336
337    AP_CONN_VALIDATE_HANDLE (hAPConnection);
338
339    pAPConnection = (apConn_t *)hAPConnection;
340
341    /* Unload state machine */
342    fsm_Unload (pAPConnection->hOs, pAPConnection->apConnSM);
343
344    /* Free pre-allocated control block */
345    os_memoryFree (pAPConnection->hOs, pAPConnection, sizeof(apConn_t));
346
347    return TI_OK;
348}
349
350/**
351*
352* apConn_init
353*
354* \b Description:
355*
356* Prepare AP Connection module to work: initiate internal variables, start state machine
357*
358* \b ARGS:
359*
360*  I   - pStadHandles  - The driver modules handles  \n
361*
362* \b RETURNS:
363*
364*  void
365*
366* \sa
367*/
368void apConn_init (TStadHandlesList *pStadHandles)
369{
370    apConn_t *pAPConnection = (apConn_t *)(pStadHandles->hAPConnection);
371
372    /** State Machine matrix */
373    static fsm_actionCell_t apConn_matrix[AP_CONNECT_NUM_STATES][AP_CONNECT_NUM_EVENTS] =
374    {
375        /* next state and actions for IDLE state */
376        {   {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* PREPARE_FOR_ROAMING  */
377            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* FINISHED_OK          */
378            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* FINISHED_NOT_OK      */
379            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* RETAIN_CURRENT_AP    */
380            {AP_CONNECT_STATE_WAIT_ROAM,apConn_startWaitingForTriggers},/* START                */
381            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* START_ROAM           */
382            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected},               /* START_SWITCH_CHANNEL */
383            {AP_CONNECT_STATE_IDLE, apConn_smNop},                      /* FINISHED_SWITCH_CH   */
384            {AP_CONNECT_STATE_IDLE, apConn_smNop},                      /* FINISHED_HAND_OVER   */
385            {AP_CONNECT_STATE_IDLE, apConn_smUnexpected}                /* STOP                 */
386        },
387        /* next state and actions for WAIT_ROAM state */
388        {   {AP_CONNECT_STATE_WAIT_CONNECT_CMD,apConn_configureDriverBeforeRoaming},/* PREPARE_FOR_ROAMING  */
389            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_OK          */
390            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_NOT_OK      */
391            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* RETAIN_CURRENT_AP    */
392            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* START                */
393            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* START_ROAM           */
394            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smNop},     /* START_SWITCH_CHANNEL */
395            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_SWITCH_CH   */
396            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smUnexpected},      /* FINISHED_HAND_OVER   */
397            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection} /* STOP                 */
398        },
399        /* next state and actions for SWITCHING_CHANNEL state */
400        {   {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* PREPARE_FOR_ROAMING  */
401            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* FINISHED_OK          */
402            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* FINISHED_NOT_OK      */
403            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* RETAIN_CURRENT_AP    */
404            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* START                */
405            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* START_ROAM           */
406            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_swChFinished},  /* START_SWITCH_CHANNEL */
407            {AP_CONNECT_STATE_WAIT_ROAM, apConn_smNop},                 /* FINISHED_SWITCH_CH   */
408            {AP_CONNECT_STATE_SWITCHING_CHANNEL, apConn_smUnexpected},  /* FINISHED_HAND_OVER   */
409            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
410        },
411        /* next state and actions for WAIT_CONNECT_CMD state */
412        {   {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* PREPARE_FOR_ROAMING  */
413            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_OK          */
414            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_NOT_OK      */
415            {AP_CONNECT_STATE_WAIT_ROAM, apConn_retainAP},              /* RETAIN_CURRENT_AP    */
416            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* START                */
417            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_requestCCKM},    /* START_ROAM           */
418            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* START_SWITCH_CHANNEL */
419            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_SWITCH_CH   */
420            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_smUnexpected},   /* FINISHED_HAND_OVER   */
421            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
422        },
423        /* next state and actions for PREPARE_HAND_OFF state */
424        {   {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* PREPARE_FOR_ROAMING  */
425            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* FINISHED_OK          */
426            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* FINISHED_NOT_OK      */
427            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* RETAIN_CURRENT_AP    */
428            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* START                */
429            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* START_ROAM           */
430            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* START_SWITCH_CHANNEL */
431            {AP_CONNECT_STATE_PREPARE_HAND_OFF, apConn_smUnexpected},   /* FINISHED_SWITCH_CH   */
432            {AP_CONNECT_STATE_CONNECTING, apConn_invokeConnectionToNewAp},/* FINISHED_HAND_OVER */
433            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
434        },
435        /* next state and actions for CONNECTING state */
436        {   {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* PREPARE_FOR_ROAMING  */
437            {AP_CONNECT_STATE_REESTABLISH_VOICE,apConn_handleTspecReneg},/* FINISHED_OK             */
438            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_reportConnFail}, /* FINISHED_NOT_OK      */
439            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* RETAIN_CURRENT_AP    */
440            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* START                */
441            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* START_ROAM           */
442            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* START_SWITCH_CHANNEL */
443            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* FINISHED_SWITCH_CH   */
444            {AP_CONNECT_STATE_CONNECTING, apConn_smUnexpected},         /* FINISHED_HAND_OVER   */
445            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
446        },
447        /* next state and actions for DISCONNECTING state */
448        {   {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* PREPARE_FOR_ROAMING  */
449            {AP_CONNECT_STATE_IDLE, apConn_reportDisconnected},     /* FINISHED_OK          */
450            {AP_CONNECT_STATE_IDLE, apConn_reportDisconnected},     /* FINISHED_NOT_OK      */
451            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* RETAIN_CURRENT_AP    */
452            {AP_CONNECT_STATE_DISCONNECTING, apConn_smUnexpected},  /* START                */
453            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* START_ROAM           */
454            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* START_SWITCH_CHANNEL */
455            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* FINISHED_SWITCH_CH   */
456            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* FINISHED_HAND_OVER   */
457            {AP_CONNECT_STATE_DISCONNECTING, apConn_smNop},         /* STOP                 */
458        },
459        /* next state and actions for REESTABLISH_VOICE state */
460        {   {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* PREPARE_FOR_ROAMING  */
461            {AP_CONNECT_STATE_WAIT_ROAM,apConn_connectedToNewAP},       /* FINISHED_OK          */
462            {AP_CONNECT_STATE_WAIT_CONNECT_CMD, apConn_reportConnFail}, /* FINISHED_NOT_OK      */
463            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* RETAIN_CURRENT_AP    */
464            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* START                */
465            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* START_ROAM           */
466            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* START_SWITCH_CHANNEL */
467            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* FINISHED_SWITCH_CH   */
468            {AP_CONNECT_STATE_REESTABLISH_VOICE, apConn_smUnexpected},  /* FINISHED_HAND_OVER   */
469            {AP_CONNECT_STATE_DISCONNECTING, apConn_stopConnection}     /* STOP                 */
470        }
471    };
472
473    fsm_Config(pAPConnection->apConnSM,
474               (fsm_Matrix_t)&apConn_matrix[0][0],
475               AP_CONNECT_NUM_STATES,
476               AP_CONNECT_NUM_EVENTS,
477               (fsm_eventActivation_t)apConn_smEvent,
478               pAPConnection->hOs);
479
480    pAPConnection->hReport      = pStadHandles->hReport;
481    pAPConnection->hCurrBSS     = pStadHandles->hCurrBss;
482    pAPConnection->hRoamMng     = pStadHandles->hRoamingMngr;
483    pAPConnection->hSme         = pStadHandles->hSme;
484    pAPConnection->hSiteMgr     = pStadHandles->hSiteMgr;
485    pAPConnection->hXCCMngr     = pStadHandles->hXCCMngr;
486    pAPConnection->hConnSm      = pStadHandles->hConn;
487    pAPConnection->hPrivacy     = pStadHandles->hRsn;
488    pAPConnection->hQos         = pStadHandles->hQosMngr;
489    pAPConnection->hEvHandler   = pStadHandles->hEvHandler;
490    pAPConnection->hScr         = pStadHandles->hSCR;
491    pAPConnection->hAssoc       = pStadHandles->hAssoc;
492    pAPConnection->hMlme        = pStadHandles->hMlmeSm;
493    pAPConnection->hRegulatoryDomain = pStadHandles->hRegulatoryDomain;
494
495    pAPConnection->currentState = AP_CONNECT_STATE_IDLE;
496    pAPConnection->firstAttempt2Roam = TI_TRUE;
497    pAPConnection->roamingEnabled = TI_TRUE;
498    pAPConnection->reportStatusCallb = NULL;
499    pAPConnection->roamEventCallb = NULL;
500    pAPConnection->returnNeighborApsCallb = NULL;
501}
502
503
504TI_STATUS apConn_SetDefaults  (TI_HANDLE hAPConnection, apConnParams_t *pApConnParams)
505{
506    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
507    TI_UINT32  index;
508
509    pAPConnection->ignoreDeauthReason0 = pApConnParams->ignoreDeauthReason0;
510
511    for (index=ROAMING_TRIGGER_NONE; index<ROAMING_TRIGGER_LAST; index++)
512    {
513        pAPConnection->roamingTriggerEvents[index] = 0;
514    }
515    pAPConnection->roamingSuccesfulHandoverNum = 0;
516    pAPConnection->roamingSuccesfulHandoverTotalNum = 0;
517    pAPConnection->roamingFailedHandoverNum = 0;
518    pAPConnection->retainCurrAPNum = 0;
519    pAPConnection->disconnectFromRoamMngrNum = 0;
520    pAPConnection->stopFromSmeNum = 0;
521    pAPConnection->txFailureThreshold = NO_ACK_DEFAULT_THRESHOLD;
522    pAPConnection->lowRateThreshold = LOW_RATE_DEFAULT_THRESHOLD;
523    pAPConnection->rssiThreshold = RSSI_DEFAULT_THRESHOLD;
524    pAPConnection->snrThreshold = SNR_DEFAULT_THRESHOLD;
525    pAPConnection->vsIElength = 0;
526    pAPConnection->isRssiTriggerMaskedOut = TI_FALSE;
527    pAPConnection->isSnrTriggerMaskedOut = TI_TRUE;
528    pAPConnection->islowRateTriggerMaskedOut = TI_FALSE;
529    pAPConnection->isConsTxFailureMaskedOut = TI_FALSE;
530    pAPConnection->removeKeys = TI_TRUE;
531    pAPConnection->sendDeauthPacket = TI_TRUE;       /* Default behavior is radio On - send DISASSOC frame */
532	pAPConnection->deauthPacketReasonCode = STATUS_UNSPECIFIED;
533    pAPConnection->voiceTspecConfigured = TI_FALSE;
534	pAPConnection->videoTspecConfigured = TI_FALSE;
535    pAPConnection->resetReportedRoamingStatistics = TI_FALSE;
536    pAPConnection->reNegotiateTSPEC = TI_FALSE;
537    pAPConnection->bNonRoamingDisAssocReason = TI_FALSE;
538
539    pAPConnection->roamingStartedTimestamp = 0;
540    pAPConnection->lastRoamingDelay = 0;
541    pAPConnection->roamingSuccesfulHandoverNum = 0;
542
543    return TI_OK;
544}
545
546
547/* apConn_isPsRequiredBeforeScan
548*
549* \b Description:
550*
551* verify if the PS required before scan according if roaming triger is part of ROAMING_TRIGGER_LOW_QUALITY_GROUP
552*
553* \b ARGS:
554*
555*  I   - hAPConnection - pointer to module\n
556*
557* \b RETURNS:
558*
559*  TRUE or FALSE.
560*
561* \sa
562*/
563TI_BOOL apConn_isPsRequiredBeforeScan(TI_HANDLE hAPConnection)
564{
565    apConn_t * pAPConnection = (apConn_t *) hAPConnection;
566
567	/* check if part of ROAMING_TRIGGER_LOW_QUALITY_GROUP */
568	if (pAPConnection->roamReason <= ROAMING_TRIGGER_MAX_TX_RETRIES)
569		return TI_TRUE;
570	else
571		return TI_FALSE;
572}
573
574
575
576/**
577*
578* apConn_ConnCompleteInd
579*
580* \b Description:
581*
582* Inform AP Connection about successful / unsuccessful completion
583* of link establishing
584*
585* \b ARGS:
586*
587*  I   - result - TI_OK if successfully connected, TI_NOK otherwise  \n
588*
589* \b RETURNS:
590*
591*  None.
592*
593* \sa
594*/
595void apConn_ConnCompleteInd(TI_HANDLE hAPConnection, mgmtStatus_e status, TI_UINT32 uStatusCode)
596{
597    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
598
599    if (status == STATUS_SUCCESSFUL)
600    {
601        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
602    }
603    else
604    {
605        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection);
606    }
607}
608
609TI_STATUS apConn_getRoamThresholds(TI_HANDLE hAPConnection, roamingMngrThresholdsConfig_t *pParam)
610{
611    apConn_t * pAPConnection = (apConn_t *) hAPConnection;
612
613    pParam->lowRssiThreshold = pAPConnection->rssiThreshold;
614    pParam->lowSnrThreshold = pAPConnection->snrThreshold;
615    pParam->txRateThreshold = pAPConnection->lowRateThreshold;
616    pParam->dataRetryThreshold = pAPConnection->txFailureThreshold;
617
618    currBSS_getRoamingParams(pAPConnection->hCurrBSS,
619                             &pParam->numExpectedTbttForBSSLoss,
620                             &pParam->lowQualityForBackgroungScanCondition,
621                             &pParam->normalQualityForBackgroungScanCondition);
622
623    return TI_OK;
624}
625
626TI_STATUS apConn_setRoamThresholds(TI_HANDLE hAPConnection, roamingMngrThresholdsConfig_t *pParam)
627{
628    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
629
630    AP_CONN_VALIDATE_HANDLE(hAPConnection);
631
632    /* If low quality trigger threshold is set to 0 - this is the request to ignore this trigger */
633    /* Otherwise store it */
634    if (pParam->lowRssiThreshold == (TI_INT8)AP_CONNECT_TRIGGER_IGNORED)
635    {
636        pAPConnection->isRssiTriggerMaskedOut = TI_TRUE;
637        pParam->lowRssiThreshold = pAPConnection->rssiThreshold;
638    }
639    else
640    {
641        pAPConnection->isRssiTriggerMaskedOut = TI_FALSE;
642        pAPConnection->rssiThreshold = pParam->lowRssiThreshold;
643    }
644
645    if (pParam->txRateThreshold == AP_CONNECT_TRIGGER_IGNORED)
646    {
647        pAPConnection->islowRateTriggerMaskedOut = TI_TRUE;
648        pParam->txRateThreshold = pAPConnection->lowRateThreshold;
649    }
650    else
651    {
652        pAPConnection->islowRateTriggerMaskedOut = TI_FALSE;
653        pAPConnection->lowRateThreshold = pParam->txRateThreshold;
654    }
655
656    if (pParam->dataRetryThreshold == AP_CONNECT_TRIGGER_IGNORED)
657    {
658        pAPConnection->isConsTxFailureMaskedOut = TI_TRUE;
659        pParam->dataRetryThreshold = pAPConnection->txFailureThreshold;
660    }
661    else
662    {
663        pAPConnection->isConsTxFailureMaskedOut = TI_FALSE;
664        pAPConnection->txFailureThreshold = pParam->dataRetryThreshold;
665    }
666
667    pAPConnection->isSnrTriggerMaskedOut = TI_FALSE;
668    pAPConnection->snrThreshold = pParam->lowSnrThreshold;
669
670    currBSS_updateRoamingTriggers(pAPConnection->hCurrBSS, pParam);
671
672    return TI_OK;
673}
674
675TI_STATUS apConn_registerRoamMngrCallb(TI_HANDLE hAPConnection,
676                                       apConn_roamMngrEventCallb_t  roamEventCallb,
677                                       apConn_roamMngrCallb_t       reportStatusCallb,
678                                       apConn_roamMngrCallb_t       returnNeighborApsCallb)
679{
680    apConn_t *pAPConnection;
681    apConn_connStatus_t reportStatus;
682    paramInfo_t param;
683
684    AP_CONN_VALIDATE_HANDLE(hAPConnection);
685
686    pAPConnection = (apConn_t *)hAPConnection;
687
688    pAPConnection->roamEventCallb = roamEventCallb;
689    pAPConnection->reportStatusCallb = reportStatusCallb;
690    if ((pAPConnection->roamingEnabled) && (pAPConnection->currentState != AP_CONNECT_STATE_IDLE))
691    {
692        param.paramType   = ASSOC_ASSOCIATION_REQ_PARAM;
693
694        assoc_getParam(pAPConnection->hAssoc, &param);
695        reportStatus.dataBuf = (char *)(param.content.assocReqBuffer.buffer);
696        reportStatus.dataBufLength = param.content.assocReqBuffer.bufferSize;
697
698        reportStatus.status = CONN_STATUS_CONNECTED;
699        reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
700    }
701    ((apConn_t *)hAPConnection)->returnNeighborApsCallb = returnNeighborApsCallb;
702
703    return TI_OK;
704}
705
706TI_STATUS apConn_unregisterRoamMngrCallb(TI_HANDLE hAPConnection)
707{
708    apConn_t *pAPConnection;
709
710    AP_CONN_VALIDATE_HANDLE(hAPConnection);
711
712        pAPConnection = (apConn_t *)hAPConnection;
713
714        pAPConnection->roamEventCallb = NULL;
715        pAPConnection->reportStatusCallb = NULL;
716        pAPConnection->returnNeighborApsCallb = NULL;
717
718    if ((pAPConnection->currentState != AP_CONNECT_STATE_IDLE) && (pAPConnection->currentState != AP_CONNECT_STATE_WAIT_ROAM))
719    {
720        /* Roaming Manager is unregistering it's callbacks in the middle of roaming - disconnect */
721        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
722    }
723    return TI_OK;
724}
725
726TI_STATUS apConn_disconnect(TI_HANDLE hAPConnection)
727{
728    apConn_t *pAPConnection;
729
730    AP_CONN_VALIDATE_HANDLE(hAPConnection);
731
732    pAPConnection = (apConn_t *)hAPConnection;
733    UPDATE_SEND_DEAUTH_PACKET_FLAG(pAPConnection->roamReason);
734	if (pAPConnection->roamReason == ROAMING_TRIGGER_SECURITY_ATTACK)
735		pAPConnection->deauthPacketReasonCode = STATUS_MIC_FAILURE;
736	else
737		pAPConnection->deauthPacketReasonCode = STATUS_UNSPECIFIED;
738	apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
739    pAPConnection->disconnectFromRoamMngrNum++;
740
741    return TI_OK;
742}
743
744TI_STATUS apConn_getStaCapabilities(TI_HANDLE hAPConnection,
745                                    apConn_staCapabilities_t *ie_list)
746{
747    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
748    apConn_staCapabilities_t *pList;
749    paramInfo_t param;
750
751    AP_CONN_VALIDATE_HANDLE(hAPConnection);
752
753        pList = ie_list;
754
755    /* Get authentication suite type */
756    param.paramType = RSN_EXT_AUTHENTICATION_MODE;
757    rsn_getParam(pAPConnection->hPrivacy, &param);
758
759    switch (param.content.rsnExtAuthneticationMode)
760    {
761        case RSN_EXT_AUTH_MODE_OPEN:
762            pList->authMode = os802_11AuthModeOpen;
763            break;
764        case RSN_EXT_AUTH_MODE_SHARED_KEY:
765            pList->authMode = os802_11AuthModeShared;
766            break;
767        case RSN_EXT_AUTH_MODE_AUTO_SWITCH:
768            pList->authMode = os802_11AuthModeAutoSwitch;
769            break;
770        case RSN_EXT_AUTH_MODE_WPA:
771            pList->authMode = os802_11AuthModeWPA;
772            break;
773        case RSN_EXT_AUTH_MODE_WPAPSK:
774            pList->authMode = os802_11AuthModeWPAPSK;
775            break;
776        case RSN_EXT_AUTH_MODE_WPANONE:
777            pList->authMode = os802_11AuthModeWPANone;
778            break;
779        case RSN_EXT_AUTH_MODE_WPA2:
780            pList->authMode = os802_11AuthModeWPA2;
781            break;
782        case RSN_EXT_AUTH_MODE_WPA2PSK:
783            pList->authMode = os802_11AuthModeWPA2PSK;
784            break;
785        default:
786            pList->authMode = os802_11AuthModeOpen;
787            break;
788    }
789
790    /* Get encryption type */
791    param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
792    rsn_getParam(pAPConnection->hPrivacy, &param);
793
794    switch (param.content.rsnEncryptionStatus)
795    {
796        case TWD_CIPHER_NONE:
797            pList->encryptionType = OS_ENCRYPTION_TYPE_NONE;
798            break;
799        case TWD_CIPHER_WEP:
800        case TWD_CIPHER_WEP104:
801            pList->encryptionType = OS_ENCRYPTION_TYPE_WEP;
802            break;
803        case TWD_CIPHER_TKIP:
804        case TWD_CIPHER_CKIP:
805            pList->encryptionType = OS_ENCRYPTION_TYPE_TKIP;
806            break;
807        case TWD_CIPHER_AES_WRAP:
808        case TWD_CIPHER_AES_CCMP:
809            pList->encryptionType = OS_ENCRYPTION_TYPE_AES;
810            break;
811        default:
812            pList->encryptionType = OS_ENCRYPTION_TYPE_NONE;
813            break;
814    }
815
816    /* Get supported rates */
817    param.paramType = SITE_MGR_DESIRED_SUPPORTED_RATE_SET_PARAM;
818    siteMgr_getParam(pAPConnection->hSiteMgr, &param);
819    os_memoryCopy(pAPConnection->hOs, (void *)param.content.siteMgrDesiredSupportedRateSet.ratesString, pList->rateMask, sizeof(OS_802_11_RATES_EX));
820
821    /* Get mode: 2.4G, 5G or Dual */
822    param.paramType = SITE_MGR_DESIRED_DOT11_MODE_PARAM;
823    siteMgr_getParam(pAPConnection->hSiteMgr, &param);
824    pList->networkType = (OS_802_11_NETWORK_TYPE)param.content.siteMgrDot11Mode;
825    switch(param.content.siteMgrDot11Mode)
826    {
827        case DOT11_B_MODE:
828            pList->networkType = os802_11DS;
829            break;
830        case DOT11_A_MODE:
831            pList->networkType = os802_11OFDM5;
832            break;
833        case DOT11_G_MODE:
834            pList->networkType = os802_11OFDM24;
835            break;
836        case DOT11_DUAL_MODE:
837            pList->networkType = os802_11Automode;
838            break;
839        default:
840            pList->networkType = os802_11DS;
841            break;
842    }
843
844
845    /* Get XCC status */
846#ifdef XCC_MODULE_INCLUDED
847    param.paramType = XCC_ENABLED;
848    XCCMngr_getParam(pAPConnection->hXCCMngr, &param);
849    pList->XCCEnabled = (param.content.XCCEnabled==XCC_MODE_ENABLED)? TI_TRUE : TI_FALSE;
850#else
851    pList->XCCEnabled = TI_FALSE;
852#endif
853
854    /* Get QoS type */
855    param.paramType = QOS_MNGR_ACTIVE_PROTOCOL;
856    qosMngr_getParams(pAPConnection->hQos, &param);
857    pList->qosEnabled = param.content.qosSiteProtocol != QOS_NONE;
858
859    pList->regDomain = REG_DOMAIN_FIXED;
860    /* Get regulatory domain type */
861    param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
862    regulatoryDomain_getParam(pAPConnection->hRegulatoryDomain, &param);
863    if (param.content.spectrumManagementEnabled)
864    {   /* 802.11h is enabled (802.11h includes 802.11d) */
865        pList->regDomain = REG_DOMAIN_80211H;
866    }
867    else
868    {
869    param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM;
870    regulatoryDomain_getParam(pAPConnection->hRegulatoryDomain, &param);
871        if (param.content.regulatoryDomainEnabled)
872        {   /* 802.11d is enabled */
873            pList->regDomain = REG_DOMAIN_80211D;
874        }
875    }
876    return TI_OK;
877}
878
879TI_STATUS apConn_connectToAP(TI_HANDLE hAPConnection,
880                             bssEntry_t *newAP,
881                             apConn_connRequest_t *request,
882                             TI_BOOL reNegotiateTspec)
883{
884    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
885
886    AP_CONN_VALIDATE_HANDLE(hAPConnection);
887
888    pAPConnection->requestType = request->requestType;
889
890    switch (request->requestType)
891    {
892        case AP_CONNECT_RETAIN_CURR_AP:
893            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_RETAIN_CURRENT_AP, pAPConnection);
894            break;
895
896        case AP_CONNECT_FULL_TO_AP:
897            pAPConnection->removeKeys = TI_TRUE;
898            pAPConnection->newAP = newAP;
899            pAPConnection->roamingFailedHandoverNum++;
900            pAPConnection->reNegotiateTSPEC = reNegotiateTspec;
901            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_ROAM, pAPConnection);
902            break;
903
904        case AP_CONNECT_FAST_TO_AP:
905        case AP_CONNECT_RECONNECT_CURR_AP:
906            pAPConnection->removeKeys = TI_FALSE;
907            pAPConnection->newAP = newAP;
908            pAPConnection->roamingFailedHandoverNum++;
909            pAPConnection->reNegotiateTSPEC = reNegotiateTspec;
910            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_ROAM, pAPConnection);
911            break;
912
913        default:
914            break;
915    }
916
917    /* If there is vendor specific IE to attach to Assoc req, store it now */
918    if (request->dataBufLength > 0)
919    {
920        pAPConnection->vsIEbuf = request->dataBuf;
921        pAPConnection->vsIElength = request->dataBufLength;
922    }
923
924    return TI_OK;
925}
926
927bssEntry_t *apConn_getBSSParams(TI_HANDLE hAPConnection)
928{
929#ifdef TI_DBG
930    if (hAPConnection == NULL) /* Failed to allocate control block */
931    {
932        WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n"));
933        return NULL;
934    }
935#endif
936
937    return currBSS_getBssInfo(((apConn_t *)hAPConnection)->hCurrBSS);
938}
939
940TI_BOOL apConn_isSiteBanned(TI_HANDLE hAPConnection, TMacAddr * givenAp)
941{
942    apConn_t * pAPConnection = (apConn_t *) hAPConnection;
943
944    return rsn_isSiteBanned(pAPConnection->hPrivacy, *givenAp);
945}
946
947TI_BOOL apConn_getPreAuthAPStatus(TI_HANDLE hAPConnection, TMacAddr *givenAp)
948{
949    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
950    paramInfo_t     param;
951
952    AP_CONN_VALIDATE_HANDLE(hAPConnection);
953
954    param.paramType = RSN_PRE_AUTH_STATUS;
955    MAC_COPY (param.content.rsnApMac, *givenAp);
956    rsn_getParam(pAPConnection->hPrivacy, &param);
957
958    return param.content.rsnPreAuthStatus;
959}
960
961TI_STATUS apConn_preAuthenticate(TI_HANDLE hAPConnection, bssList_t *listAPs)
962{
963    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
964    TBssidList4PreAuth  apList;
965    TI_UINT32           listIndex, apListIndex;
966    bssEntry_t          *pCurrentAP;
967    TI_UINT8            *pRsnIEs;
968
969#ifdef TI_DBG
970    if ((hAPConnection == NULL) || (listAPs == NULL))
971    {
972        WLAN_OS_REPORT(("FATAL ERROR: AP Connection context is not initiated\n"));
973        return TI_NOK;
974    }
975
976        TRACE0(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_reserveResources \n");
977#endif
978
979    for (listIndex=0, apListIndex=0; listIndex<listAPs->numOfEntries; listIndex++)
980    {
981        MAC_COPY (apList.bssidList[apListIndex].bssId,
982				  listAPs->BSSList[listIndex].BSSID);
983
984        /* search in the buffer pointer to the beginning of the
985            RSN IE according to the IE ID */
986        if (!mlmeParser_ParseIeBuffer (pAPConnection->hMlme, listAPs->BSSList[listIndex].pBuffer, listAPs->BSSList[listIndex].bufferLength, RSN_IE_ID, &pRsnIEs, NULL, 0))
987        {
988            TRACE0(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_preAuthenticate, no RSN IE was found \n");
989            TRACE_INFO_HEX(pAPConnection->hReport, listAPs->BSSList[listIndex].pBuffer, listAPs->BSSList[listIndex].bufferLength);
990            continue;
991        }
992
993        apList.bssidList[apListIndex].pRsnIEs = (dot11_RSN_t*)pRsnIEs;
994        apList.bssidList[apListIndex].rsnIeLen = apList.bssidList[apListIndex].pRsnIEs->hdr[1] + 2;
995        apListIndex++;
996    }
997
998    /* Start pre-auth after any Conn succ (including first),
999    and not only when a New BSSID was added, in order to save/refresh
1000    PMKID of the current AP.*/
1001    {
1002        /* Add the current BSSID to the list */
1003        pCurrentAP = apConn_getBSSParams(pAPConnection);
1004        MAC_COPY (apList.bssidList[apListIndex].bssId, pCurrentAP->BSSID);
1005        /* search in the buffer pointer to the beginning of the
1006            RSN IE according to the IE ID */
1007
1008        if (!mlmeParser_ParseIeBuffer (pAPConnection->hMlme, pCurrentAP->pBuffer, pCurrentAP->bufferLength, RSN_IE_ID, &pRsnIEs, NULL, 0))
1009        {
1010            TRACE6(pAPConnection->hReport, REPORT_SEVERITY_ERROR, "apConn_preAuthenticate, no RSN IE was found in the current BSS, BSSID=0x%x-0x%x-0x%x-0x%x-0x%x-0x%x \n", pCurrentAP->BSSID[0], pCurrentAP->BSSID[1], pCurrentAP->BSSID[2], pCurrentAP->BSSID[3], pCurrentAP->BSSID[4], pCurrentAP->BSSID[5]);
1011            report_PrintDump (pCurrentAP->pBuffer, pCurrentAP->bufferLength);
1012            apList.bssidList[apListIndex].pRsnIEs = NULL;
1013            apList.bssidList[apListIndex].rsnIeLen = 0;
1014        }
1015        else
1016        {
1017            apList.bssidList[apListIndex].pRsnIEs = (dot11_RSN_t*)pRsnIEs;
1018            apList.bssidList[apListIndex].rsnIeLen = apList.bssidList[apListIndex].pRsnIEs->hdr[1] + 2;
1019        }
1020        apList.NumOfItems = apListIndex+1;
1021        rsn_startPreAuth(pAPConnection->hPrivacy, &apList);
1022    }
1023    return TI_OK;
1024}
1025
1026TI_STATUS apConn_prepareToRoaming(TI_HANDLE hAPConnection, apConn_roamingTrigger_e reason)
1027{
1028    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1029
1030    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1031
1032    pAPConnection->roamReason = reason;
1033
1034    return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_PREPARE_FOR_ROAMING, pAPConnection);
1035}
1036
1037/**
1038*
1039* apConn_indicateSwitchChannelInProgress
1040*
1041* \b Description:
1042*
1043* This function is called when switch channel process is started; it will trigger
1044* AP Connection state machine from 'Wait for roaming start' to 'Switch channel in progress'
1045* state.
1046*
1047* \b ARGS:
1048*
1049*  I   - reason - the reason for roaming \n
1050*
1051* \b RETURNS:
1052*
1053*  TI_OK if successful, TI_NOK otherwise.
1054*
1055* \sa
1056*/
1057TI_STATUS apConn_indicateSwitchChannelInProgress(TI_HANDLE hAPConnection)
1058{
1059    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1060
1061    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1062
1063    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START_SWITCH_CHANNEL, pAPConnection);
1064    return TI_OK;
1065}
1066
1067
1068/**
1069*
1070* apConn_indicateSwitchChannelFinished
1071*
1072* \b Description:
1073*
1074* This function is called when switch channel process is finished
1075*
1076* \b ARGS:
1077*
1078*  I   - reason - the reason for roaming \n
1079*
1080* \b RETURNS:
1081*
1082*  TI_OK if successful, TI_NOK otherwise.
1083*
1084* \sa
1085*/
1086TI_STATUS apConn_indicateSwitchChannelFinished(TI_HANDLE hAPConnection)
1087{
1088    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1089
1090    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1091
1092    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_SWITCH_CH, pAPConnection);
1093
1094    return TI_OK;
1095}
1096
1097
1098/**
1099*
1100* apConn_start
1101*
1102* \b Description:
1103*
1104* Called by SME module when new connection has been successfully established (first time connection)
1105*
1106* \b ARGS:
1107*
1108*  I   - isValidBSS - if TI_FALSE, no roaming shall be performed, disconnect upon any roaming event;
1109*                   other parameters of current AP can be received from Current BSS module
1110*
1111* \b RETURNS:
1112*
1113*  TI_OK if successful, TI_NOK otherwise.
1114*
1115* \sa
1116*/
1117TI_STATUS apConn_start(TI_HANDLE hAPConnection, TI_BOOL roamingEnabled)
1118{
1119    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1120
1121    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1122
1123    pAPConnection->roamingEnabled = roamingEnabled;
1124
1125    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_START, pAPConnection);
1126    return TI_OK;
1127}
1128
1129
1130/**
1131*
1132* apConn_stop
1133*
1134* \b Description:
1135*
1136* Called by SME module when current connection must be taken down
1137* (due to driver download, connection failure or any other reason)
1138*
1139* \b ARGS:
1140*
1141* \b RETURNS:
1142*
1143*  TI_OK if successful, TI_NOK otherwise.
1144*
1145* \sa
1146*/
1147TI_STATUS apConn_stop(TI_HANDLE hAPConnection, TI_BOOL removeKeys)
1148{
1149    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1150
1151    pAPConnection->stopFromSmeNum++;
1152    pAPConnection->removeKeys = removeKeys;
1153    pAPConnection->sendDeauthPacket = TI_TRUE;
1154    pAPConnection->reNegotiateTSPEC = TI_FALSE;
1155    pAPConnection->voiceTspecConfigured = TI_FALSE;
1156	pAPConnection->videoTspecConfigured = TI_FALSE;
1157
1158	/* Mark that the connection is stopped due to reason outside the scope of this module */
1159	if (pAPConnection->roamReason == ROAMING_TRIGGER_SECURITY_ATTACK)
1160		pAPConnection->bNonRoamingDisAssocReason = TI_FALSE;
1161	else
1162		pAPConnection->bNonRoamingDisAssocReason = TI_TRUE;
1163
1164	apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
1165    return TI_OK;
1166}
1167
1168
1169/**
1170*
1171* apConn_reportRoamingEvent
1172*
1173* \b Description:
1174*
1175* Called when one of roaming events occur
1176*
1177* \b ARGS:
1178*
1179*  I   - roamingEventType
1180*  I   - pRoamingEventData - in case of 'Tx rate' event, or AP disconnect
1181*
1182* \b RETURNS:
1183*
1184*  TI_OK if successful, TI_NOK otherwise.
1185*
1186* \sa
1187*/
1188TI_STATUS apConn_reportRoamingEvent(TI_HANDLE hAPConnection,
1189                                    apConn_roamingTrigger_e roamingEventType,
1190                                    roamingEventData_u *pRoamingEventData)
1191{
1192    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1193    paramInfo_t param;  /* parameter for retrieving BSSID */
1194    TI_UINT16 reasonCode = 0;
1195
1196    AP_CONN_VALIDATE_HANDLE(hAPConnection);
1197
1198    TRACE4(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_reportRoamingEvent, type=%d, cur_state=%d, roamingEnabled=%d, roamEventCallb=%p  \n", roamingEventType, pAPConnection->currentState, pAPConnection->roamingEnabled, pAPConnection->roamEventCallb);
1199
1200    /* 1. Check if this is Rogue AP test case */
1201    if (roamingEventType == ROAMING_TRIGGER_AP_DISCONNECT)
1202    {
1203		if (pRoamingEventData != NULL)
1204		{	/* Save the disconnect reason for future use */
1205			pAPConnection->APDisconnect.uStatusCode     = pRoamingEventData->APDisconnect.uStatusCode;
1206			pAPConnection->APDisconnect.bDeAuthenticate = pRoamingEventData->APDisconnect.bDeAuthenticate;
1207            reasonCode = pRoamingEventData->APDisconnect.uStatusCode;
1208		}
1209        if ((pAPConnection->ignoreDeauthReason0) && (pRoamingEventData!=NULL) &&
1210               (pAPConnection->APDisconnect.uStatusCode == 0))
1211        {   /* This is required for Rogue AP test,
1212                When Rogue AP due to invalid User name, deauth with reason 0 arrives before the Rogue AP,
1213                and this XCC test fails.*/
1214            TRACE0(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_reportRoamingEvent, Ignore DeAuth with reason 0 \n");
1215            return TI_OK;
1216        }
1217        TRACE1(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_reportRoamingEvent, DeAuth with reason %d \n", pAPConnection->APDisconnect.uStatusCode);
1218
1219        if (pAPConnection->APDisconnect.uStatusCode == STATUS_CODE_802_1X_AUTHENTICATION_FAILED)
1220        {
1221          #ifdef XCC_MODULE_INCLUDED
1222            TI_STATUS    status;
1223
1224            /* Raise the EAP-Failure as event */
1225            status = XCCMngr_rogueApDetected (pAPConnection->hXCCMngr, RSN_AUTH_STATUS_CHALLENGE_FROM_AP_FAILED);
1226          #endif
1227
1228
1229            /* Remove AP from candidate list for a specified amount of time */
1230            param.paramType = SITE_MGR_CURRENT_BSSID_PARAM;
1231        	siteMgr_getParam(pAPConnection->hSiteMgr, &param);
1232
1233            TRACE1(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "current station is banned from the roaming candidates list for %d Ms\n", RSN_AUTH_FAILURE_TIMEOUT);
1234
1235            rsn_banSite(pAPConnection->hPrivacy, param.content.siteMgrDesiredBSSID, RSN_SITE_BAN_LEVEL_FULL, RSN_AUTH_FAILURE_TIMEOUT);
1236        }
1237
1238    }
1239
1240    /* 2. Check if received trigger is masked out */
1241    if (((pAPConnection->isConsTxFailureMaskedOut) && (roamingEventType == ROAMING_TRIGGER_MAX_TX_RETRIES)) ||
1242        ((pAPConnection->isRssiTriggerMaskedOut)   && (roamingEventType == ROAMING_TRIGGER_LOW_QUALITY)) ||
1243        ((pAPConnection->isSnrTriggerMaskedOut)    && (roamingEventType == ROAMING_TRIGGER_LOW_SNR)) ||
1244        ((pAPConnection->islowRateTriggerMaskedOut)&& (roamingEventType == ROAMING_TRIGGER_LOW_TX_RATE)))
1245    {
1246        TRACE0(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_reportRoamingEvent, trigger ignored \n");
1247        return TI_OK;
1248    }
1249
1250    /* 3.  Valid trigger received: */
1251    /* 3a. Update statistics */
1252    pAPConnection->roamingTriggerEvents[roamingEventType]++;
1253
1254	/* 3b. Store the most severe trigger */
1255	if (pAPConnection->roamReason < roamingEventType)
1256	{
1257		pAPConnection->roamReason = roamingEventType;
1258	}
1259
1260    /* 3c. Check if Roaming Manager is available */
1261    if (((!pAPConnection->roamingEnabled) || (pAPConnection->roamEventCallb == NULL) ||
1262          (pAPConnection->currentState == AP_CONNECT_STATE_IDLE))
1263        && (roamingEventType >= ROAMING_TRIGGER_LOW_TX_RATE)
1264		&& (roamingEventType != ROAMING_TRIGGER_MAX_TX_RETRIES))
1265    {
1266       /* 'Any SSID' configured, meaning Roaming Manager is not allowed to perform roaming,
1267           or Roaming Manager is not registered for roaming events;
1268           unless this is trigger to change parameters of background scan, disconnect the link */
1269        TRACE1(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "Disconnecting link due to roaming event: ev = %d\n", roamingEventType);
1270
1271        /*  Handle IBSS case TBD to remove
1272            Handle also the case where A first connection is in progress, and
1273            de-auth arrived. */
1274        if (pAPConnection->currentState == AP_CONNECT_STATE_IDLE)
1275		{
1276			sme_ReportApConnStatus(pAPConnection->hSme, STATUS_DISCONNECT_DURING_CONNECT, pAPConnection->APDisconnect.uStatusCode);
1277		}
1278        else
1279        {
1280            /* Infra-structure BSS case - disconnect the link */
1281            if (roamingEventType >= ROAMING_TRIGGER_AP_DISCONNECT)
1282            {
1283                pAPConnection->removeKeys = TI_TRUE;
1284            }
1285            else
1286            {
1287                pAPConnection->removeKeys = TI_FALSE;
1288            }
1289            UPDATE_SEND_DEAUTH_PACKET_FLAG(roamingEventType);
1290			if (roamingEventType == ROAMING_TRIGGER_SECURITY_ATTACK)
1291				pAPConnection->deauthPacketReasonCode = STATUS_MIC_FAILURE;
1292			else
1293				pAPConnection->deauthPacketReasonCode = STATUS_UNSPECIFIED;
1294            apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_STOP, pAPConnection);
1295        }
1296        return TI_OK;
1297    }
1298
1299    /* 4. Check if we are in the middle of switching channel */
1300    if (pAPConnection->currentState == AP_CONNECT_STATE_SWITCHING_CHANNEL)
1301    {
1302        /* Trigger received in the middle of switch channel, continue without reporting Roaming Manager */
1303        TRACE1(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "Roaming event during switch channel: ev = %d\n", roamingEventType);
1304        return TI_OK;
1305    }
1306
1307    /* 5. Report Roaming Manager */
1308    if ((pAPConnection->roamingEnabled == TI_TRUE) && (pAPConnection->roamEventCallb != NULL))
1309    {
1310        TRACE1(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "Roaming event raised: ev = %d\n", roamingEventType);
1311        if (roamingEventType == ROAMING_TRIGGER_LOW_QUALITY)
1312        {
1313            EvHandlerSendEvent(pAPConnection->hEvHandler, IPC_EVENT_LOW_RSSI, NULL,0);
1314        }
1315        /* Report to Roaming Manager */
1316        pAPConnection->roamEventCallb(pAPConnection->hRoamMng, &roamingEventType, reasonCode);
1317    }
1318
1319    return TI_OK;
1320}
1321
1322
1323/**
1324*
1325* apConn_RoamHandoffFinished
1326*
1327* \b Description:
1328*
1329* Called when XCC module receives response from the supplicant or recognizes
1330* timeout while waiting for the response
1331*
1332* \b ARGS:
1333*
1334* \b RETURNS:
1335*
1336* \sa
1337*/
1338void apConn_RoamHandoffFinished(TI_HANDLE hAPConnection)
1339{
1340    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1341
1342#ifdef TI_DBG
1343    if (hAPConnection == NULL) /* Failed to allocate control block */
1344    {
1345        WLAN_OS_REPORT(("FATAL ERROR: apConn_create(): Error allocating cb - aborting\n"));
1346        return;
1347    }
1348#endif
1349
1350    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_HAND_OVER, pAPConnection);
1351}
1352
1353
1354/**
1355*
1356* apConn_DisconnCompleteInd
1357*
1358* \b Description:
1359*
1360* DISASSOCIATE Packet was sent - proceed with stopping the module
1361*
1362* \b ARGS:
1363*
1364*  I   - pData - pointer to AP Connection context\n
1365*
1366* \b RETURNS:
1367*
1368*  None
1369*
1370* \sa
1371*/
1372void apConn_DisconnCompleteInd(TI_HANDLE hAPConnection, mgmtStatus_e status, TI_UINT32 uStatusCode)
1373{
1374    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1375
1376    apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
1377}
1378
1379
1380/**
1381*
1382* apConn_updateNeighborAPsList
1383*
1384* \b Description:
1385*
1386* Called by XCC Manager when Priority APs are found
1387*
1388* \b ARGS:
1389*
1390* \b RETURNS:
1391*
1392*  TI_OK if successful, TI_NOK otherwise.
1393*
1394* \sa
1395*/
1396void apConn_updateNeighborAPsList(TI_HANDLE hAPConnection, neighborAPList_t *pListOfpriorityAps)
1397{
1398    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1399
1400    if (pAPConnection->returnNeighborApsCallb != NULL )
1401    {
1402        pAPConnection->returnNeighborApsCallb(pAPConnection->hRoamMng, pListOfpriorityAps);
1403    }
1404}
1405
1406
1407/**
1408*
1409* apConn_getRoamingStatistics
1410*
1411* \b Description:
1412*
1413* Called from Measurement XCC sub-module when preparing TSM report to the AP.
1414*
1415* \b ARGS: AP Connection handle
1416*
1417* \b RETURNS:
1418*
1419*  total number of successful roams
1420*  delay of the latest successful roam
1421*
1422* \sa
1423*/
1424void apConn_getRoamingStatistics(TI_HANDLE hAPConnection, TI_UINT8 *roamingCount, TI_UINT16 *roamingDelay)
1425{
1426    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1427
1428    /* Get (and clear) total number of successful roams */
1429    *roamingCount = pAPConnection->roamingSuccesfulHandoverNum;
1430    pAPConnection->roamingSuccesfulHandoverNum = 0;
1431
1432    /* Get delay of the latest roam */
1433    *roamingDelay = pAPConnection->lastRoamingDelay;
1434    pAPConnection->lastRoamingDelay = 0;
1435}
1436
1437
1438
1439
1440/**
1441*
1442* apConn_resetRoamingStatistics
1443*
1444* \b Description:
1445*
1446* Called from Measurement XCC sub-module in order to re-start roaming statistics.
1447*
1448* \b ARGS: AP Connection handle
1449*
1450* \b RETURNS:
1451*
1452*  total number of successful roams
1453*  delay of the latest successful roam
1454*
1455* \sa
1456*/
1457void apConn_resetRoamingStatistics(TI_HANDLE hAPConnection)
1458{
1459    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1460
1461    pAPConnection->resetReportedRoamingStatistics = TI_TRUE;
1462    pAPConnection->roamingSuccesfulHandoverNum = 0;
1463    pAPConnection->lastRoamingDelay = 0;
1464}
1465
1466
1467/**
1468*
1469* apConn_printStatistics
1470*
1471* \b Description:
1472*
1473* Called by Site Manager when request to print statistics is requested from CLI
1474*
1475* \b ARGS: AP Connection handle
1476*
1477* \b RETURNS:
1478*
1479*  TI_OK if successful, TI_NOK otherwise.
1480*
1481* \sa
1482*/
1483void apConn_printStatistics(TI_HANDLE hAPConnection)
1484{
1485    WLAN_OS_REPORT(("-------------- Roaming Statistics ---------------\n\n"));
1486    WLAN_OS_REPORT(("- Low TX rate = %d\n",     ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_TX_RATE]));
1487    WLAN_OS_REPORT(("- Low SNR = %d\n",         ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_SNR]));
1488    WLAN_OS_REPORT(("- Low Quality = %d\n",     ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_LOW_QUALITY]));
1489    WLAN_OS_REPORT(("- MAX TX retries = %d\n",  ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_MAX_TX_RETRIES]));
1490    WLAN_OS_REPORT(("- BSS Loss TX = %d\n",     ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_BSS_LOSS]));
1491    WLAN_OS_REPORT(("- Switch Channel = %d\n",  ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_SWITCH_CHANNEL]));
1492    WLAN_OS_REPORT(("- AP Disconnect = %d\n",   ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_AP_DISCONNECT]));
1493    WLAN_OS_REPORT(("- SEC attack = %d\n",      ((apConn_t *)hAPConnection)->roamingTriggerEvents[ROAMING_TRIGGER_SECURITY_ATTACK]));
1494    WLAN_OS_REPORT(("\n"));
1495    WLAN_OS_REPORT(("- Successful roaming = %d\n",                  ((apConn_t *)hAPConnection)->roamingSuccesfulHandoverTotalNum));
1496    WLAN_OS_REPORT(("- UnSuccessful roaming = %d\n",                ((apConn_t *)hAPConnection)->roamingFailedHandoverNum));
1497    WLAN_OS_REPORT(("- Giving up roaming = %d\n",                   ((apConn_t *)hAPConnection)->retainCurrAPNum));
1498    WLAN_OS_REPORT(("- Disconnect cmd from roaming manager = %d\n", ((apConn_t *)hAPConnection)->disconnectFromRoamMngrNum));
1499    WLAN_OS_REPORT(("- Disconnect cmd from SME = %d\n",             ((apConn_t *)hAPConnection)->stopFromSmeNum));
1500    WLAN_OS_REPORT(("\n"));
1501}
1502
1503
1504
1505/**
1506*
1507* apConn_getVendorSpecificIE
1508*
1509* \b Description:
1510*
1511* Called by Association SM when request to associate is built and sent to AP;
1512* returns request updated with vendor specific info-element
1513*
1514* \b ARGS:
1515*
1516*  I   - hAPConnection - AP Connection handle\n
1517*  O   - pRequest - pointer to request buffer\n
1518*  O   - len - size of returned IE\n
1519*
1520* \b RETURNS:
1521*
1522*  TI_OK if successful, TI_NOK otherwise.
1523*
1524* \sa
1525*/
1526TI_STATUS apConn_getVendorSpecificIE(TI_HANDLE hAPConnection, TI_UINT8 *pRequest, TI_UINT32 *len)
1527{
1528    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
1529
1530    if (pAPConnection->vsIElength > 0)
1531    {
1532        *len = pAPConnection->vsIElength;
1533        os_memoryCopy(pAPConnection->hOs, pRequest, pAPConnection->vsIEbuf, pAPConnection->vsIElength);
1534    }
1535    else
1536    {
1537        *len = 0;
1538    }
1539    return TI_OK;
1540}
1541
1542
1543/* Internal functions implementation */
1544
1545
1546/**
1547*
1548* apConn_smEvent
1549*
1550* \b Description:
1551*
1552* AP Connection state machine transition function
1553*
1554* \b ARGS:
1555*
1556*  I/O - currentState - current state in the state machine\n
1557*  I   - event - specific event for the state machine\n
1558*  I   - pData - pointer to AP Connection context\n
1559*
1560* \b RETURNS:
1561*
1562*  TI_OK on success, TI_NOK otherwise.
1563*
1564* \sa
1565*/
1566static TI_STATUS apConn_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data)
1567{
1568    TI_STATUS   status;
1569    TI_UINT8       nextState;
1570    apConn_t    *pAPConnection;
1571
1572    pAPConnection = (apConn_t *)data;
1573    status = fsm_GetNextState(pAPConnection->apConnSM, (TI_UINT8)*currState, event, &nextState);
1574    if (status == TI_OK)
1575    {
1576		TRACE3( pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState);
1577
1578        status = fsm_Event(pAPConnection->apConnSM, (TI_UINT8 *)currState, event, pAPConnection);
1579        return status;
1580    }
1581    else
1582    {
1583        TRACE0(pAPConnection->hReport, REPORT_SEVERITY_ERROR, "apConn_smEvent, fsm_GetNextState error\n");
1584        return status;
1585    }
1586}
1587
1588
1589/**
1590*
1591* apConn_smNop - Do nothing
1592*
1593* \b Description:
1594*
1595* Do nothing in the SM.
1596*
1597* \b ARGS:
1598*
1599*  I   - pData - pointer to AP Connection context \n
1600*
1601* \b RETURNS:
1602*
1603*  TI_OK if successful, TI_NOK otherwise.
1604*
1605*
1606*/
1607static TI_STATUS apConn_smNop(void *pData)
1608{
1609	apConn_t *hReport = ((apConn_t *)pData)->hReport;
1610    TRACE0(hReport, REPORT_SEVERITY_INFORMATION, "apConn_smNop\n");
1611    return TI_OK;
1612}
1613
1614
1615/**
1616*
1617* apConn_smUnexpected - Unexpected event
1618*
1619* \b Description:
1620*
1621* Unexpected event in the SM.
1622*
1623* \b ARGS:
1624*
1625*  I   - pData - pointer to AP Connection context \n
1626*
1627* \b RETURNS:
1628*
1629*  TI_OK if successful, TI_NOK otherwise.
1630*
1631*
1632*/
1633static TI_STATUS apConn_smUnexpected(void *pData)
1634{
1635    TRACE0(((apConn_t *)pData)->hReport, REPORT_SEVERITY_INFORMATION, "apConn_smUnexpected\n");
1636    return TI_NOK;
1637}
1638
1639
1640/**
1641*
1642* apConn_startWaitingForTriggers
1643*
1644* \b Description:
1645*
1646* SME informs AP Connection module about successfull link establishment; start wiating for roaming triggers
1647*
1648* \b ARGS:
1649*
1650*  I   - pData - pointer to AP Connection context \n
1651*
1652* \b RETURNS:
1653*
1654*  TI_OK on success, TI_NOK otherwise.
1655*
1656* \sa
1657*/
1658static TI_STATUS apConn_startWaitingForTriggers(void *pData)
1659{
1660    apConn_t    *pAPConnection;
1661    apConn_connStatus_t reportStatus;
1662    paramInfo_t param;
1663
1664    pAPConnection = (apConn_t *)pData;
1665
1666    if ((pAPConnection->roamingEnabled) && (pAPConnection->reportStatusCallb != NULL))
1667    {
1668        param.paramType   = ASSOC_ASSOCIATION_REQ_PARAM;
1669
1670        assoc_getParam(pAPConnection->hAssoc, &param);
1671        reportStatus.dataBuf = (char *)(param.content.assocReqBuffer.buffer);
1672        reportStatus.dataBufLength = param.content.assocReqBuffer.bufferSize;
1673
1674        reportStatus.status = CONN_STATUS_CONNECTED;
1675        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
1676    }
1677    pAPConnection->firstAttempt2Roam = TI_TRUE;
1678    pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
1679    pAPConnection->removeKeys = TI_TRUE;
1680    pAPConnection->sendDeauthPacket = TI_TRUE;
1681    pAPConnection->reNegotiateTSPEC = TI_FALSE;
1682    pAPConnection->voiceTspecConfigured = TI_FALSE;
1683	pAPConnection->videoTspecConfigured = TI_FALSE;
1684    return TI_OK;
1685}
1686
1687
1688/**
1689*
1690* apConn_connectedToNewAP
1691*
1692* \b Description:
1693*
1694* After roaming was requested, Connection SM informs AP Connection module about
1695* successful link re-establishment; start waiting for roaming triggers
1696*
1697* \b ARGS:
1698*
1699*  I   - pData - pointer to AP Connection context \n
1700*
1701* \b RETURNS:
1702*
1703*  TI_OK on success, TI_NOK otherwise.
1704*
1705* \sa
1706*/
1707static TI_STATUS apConn_connectedToNewAP(void *pData)
1708{
1709    apConn_t    *pAPConnection;
1710    apConn_connStatus_t reportStatus;
1711    paramInfo_t param;
1712
1713    pAPConnection = (apConn_t *)pData;
1714
1715    /* Configure SCR group back to connection */
1716    scr_setGroup (pAPConnection->hScr, SCR_GID_CONNECTED);
1717
1718    /* Erase vendor specific info-element if was defined for last AP Assoc request */
1719    pAPConnection->vsIElength = 0;
1720
1721    /* TBD Notify Curr BSS module about update of current AP database */
1722
1723    if (pAPConnection->roamingFailedHandoverNum>0)
1724    {
1725        pAPConnection->roamingFailedHandoverNum--;
1726    }
1727    /* Report Roaming Manager */
1728    if (pAPConnection->reportStatusCallb != NULL)
1729    {
1730        param.paramType   = ASSOC_ASSOCIATION_REQ_PARAM;
1731
1732        assoc_getParam(pAPConnection->hAssoc, &param);
1733        reportStatus.dataBuf = (char *)(param.content.assocReqBuffer.buffer);
1734        reportStatus.dataBufLength = param.content.assocReqBuffer.bufferSize;
1735
1736        reportStatus.status = CONN_STATUS_HANDOVER_SUCCESS;
1737
1738        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
1739    }
1740    pAPConnection->firstAttempt2Roam = TI_TRUE;
1741    pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
1742    pAPConnection->roamingSuccesfulHandoverTotalNum++;
1743    pAPConnection->removeKeys = TI_TRUE;
1744    pAPConnection->sendDeauthPacket = TI_TRUE;
1745    pAPConnection->reNegotiateTSPEC = TI_FALSE;
1746    pAPConnection->voiceTspecConfigured = TI_FALSE;
1747	pAPConnection->videoTspecConfigured = TI_FALSE;
1748
1749
1750    if (!pAPConnection->resetReportedRoamingStatistics)
1751    {
1752        pAPConnection->roamingSuccesfulHandoverNum++;
1753        pAPConnection->lastRoamingDelay =
1754	        (TI_UINT16)os_timeStampMs(pAPConnection->hOs) - pAPConnection->roamingStartedTimestamp;
1755    }
1756    else
1757    {
1758        pAPConnection->resetReportedRoamingStatistics = TI_FALSE;
1759    }
1760
1761    /* Raise event of Roaming Completion */
1762    TRACE0(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "EvHandlerSendEvent -ROAMING_COMPLETE\n");
1763    EvHandlerSendEvent(pAPConnection->hEvHandler, IPC_EVENT_ROAMING_COMPLETE, NULL, 0);
1764
1765    return TI_OK;
1766}
1767
1768
1769/**
1770*
1771* apConn_stopConnection
1772*
1773* \b Description:
1774*
1775* Stop required before roaming was started
1776*
1777* \b ARGS:
1778*
1779*  I   - pData - pointer to AP Connection context\n
1780*
1781* \b RETURNS:
1782*
1783*  TI_OK on success, TI_NOK otherwise.
1784*
1785* \sa
1786*/
1787static TI_STATUS apConn_stopConnection(void *pData)
1788{
1789    apConn_t *pAPConnection;
1790    DisconnectType_e disConnType;
1791    pAPConnection = (apConn_t *)pData;
1792
1793    TRACE2(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, "apConn_stopConnection, calls conn_stop, removeKeys=%d, sendDeauthPacket=%d \n", pAPConnection->removeKeys, pAPConnection->sendDeauthPacket);
1794
1795    /* Erase vendor specific info-element if was defined for last AP Assoc request */
1796    pAPConnection->vsIElength = 0;
1797
1798    /* In case AP connection was stopped by SME, and radioOn is false, meaning immidiate shutdown is required without disassoc frame */
1799    /* Otherwise, ask for normal disconnection with disassoc frame */
1800    disConnType = (pAPConnection->sendDeauthPacket == TI_TRUE) ? DISCONNECT_DE_AUTH : DISCONNECT_IMMEDIATE;
1801
1802
1803
1804    /* set the SCr group to connecting */
1805    scr_setGroup (pAPConnection->hScr, SCR_GID_CONNECT);
1806
1807	/* Stop Connection state machine - always immediate TBD */
1808	conn_stop(pAPConnection->hConnSm,
1809			  disConnType,
1810			  pAPConnection->deauthPacketReasonCode,
1811			  pAPConnection->removeKeys, /* for Roaming, do not remove the keys */
1812			  apConn_DisconnCompleteInd,
1813			  pAPConnection);
1814
1815	pAPConnection->deauthPacketReasonCode = STATUS_UNSPECIFIED;
1816
1817    return TI_OK;
1818}
1819
1820
1821/**
1822*
1823* apConn_reportDisconnected
1824*
1825* \b Description:
1826*
1827* Moving from 'Disconnecting' state to 'Idle':
1828*   RoamMgr.status("not-connected")
1829*
1830* \b ARGS:
1831*
1832*  I   - pData - pointer to AP Connection context\n
1833*
1834* \b RETURNS:
1835*
1836*  TI_OK on success, TI_NOK otherwise.
1837*
1838* \sa
1839*/
1840static TI_STATUS apConn_reportDisconnected(void *pData)
1841{
1842    apConn_t    *pAPConnection;
1843    apConn_connStatus_t reportStatus;
1844
1845    pAPConnection = (apConn_t *)pData;
1846
1847    if (pAPConnection->reportStatusCallb != NULL)
1848    {
1849        reportStatus.status = CONN_STATUS_NOT_CONNECTED;
1850        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
1851    }
1852
1853    pAPConnection->firstAttempt2Roam = TI_TRUE;
1854
1855    /* Notify SME */
1856    apConn_reportConnStatusToSME(pAPConnection);
1857
1858    return TI_OK;
1859}
1860
1861
1862/**
1863*
1864* apConn_retainAP
1865*
1866* \b Description:
1867*
1868* Roaming Manager gives up on roaming.
1869* Moving from 'Wait for connection command' back to 'Wait for roam started.
1870*
1871* \b ARGS:
1872*
1873*  I   - pData - pointer to AP Connection context\n
1874*
1875* \b RETURNS:
1876*
1877*  TI_OK on success, TI_NOK otherwise.
1878*
1879* \sa
1880*/
1881static TI_STATUS apConn_retainAP(void *data)
1882{
1883    apConn_t    *pAPConnection;
1884    apConn_connStatus_t reportStatus;
1885    paramInfo_t param;
1886
1887    pAPConnection = (apConn_t *)data;
1888
1889    /* Configure SCR group back to connection */
1890    scr_setGroup (pAPConnection->hScr, SCR_GID_CONNECTED);
1891
1892    /* Report Roaming Manager */
1893    if (pAPConnection->reportStatusCallb != NULL)
1894    {
1895        param.paramType   = ASSOC_ASSOCIATION_REQ_PARAM;
1896
1897        assoc_getParam(pAPConnection->hAssoc, &param);
1898        reportStatus.dataBuf = (char *)(param.content.assocReqBuffer.buffer);
1899        reportStatus.dataBufLength = param.content.assocReqBuffer.bufferSize;
1900
1901        reportStatus.status = CONN_STATUS_HANDOVER_SUCCESS;
1902
1903        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
1904    }
1905    pAPConnection->retainCurrAPNum++;
1906
1907    pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
1908    pAPConnection->removeKeys = TI_TRUE;
1909    pAPConnection->sendDeauthPacket = TI_TRUE;
1910    pAPConnection->reNegotiateTSPEC = TI_FALSE;
1911    pAPConnection->voiceTspecConfigured = TI_FALSE;
1912	pAPConnection->videoTspecConfigured = TI_FALSE;
1913
1914    return TI_OK;
1915}
1916
1917
1918/**
1919*
1920* apConn_requestCCKM
1921*
1922* \b Description:
1923*
1924* Roaming Manager requests to roaming.
1925* Get CCKM (prepare hand-off).
1926*
1927* \b ARGS:
1928*
1929*  I   - pData - pointer to AP Connection context\n
1930*
1931* \b RETURNS:
1932*
1933*  TI_OK on success, TI_NOK otherwise.
1934*
1935* \sa
1936*/
1937static TI_STATUS apConn_requestCCKM(void *data)
1938{
1939    apConn_t    *pAPConnection;
1940    TI_STATUS   status;
1941
1942        pAPConnection = (apConn_t *)data;
1943
1944#ifdef XCC_MODULE_INCLUDED
1945        /* Send request to XCC module */
1946    apConn_calcNewTsf(pAPConnection, (TI_UINT8 *)&(pAPConnection->newAP->lastRxTSF), pAPConnection->newAP->lastRxHostTimestamp, pAPConnection->newAP->beaconInterval);
1947    status = XCCMngr_startCckm(pAPConnection->hXCCMngr, &(pAPConnection->newAP->BSSID), (TI_UINT8 *)&(pAPConnection->newAP->lastRxTSF));
1948#else
1949        status  = TI_OK;
1950        apConn_RoamHandoffFinished(pAPConnection);
1951#endif
1952        return status;
1953    }
1954
1955
1956#ifdef XCC_MODULE_INCLUDED
1957/**
1958*
1959* calcNewTsfTimestamp - Calculates the TSF
1960*
1961* \b Description:
1962*
1963* Calculates the TSF according to the delta of the TSF from the last Beacon/Probe Resp and the current time.
1964*
1965* \b ARGS:
1966*
1967*  I   - hRoamingMngr - pointer to the roamingMngr SM context  \n
1968*  I/O - tsfTimeStamp - the TSF field in the site entry of the roaming candidate AP
1969*  I   - newSiteOsTimeStamp - the TS field in the site entry of the roaming candidate AP
1970*
1971* \b RETURNS:
1972*
1973*  Nothing.
1974*
1975*
1976*/
1977static void apConn_calcNewTsf(apConn_t *hAPConnection, TI_UINT8 *tsfTimeStamp, TI_UINT32 newSiteOsTimeStamp, TI_UINT32 beaconInterval)
1978{
1979    apConn_t    *pAPConnection = hAPConnection;
1980    TI_UINT32      osTimeStamp = os_timeStampMs(pAPConnection->hOs);
1981    TI_UINT32      deltaTimeStamp;
1982    TI_UINT32      tsfLsdw,tsfMsdw, newOsTimeStamp;
1983    TI_UINT32      remainder;
1984    TI_UINT8       newTsfTimestamp[TIME_STAMP_LEN];
1985
1986    /* get the delta TS between the TS of the last Beacon/ProbeResp-from the site table
1987    and the current TS */
1988    deltaTimeStamp = osTimeStamp - newSiteOsTimeStamp;
1989    tsfLsdw = *((TI_UINT32*)&tsfTimeStamp[0]);
1990    tsfMsdw = *((TI_UINT32*)&tsfTimeStamp[4]);
1991
1992    TRACE2(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, " TSF time LSDW reversed=%x, TSF time MSDW reversed=%x\n", tsfLsdw, tsfMsdw);
1993
1994    deltaTimeStamp = deltaTimeStamp*1000;/* from mSec to uSec*/
1995    /* Before adding, save remainder */
1996    remainder = tsfTimeStamp[3] + ((deltaTimeStamp & 0xff000000) >> 24);
1997
1998    /* The LS DW of the TS is the TSF taken from the last Beacon/Probe Resp
1999        + the delta TS from the time the Beacon/Probe Resp arrive till now. */
2000    newOsTimeStamp = deltaTimeStamp+tsfLsdw;
2001
2002    /* substracting one beacon interval */
2003    newOsTimeStamp -= (beaconInterval * 1024); /* im usec */
2004
2005    /* save just for debug printout */
2006    deltaTimeStamp +=osTimeStamp; /* uMsec */
2007    /* update the LSB of the TSF */
2008    newTsfTimestamp[0] = newOsTimeStamp & 0x000000ff;
2009    newTsfTimestamp[1] = (newOsTimeStamp & 0x0000ff00) >> 8;
2010    newTsfTimestamp[2] = (newOsTimeStamp & 0x00ff0000) >> 16;
2011    newTsfTimestamp[3] = (newOsTimeStamp & 0xff000000) >> 24;
2012
2013    /* increase the MSB in case of overflow */
2014    if (remainder > 0xff)
2015    {
2016        tsfMsdw++;
2017
2018    }
2019    /* update the MSB of the TSF */
2020    newTsfTimestamp[4] = tsfMsdw & 0x000000ff;
2021    newTsfTimestamp[5] = (tsfMsdw & 0x0000ff00) >> 8;
2022    newTsfTimestamp[6] = (tsfMsdw & 0x00ff0000) >> 16;
2023    newTsfTimestamp[7] = (tsfMsdw & 0xff000000) >> 24;
2024
2025    TRACE11(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, " NEW TSF time: reversedTsfTimeStamp= 0x%x, New deltaTimeStamp= 0x%x, \n remainder=0x%x, new tsfTimeStamp=%x-%x-%x-%x-%x-%x-%x-%x\n", newOsTimeStamp, deltaTimeStamp, remainder, newTsfTimestamp[0], newTsfTimestamp[1], newTsfTimestamp[2], newTsfTimestamp[3], newTsfTimestamp[4], newTsfTimestamp[5], newTsfTimestamp[6], newTsfTimestamp[7]);
2026
2027    os_memoryCopy(pAPConnection->hOs, tsfTimeStamp, newTsfTimestamp, TIME_STAMP_LEN);
2028}
2029#endif
2030
2031
2032/**
2033*
2034* apConn_invokeConnectionToNewAp
2035*
2036* \b Description:
2037*
2038* Got CCKM (hand-off), start re-connection to another AP
2039*
2040* \b ARGS:
2041*
2042*  I   - pData - pointer to AP Connection context\n
2043*
2044* \b RETURNS:
2045*
2046*  TI_OK on success, TI_NOK otherwise.
2047*
2048* \sa
2049*/
2050static TI_STATUS apConn_invokeConnectionToNewAp(void *data)
2051{
2052    apConn_t    *pAPConnection;
2053    EConnType    connType;
2054    paramInfo_t param;
2055    TI_UINT8     staPrivacySupported, apPrivacySupported;
2056    TI_BOOL      renegotiateTspec = TI_FALSE;
2057
2058	pAPConnection = (apConn_t *)data;
2059
2060	pAPConnection->roamingStartedTimestamp = os_timeStampMs(pAPConnection->hOs);
2061
2062    /* Check privacy compatibility */
2063    param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
2064    rsn_getParam(pAPConnection->hPrivacy, &param);
2065
2066    staPrivacySupported = (param.content.rsnEncryptionStatus == TWD_CIPHER_NONE) ? TI_FALSE : TI_TRUE;
2067    apPrivacySupported  = ((pAPConnection->newAP->capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TI_TRUE : TI_FALSE;
2068
2069    if (staPrivacySupported != apPrivacySupported)
2070    {
2071        param.paramType = RSN_MIXED_MODE;
2072        rsn_getParam(pAPConnection->hPrivacy, &param);
2073
2074        if (apPrivacySupported ||
2075            (!param.content.rsnMixedMode && staPrivacySupported))
2076        {
2077            TRACE2(pAPConnection->hReport, REPORT_SEVERITY_WARNING, ": failed privacy comparison %d vs. %d\n", staPrivacySupported, apPrivacySupported);
2078            return (apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection));
2079        }
2080    }
2081
2082    /* Update data info of desired AP; in case of first attempt to roam,
2083       store previous primary site info */
2084    if (siteMgr_overwritePrimarySite(pAPConnection->hSiteMgr, pAPConnection->newAP, pAPConnection->firstAttempt2Roam) != TI_OK)
2085    {
2086        TRACE0(pAPConnection->hReport, REPORT_SEVERITY_WARNING, ": failed to ovewrite Primary Site\n");
2087        return (apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection));
2088    }
2089
2090    /* Update re-associate parameter of MLME */
2091    if (pAPConnection->requestType == AP_CONNECT_FAST_TO_AP)
2092    {
2093        connType = CONN_TYPE_ROAM;
2094    }
2095    else
2096    {
2097        connType = CONN_TYPE_FIRST_CONN;
2098    }
2099
2100#ifdef XCC_MODULE_INCLUDED
2101    /* Check the need in TSPEC re-negotiation */
2102    if ( (pAPConnection->voiceTspecConfigured || pAPConnection->videoTspecConfigured) && pAPConnection->reNegotiateTSPEC )
2103    {
2104        /* If the candidate AP is at least XCCver4 AP, try to re-negotiate TSPECs */
2105        if (XCCMngr_parseXCCVer(pAPConnection->hXCCMngr,
2106                                pAPConnection->newAP->pBuffer,
2107                                pAPConnection->newAP->bufferLength) >= 4)
2108        {
2109            renegotiateTspec = TI_TRUE;
2110        }
2111    }
2112#endif
2113
2114    TRACE2(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, ": calls conn_start, removeKeys=%d, renegotiateTSPEC=%d\n", pAPConnection->removeKeys, renegotiateTspec);
2115
2116    /* Start Connection state machine */
2117    return conn_start(pAPConnection->hConnSm,
2118                      connType,
2119                      apConn_ConnCompleteInd,
2120                      pAPConnection,
2121                      pAPConnection->removeKeys,
2122                      renegotiateTspec);
2123}
2124
2125
2126/**
2127*
2128* apConn_reportConnFail
2129*
2130* \b Description:
2131*
2132* Got 'Failed' indication from Connection state machine - inform Roaming Manager Module
2133*
2134* \b ARGS:
2135*
2136*  I   - pData - pointer to AP Connection context\n
2137*
2138* \b RETURNS:
2139*
2140*  TI_OK on success, TI_NOK otherwise.
2141*
2142* \sa
2143*/
2144static TI_STATUS apConn_reportConnFail(void *data)
2145{
2146    apConn_t *pAPConnection;
2147    apConn_connStatus_t reportStatus;
2148    paramInfo_t param;
2149
2150    pAPConnection = (apConn_t *)data;
2151
2152    pAPConnection->firstAttempt2Roam = TI_FALSE;
2153    pAPConnection->resetReportedRoamingStatistics = TI_FALSE;
2154
2155    /* Erase vendor specific info-element if was defined for last AP Assoc request */
2156    pAPConnection->vsIElength = 0;
2157
2158    /* Report to Roaming Manager */
2159    if (pAPConnection->reportStatusCallb != NULL)
2160    {
2161        param.paramType   = ASSOC_ASSOCIATION_REQ_PARAM;
2162
2163        assoc_getParam(pAPConnection->hAssoc, &param);
2164        reportStatus.dataBuf = (char *)(param.content.assocReqBuffer.buffer);
2165        reportStatus.dataBufLength = param.content.assocReqBuffer.bufferSize;
2166
2167        reportStatus.status = CONN_STATUS_HANDOVER_FAILURE;
2168
2169        pAPConnection->reportStatusCallb(pAPConnection->hRoamMng, &reportStatus);
2170    }
2171
2172    return TI_OK;
2173}
2174
2175
2176/**
2177*
2178* apConn_configureSCR
2179*
2180* \b Description:
2181*
2182* Got 'Failed' indication from Connection state machine - inform Roaming Manager Module
2183*
2184* \b ARGS:
2185*
2186*  I   - pData - pointer to AP Connection context\n
2187*
2188* \b RETURNS:
2189*
2190*  TI_OK on success, TI_NOK otherwise.
2191*
2192* \sa
2193*/
2194static TI_STATUS apConn_configureDriverBeforeRoaming(void *pData)
2195{
2196    apConn_t    *pAPConnection = (apConn_t*)pData;
2197    paramInfo_t param;
2198
2199    /* Configure SCR group of allowed clients according to 'Roaming' rule */
2200    scr_setGroup (pAPConnection->hScr, SCR_GID_ROAMING);
2201    param.paramType = QOS_MNGR_VOICE_RE_NEGOTIATE_TSPEC;
2202    qosMngr_getParams(pAPConnection->hQos, &param);
2203    pAPConnection->voiceTspecConfigured = param.content.TspecConfigure.voiceTspecConfigure;
2204    pAPConnection->videoTspecConfigured = param.content.TspecConfigure.videoTspecConfigure;
2205    pAPConnection->resetReportedRoamingStatistics = TI_FALSE;
2206    return TI_OK;
2207}
2208
2209
2210/**
2211*
2212* apConn_swChFinished
2213*
2214* \b Description:
2215*
2216* Switch channel completed; if there were roaming Manager triggers meanwhile,
2217* inform Roaming Manager Module
2218*
2219* \b ARGS:
2220*
2221*  I   - pData - pointer to AP Connection context\n
2222*
2223* \b RETURNS:
2224*
2225*  TI_OK on success, TI_NOK otherwise.
2226*
2227* \sa
2228*/
2229static TI_STATUS apConn_swChFinished(void *pData)
2230{
2231    apConn_t *pAPConnection = (apConn_t *)pData;
2232
2233    /* Inform Current BSS module */
2234    currBSS_restartRssiCounting(pAPConnection->hCurrBSS);
2235
2236    /* If there are unreported roaming triggers of 'No AP' type,
2237       report them now to roaming manager */
2238    if (pAPConnection->roamReason >= ROAMING_TRIGGER_MAX_TX_RETRIES)
2239    {
2240        if ((pAPConnection->roamingEnabled == TI_TRUE) &&
2241            (pAPConnection->roamEventCallb != NULL))
2242        {
2243            /* Report to Roaming Manager */
2244            pAPConnection->roamEventCallb(pAPConnection->hRoamMng, &pAPConnection->roamReason, (TI_UINT16)0);
2245        }
2246    }
2247    else
2248    {
2249        pAPConnection->roamReason = ROAMING_TRIGGER_NONE;
2250    }
2251
2252    return TI_OK;
2253}
2254
2255
2256/**
2257*
2258* apConn_handleTspecReneg
2259*
2260* \b Description:
2261*
2262* This function will be called when moving from CONNECTING state to
2263* START_TSPEC_RENEGOTIATION state. It checks if TSPEC re-negotiation was requested
2264* by roaming manager, if the TSPEC for voice was defined by user application,
2265* if the re-negotiation was performed during hand-over.
2266* If so, it will trigger moving to WAIT_ROAM state, otherwise it will start
2267* TSPEC negotiation, staying in the REESTABLISHING_VOICE state and waiting
2268* for results.
2269*
2270* \b ARGS:
2271*
2272*  I   - pData - pointer to AP Connection context\n
2273*
2274* \b RETURNS:
2275*
2276*  TI_OK on success, TI_NOK otherwise.
2277*
2278* \sa
2279*/
2280static TI_STATUS apConn_handleTspecReneg (void *pData)
2281{
2282    apConn_t *pAPConnection = (apConn_t *)pData;
2283    paramInfo_t param;
2284
2285    if (pAPConnection->voiceTspecConfigured && pAPConnection->reNegotiateTSPEC)
2286    {
2287        param.paramType = QOS_MNGR_VOICE_RE_NEGOTIATE_TSPEC;
2288        qosMngr_getParams(pAPConnection->hQos, &param);
2289
2290        if (param.content.TspecConfigure.voiceTspecConfigure == TI_TRUE)
2291        {
2292            /* TSPEC is already configured, move to CONNECTED */
2293            return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
2294        }
2295        else
2296        {
2297            param.paramType = QOS_MNGR_RESEND_TSPEC_REQUEST;
2298            param.content.qosRenegotiateTspecRequest.callback = (void *)apConn_qosMngrReportResultCallb;
2299            param.content.qosRenegotiateTspecRequest.handler = pData;
2300
2301            if (qosMngr_setParams(pAPConnection->hQos, &param) != TI_OK)
2302            {
2303                /* Re-negotiation of TSPEC cannot be performed */
2304                return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection);
2305            }
2306            return TI_OK;
2307        }
2308    }
2309    else
2310    {
2311        /* No need to re-negotiate TSPEC, move to CONNECTED */
2312        return apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
2313    }
2314}
2315
2316
2317/**
2318*
2319* apConn_qosMngrReportResultCallb
2320*
2321* \b Description:
2322*
2323* This function will be transferred to QoS manager upon request to start negotiation
2324* of the TSPEC for voice and signaling, and will be called when the voice TSPEC
2325* renegotiation is completed. The function will generate FINISHED_OK or
2326* FINISHED_NOK events to the state machine of AP Connection, triggering change of
2327* the current state.
2328*
2329* \b ARGS:
2330*
2331*  I   - hApConn - pointer to AP Connection context\n
2332*  I   - result - returned by Traffic admission control\n
2333*
2334* \b RETURNS:
2335*
2336*  TI_OK on success, TI_NOK otherwise.
2337*
2338* \sa
2339*/
2340static TI_STATUS apConn_qosMngrReportResultCallb (TI_HANDLE hApConn, trafficAdmRequestStatus_e result)
2341{
2342    apConn_t *pAPConnection = (apConn_t *)hApConn;
2343
2344    AP_CONN_VALIDATE_HANDLE(hApConn);
2345
2346    if (result == STATUS_TRAFFIC_ADM_REQUEST_ACCEPT)
2347    {
2348        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_OK, pAPConnection);
2349    }
2350    else
2351    {
2352        apConn_smEvent(&(pAPConnection->currentState), AP_CONNECT_EVENT_FINISHED_NOT_OK, pAPConnection);
2353    }
2354    return TI_OK;
2355}
2356
2357/**
2358*
2359* apConn_reportConnStatusToSME
2360*
2361* \b Description:
2362*
2363* Sends report to SME regarding the connection status
2364*
2365* \b ARGS:
2366*
2367*  I   - pAPConnection  - pointer to AP Connection context\n
2368*
2369* \b RETURNS:
2370*
2371*  OK on success, NOK otherwise.
2372*
2373* \sa
2374*/
2375static void apConn_reportConnStatusToSME (apConn_t *pAPConnection)
2376{
2377
2378TRACE3(pAPConnection->hReport, REPORT_SEVERITY_INFORMATION, " roamingTrigger = %d, APDisconnectStatusCode = %d, bNonRoamingDisAssocReason = %d\n", pAPConnection->roamReason, pAPConnection->APDisconnect.uStatusCode, 		pAPConnection->bNonRoamingDisAssocReason);
2379
2380	/* Check if an outside reason caused the disconnection. */
2381	if (pAPConnection->bNonRoamingDisAssocReason)
2382	{
2383		pAPConnection->bNonRoamingDisAssocReason = TI_FALSE;
2384		sme_ReportApConnStatus(pAPConnection->hSme, STATUS_UNSPECIFIED, 0);
2385	}
2386    /* DisAssociation happened due to roaming trigger */
2387	else if (pAPConnection->roamReason == ROAMING_TRIGGER_AP_DISCONNECT)
2388	{	/* AP disconnect is a special case of the status delivered to SME */
2389		mgmtStatus_e mgmtStatus = ( pAPConnection->APDisconnect.bDeAuthenticate ? STATUS_AP_DEAUTHENTICATE : STATUS_AP_DISASSOCIATE );
2390		sme_ReportApConnStatus(pAPConnection->hSme, mgmtStatus, pAPConnection->APDisconnect.uStatusCode);
2391	}
2392	else	/* Finally, just send the last roaming trigger */
2393	{
2394		sme_ReportApConnStatus(pAPConnection->hSme, STATUS_ROAMING_TRIGGER, (TI_UINT32)pAPConnection->roamReason);
2395	}
2396}
2397
2398
2399void apConn_setDeauthPacketReasonCode(TI_HANDLE hAPConnection, TI_UINT8 deauthReasonCode)
2400{
2401    apConn_t *pAPConnection = (apConn_t *)hAPConnection;
2402
2403	pAPConnection->deauthPacketReasonCode = deauthReasonCode;
2404	pAPConnection->roamReason = ROAMING_TRIGGER_SECURITY_ATTACK;
2405}
2406