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