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 */ 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 */ 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 */ 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 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 */ 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 */ 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 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 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 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, ¶m); 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 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 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 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 880 if (param.content.regulatoryDomainEnabled) 881 { /* 802.11d is enabled */ 882 pList->regDomain = REG_DOMAIN_80211D; 883 } 884 } 885 return TI_OK; 886 } 887 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 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 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 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, ¶m); 966 967 return param.content.rsnPreAuthStatus; 968 } 969 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 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 */ 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 */ 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 */ 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 */ 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 */ 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, ¶m); 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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, ¶m); 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 */ 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, ¶m); 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 */ 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 */ 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 */ 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, ¶m); 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 */ 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 */ 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 */ 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, ¶m); 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 APs dont 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, ¶m); 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 */ 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, ¶m); 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 */ 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, ¶m); 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 */ 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 */ 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, ¶m); 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, ¶m) != 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 */ 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 */ 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 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 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