• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
114 typedef 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 */
131 typedef 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 */
164 typedef 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 */
237 static TI_STATUS apConn_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data);
238 static TI_STATUS apConn_smNop(void *pData);
239 static TI_STATUS apConn_smUnexpected(void *pData);
240 static TI_STATUS apConn_startWaitingForTriggers(void *pData);
241 static TI_STATUS apConn_connectedToNewAP(void *pData);
242 static TI_STATUS apConn_configureDriverBeforeRoaming(void *pData);
243 static TI_STATUS apConn_stopConnection(void *pData);
244 static TI_STATUS apConn_invokeConnectionToNewAp(void *pData);
245 static TI_STATUS apConn_reportDisconnected(void *pData);
246 static TI_STATUS apConn_retainAP(void *pData);
247 static TI_STATUS apConn_requestCCKM(void *pData);
248 static TI_STATUS apConn_reportConnFail(void *pData);
249 static TI_STATUS apConn_swChFinished(void *pData);
250 static TI_STATUS apConn_handleTspecReneg (void *pData);
251 
252 /* other functions */
253 #ifdef XCC_MODULE_INCLUDED
254 static void apConn_calcNewTsf(apConn_t *hAPConnection, TI_UINT8 *tsfTimeStamp, TI_UINT32 newSiteOsTimeStamp, TI_UINT32 beaconInterval);
255 #endif
256 static TI_STATUS apConn_qosMngrReportResultCallb (TI_HANDLE hApConn, trafficAdmRequestStatus_e result);
257 static 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 */
apConn_create(TI_HANDLE hOs)285 TI_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 */
apConn_unload(TI_HANDLE hAPConnection)333 TI_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 */
apConn_init(TStadHandlesList * pStadHandles)368 void 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 
apConn_SetDefaults(TI_HANDLE hAPConnection,apConnParams_t * pApConnParams)504 TI_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 */
apConn_isPsRequiredBeforeScan(TI_HANDLE hAPConnection)563 TI_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 */
apConn_ConnCompleteInd(TI_HANDLE hAPConnection,mgmtStatus_e status,TI_UINT32 uStatusCode)595 void 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 
apConn_getRoamThresholds(TI_HANDLE hAPConnection,roamingMngrThresholdsConfig_t * pParam)609 TI_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 
apConn_setRoamThresholds(TI_HANDLE hAPConnection,roamingMngrThresholdsConfig_t * pParam)626 TI_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 
apConn_registerRoamMngrCallb(TI_HANDLE hAPConnection,apConn_roamMngrEventCallb_t roamEventCallb,apConn_roamMngrCallb_t reportStatusCallb,apConn_roamMngrCallb_t returnNeighborApsCallb)675 TI_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 
apConn_unregisterRoamMngrCallb(TI_HANDLE hAPConnection)706 TI_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 
apConn_disconnect(TI_HANDLE hAPConnection)726 TI_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 
apConn_getStaCapabilities(TI_HANDLE hAPConnection,apConn_staCapabilities_t * ie_list)744 TI_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 
apConn_connectToAP(TI_HANDLE hAPConnection,bssEntry_t * newAP,apConn_connRequest_t * request,TI_BOOL reNegotiateTspec)879 TI_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 
apConn_getBSSParams(TI_HANDLE hAPConnection)927 bssEntry_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 
apConn_isSiteBanned(TI_HANDLE hAPConnection,TMacAddr * givenAp)940 TI_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 
apConn_getPreAuthAPStatus(TI_HANDLE hAPConnection,TMacAddr * givenAp)947 TI_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 
apConn_preAuthenticate(TI_HANDLE hAPConnection,bssList_t * listAPs)961 TI_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 
apConn_prepareToRoaming(TI_HANDLE hAPConnection,apConn_roamingTrigger_e reason)1026 TI_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 */
apConn_indicateSwitchChannelInProgress(TI_HANDLE hAPConnection)1057 TI_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 */
apConn_indicateSwitchChannelFinished(TI_HANDLE hAPConnection)1086 TI_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 */
apConn_start(TI_HANDLE hAPConnection,TI_BOOL roamingEnabled)1117 TI_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 */
apConn_stop(TI_HANDLE hAPConnection,TI_BOOL removeKeys)1147 TI_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 */
apConn_reportRoamingEvent(TI_HANDLE hAPConnection,apConn_roamingTrigger_e roamingEventType,roamingEventData_u * pRoamingEventData)1188 TI_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 */
apConn_RoamHandoffFinished(TI_HANDLE hAPConnection)1338 void 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 */
apConn_DisconnCompleteInd(TI_HANDLE hAPConnection,mgmtStatus_e status,TI_UINT32 uStatusCode)1372 void 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 */
apConn_updateNeighborAPsList(TI_HANDLE hAPConnection,neighborAPList_t * pListOfpriorityAps)1396 void 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 */
apConn_getRoamingStatistics(TI_HANDLE hAPConnection,TI_UINT8 * roamingCount,TI_UINT16 * roamingDelay)1424 void 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 */
apConn_resetRoamingStatistics(TI_HANDLE hAPConnection)1457 void 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 */
apConn_printStatistics(TI_HANDLE hAPConnection)1483 void 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 */
apConn_getVendorSpecificIE(TI_HANDLE hAPConnection,TI_UINT8 * pRequest,TI_UINT32 * len)1526 TI_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 */
apConn_smEvent(TI_UINT8 * currState,TI_UINT8 event,void * data)1566 static 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 */
apConn_smNop(void * pData)1607 static 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 */
apConn_smUnexpected(void * pData)1633 static 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 */
apConn_startWaitingForTriggers(void * pData)1658 static 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 */
apConn_connectedToNewAP(void * pData)1707 static 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 */
apConn_stopConnection(void * pData)1787 static 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 */
apConn_reportDisconnected(void * pData)1840 static 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 */
apConn_retainAP(void * data)1881 static 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 */
apConn_requestCCKM(void * data)1937 static 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 */
apConn_calcNewTsf(apConn_t * hAPConnection,TI_UINT8 * tsfTimeStamp,TI_UINT32 newSiteOsTimeStamp,TI_UINT32 beaconInterval)1977 static 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 */
apConn_invokeConnectionToNewAp(void * data)2050 static 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 */
apConn_reportConnFail(void * data)2144 static 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 */
apConn_configureDriverBeforeRoaming(void * pData)2194 static 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 */
apConn_swChFinished(void * pData)2229 static 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 */
apConn_handleTspecReneg(void * pData)2280 static 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 */
apConn_qosMngrReportResultCallb(TI_HANDLE hApConn,trafficAdmRequestStatus_e result)2340 static 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 */
apConn_reportConnStatusToSME(apConn_t * pAPConnection)2375 static void apConn_reportConnStatusToSME (apConn_t *pAPConnection)
2376 {
2377 
2378 TRACE3(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 
apConn_setDeauthPacketReasonCode(TI_HANDLE hAPConnection,TI_UINT8 deauthReasonCode)2399 void 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