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