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