1 /* 2 * sme.c 3 * 4 * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /** \file sme.c 35 * \brief SME implementation 36 * 37 * \see sme.h, smeSm.c smePrivate.h 38 */ 39 40 41 #define __FILE_ID__ FILE_ID_41 42 #include "smePrivate.h" 43 #include "GenSM.h" 44 #include "scanResultTable.h" 45 #include "smeSm.h" 46 #include "siteMgrApi.h" 47 #include "regulatoryDomainApi.h" 48 #include "connApi.h" 49 50 51 /** 52 * \fn sme_Create 53 * \brief Creates the SME module. Allocates system resources 54 * 55 * Creates the SME module. Allocates system resources 56 * 57 * \param hOS - handle to the OS adaptation layer 58 * \return Handle to the SME object 59 * \sa sme_Init, sme_SetDefaults, sme_Destroy 60 */ 61 TI_HANDLE sme_Create (TI_HANDLE hOS) 62 { 63 TSme *pSme; 64 65 /* allocate space for the SME object */ 66 pSme = (TSme*)os_memoryAlloc (hOS, sizeof (TSme)); 67 if (NULL == pSme) 68 { 69 WLAN_OS_REPORT (("sme_Create: unable to allocate memor yfor SME object. SME craetion failed\n")); 70 return NULL; 71 } 72 73 /* nullify SME object */ 74 os_memoryZero (hOS, (void*)pSme, sizeof (TSme)); 75 76 /* store OS handle */ 77 pSme->hOS = hOS; 78 79 /* Create SME generic state-machine */ 80 pSme->hSmeSm = genSM_Create (hOS); 81 if (NULL == pSme->hSmeSm) 82 { 83 WLAN_OS_REPORT (("sme_Create: unable to create SME generic SM. SME creation failed\n")); 84 sme_Destroy ((TI_HANDLE)pSme); 85 return NULL; 86 } 87 88 /* Create SME scan result table */ 89 pSme->hSmeScanResultTable = scanResultTable_Create (hOS, SME_SCAN_TABLE_ENTRIES); 90 if (NULL == pSme->hSmeScanResultTable) 91 { 92 WLAN_OS_REPORT (("sme_Create: unable to create scan result table. SME creation failed\n")); 93 sme_Destroy ((TI_HANDLE)pSme); 94 return NULL; 95 } 96 97 return (TI_HANDLE)pSme; 98 } 99 100 /** 101 * \fn sme_Init 102 * \brief Initializes the SME object. Store module handles 103 * 104 * Initializes the SME object. Store module handles 105 * 106 * \param pStadHandles - pointer to the handles structure 107 * \return None 108 * \sa sme_Create, sme_SetDefaults 109 */ 110 void sme_Init (TStadHandlesList *pStadHandles) 111 { 112 TSme *pSme = pStadHandles->hSme; 113 114 /* Store object handles */ 115 pSme->hReport = pStadHandles->hReport; 116 pSme->hScanCncn = pStadHandles->hScanCncn; 117 pSme->hApConn = pStadHandles->hAPConnection; 118 pSme->hConn = pStadHandles->hConn; 119 pSme->hScr = pStadHandles->hSCR; 120 pSme->hRegDomain = pStadHandles->hRegulatoryDomain; 121 pSme->hEvHandler = pStadHandles->hEvHandler; 122 pSme->hSiteMgr = pStadHandles->hSiteMgr; 123 pSme->hRsn = pStadHandles->hRsn; 124 pSme->hDrvMain = pStadHandles->hDrvMain; 125 pSme->hTwd = pStadHandles->hTWD; 126 127 128 /* Initialize the scan result table object */ 129 scanResultTable_Init (pSme->hSmeScanResultTable, pStadHandles, SCAN_RESULT_TABLE_CLEAR); 130 131 /* Initialize the SME state-machine object */ 132 genSM_Init (pSme->hSmeSm, pStadHandles->hReport); 133 } 134 135 /** 136 * \fn sme_SetDefaults 137 * \brief Set default values to the SME (and the SM and scan result table) 138 * 139 * Set default values to the SME (and the SM and scan result table) 140 * 141 * \param hSme - handle to the SME object 142 * \param pInitParams - values read from registry / ini file 143 * \return None 144 * \sa sme_Create, sme_Init 145 */ 146 void sme_SetDefaults (TI_HANDLE hSme, TSmeModifiedInitParams *pModifiedInitParams, TSmeInitParams *pInitParams) 147 { 148 TSme *pSme = (TSme*)hSme; 149 150 /* copy init params */ 151 os_memoryCopy (pSme->hOS, &(pSme->tInitParams), pInitParams, sizeof (TSmeInitParams)); 152 153 /* initialize SME varaibles */ 154 pSme->bRadioOn = pModifiedInitParams->bRadioOn; 155 pSme->eConnectMode = pModifiedInitParams->eConnectMode; 156 if (CONNECT_MODE_AUTO == pSme->eConnectMode) 157 { 158 pSme->hScanResultTable = pSme->hSmeScanResultTable; 159 } 160 else if (CONNECT_MODE_MANUAL == pSme->eConnectMode) 161 { 162 pSme->hScanResultTable = pSme->hScanCncnScanResulTable; 163 } 164 165 pSme->eBssType = pModifiedInitParams->eDesiredBssType; 166 MAC_COPY (pSme->tBssid, pModifiedInitParams->tDesiredBssid); 167 168 pSme->tSsid.len = pModifiedInitParams->tDesiredSsid.len; 169 if ( pSme->tSsid.len > MAX_SSID_LEN ) 170 { 171 TRACE2( pSme->hReport, REPORT_SEVERITY_ERROR, "sme_SetDefaults. pSme->tSsid.len=%d exceeds the limit %d\n", pSme->tSsid.len, MAX_SSID_LEN); 172 pSme->tSsid.len = MAX_SSID_LEN; 173 } 174 os_memoryCopy (pSme->hOS, &(pSme->tSsid.str[ 0 ]), &(pModifiedInitParams->tDesiredSsid.str[ 0 ]), pSme->tSsid.len); 175 if (OS_802_11_SSID_JUNK (pSme->tSsid.str, pSme->tSsid.len)) 176 { 177 pSme->eSsidType = SSID_TYPE_INVALID; 178 pSme->bConnectRequired = TI_FALSE; 179 } 180 else if (0 == pSme->tSsid.len) 181 { 182 pSme->eSsidType = SSID_TYPE_ANY; 183 pSme->bConnectRequired = TI_TRUE; 184 } 185 else 186 { 187 pSme->eSsidType = SSID_TYPE_SPECIFIC; 188 pSme->bConnectRequired = TI_TRUE; 189 } 190 191 pSme->eLastConnectMode = CONNECT_MODE_AUTO; 192 pSme->bAuthSent = TI_FALSE; 193 pSme->bReselect = TI_FALSE; 194 pSme->uScanCount = 0; 195 pSme->bRunning = TI_FALSE; 196 197 /* Initialize the SME state-machine */ 198 genSM_SetDefaults (pSme->hSmeSm, SME_SM_NUMBER_OF_STATES, SME_SM_NUMBER_OF_EVENTS, (TGenSM_matrix)tSmMatrix, 199 SME_SM_STATE_IDLE, "SME SM", uStateDescription, uEventDescription, __FILE_ID__); 200 201 /* register scan conecntrator CB */ 202 scanCncn_RegisterScanResultCB (pSme->hScanCncn, SCAN_SCC_DRIVER, sme_ScanResultCB, hSme); 203 } 204 205 /** 206 * \fn sme_setScanResultTable 207 * \brief Sets the scanResultTable pointer for the manual mode. 208 * \param hSme - handle to the SME object 209 * \param hScanResultTable - pointer to ScanResultTable 210 * \return none 211 */ 212 void sme_SetScanResultTable(TI_HANDLE hSme, TI_HANDLE hScanResultTable) 213 { 214 TSme *pSme = (TSme*)hSme; 215 216 pSme->hScanCncnScanResulTable = hScanResultTable; 217 if (CONNECT_MODE_MANUAL == pSme->eConnectMode) 218 { 219 pSme->hScanResultTable = pSme->hScanCncnScanResulTable; 220 } 221 } 222 223 /** 224 * \fn sme_Destroy 225 * \brief Destroys the SME object. De-allocates system resources 226 * 227 * Destroys the SME object. De-allocates system resources 228 * 229 * \param hSme - handle to the SME object 230 * \return None 231 * \sa sme_Create 232 */ 233 void sme_Destroy (TI_HANDLE hSme) 234 { 235 TSme *pSme = (TSme*)hSme; 236 237 /* destroy the scan result table */ 238 if (NULL != pSme->hSmeScanResultTable) 239 { 240 scanResultTable_Destroy (pSme->hSmeScanResultTable); 241 } 242 243 /* destroy the SME generic state machine */ 244 if (NULL != pSme->hSmeSm) 245 { 246 genSM_Unload (pSme->hSmeSm); 247 } 248 249 /* free the SME object */ 250 os_memoryFree (pSme->hOS, hSme, sizeof (TSme)); 251 } 252 253 /** 254 * \fn sme_Start 255 * \brief Starts SME operation 256 * 257 * Starts SME operation. Send probe request templates and send a start event to the SM. 258 * Only the DrvMain module could & is call that function !!! 259 * 260 * \param hSme - handle to the SME object 261 * \return None 262 * \sa sme_Stop 263 */ 264 void sme_Start (TI_HANDLE hSme) 265 { 266 TSme *pSme = (TSme*)hSme; 267 268 TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Start: called, bRadioOn = %d\n", pSme->bRadioOn); 269 270 pSme->bRunning = TI_TRUE; 271 272 /* 273 * call setDefaultProbeReqTemplate at sme_Start() due to the fact in order to set prob req template 274 * all moudules need to be set already 275 */ 276 setDefaultProbeReqTemplate (pSme->hSiteMgr); 277 278 /* if radio is on, start the SM */ 279 if (TI_TRUE == pSme->bRadioOn) 280 { 281 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_START, hSme); 282 } 283 } 284 285 /** 286 * \fn sme_Stop 287 * \brief Stops the driver (shuts-down the radio) 288 * 289 * Stops the driver (shuts-down the radio) 290 * 291 * \param hSme - handle to the SME object 292 * \param pCBFunc - callback function to be called when stop operation is doen 293 * \param hCBHanlde - handle to supply to the callback function 294 * \return None 295 * \sa sme_Start 296 */ 297 void sme_Stop (TI_HANDLE hSme) 298 { 299 TSme *pSme = (TSme*)hSme; 300 301 TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Stop called\n"); 302 303 pSme->bRunning = TI_FALSE; 304 305 /* mark that running flag is send a stop event to the SM */ 306 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_STOP, hSme); 307 } 308 309 /** 310 * \fn sme_Restart 311 * \brief Called due to a paramter value change in site mgr. Triggers a disconnect. 312 * 313 * Called due to a paramter value change in site mgr. Triggers a disconnect. 314 * 315 * \param hSme - handle to the SME object 316 * \param eReason - the reason for restarting the SME 317 * \return None 318 */ 319 void sme_Restart (TI_HANDLE hSme) 320 { 321 TSme *pSme = (TSme*)hSme; 322 323 TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Restart called.\n"); 324 325 pSme->uScanCount = 0; 326 327 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 328 } 329 330 /** 331 * \fn sme_SetParam 332 * \brief Set parameters values 333 * 334 * Set parameters values 335 * 336 * \note Note is indicated here 337 * \param hSme - handle to the SME object 338 * \param pParam - pointer to the param to set 339 * \return PARAM_NOT_SUPPORTED for an unrecognized parameter, TI_OK if successfull. 340 * \sa sme_GetParam 341 */ 342 TI_STATUS sme_SetParam (TI_HANDLE hSme, paramInfo_t *pParam) 343 { 344 TSme *pSme = (TSme*)hSme; 345 346 TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_SetParam: param type is 0x%x\n", pParam->paramType); 347 348 switch (pParam->paramType) 349 { 350 case SME_RADIO_ON_PARAM: 351 /* if new value is different than current one */ 352 if (pSme->bRadioOn != pParam->content.smeRadioOn) 353 { 354 /* set new radio on value and send an event to the state-machine accordingly */ 355 pSme->bRadioOn = pParam->content.smeRadioOn; 356 if (TI_TRUE == pSme->bRadioOn) 357 { 358 if(TI_TRUE == pSme->bRunning) 359 { 360 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_START, hSme); 361 } 362 } 363 else 364 { 365 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_STOP, hSme); 366 } 367 } 368 break; 369 370 case SME_DESIRED_SSID_PARAM: 371 372 if (pParam->content.smeDesiredSSID.len > MAX_SSID_LEN) 373 { 374 return PARAM_VALUE_NOT_VALID; /* SSID length is out of range */ 375 } 376 377 /* if new value is different than current one */ 378 if ((pSme->tSsid.len != pParam->content.smeDesiredSSID.len) || 379 (0 != os_memoryCompare (pSme->hOS, (TI_UINT8 *)&(pSme->tSsid.str[ 0 ]), 380 (TI_UINT8 *)&(pParam->content.smeDesiredSSID.str[ 0 ]), pSme->tSsid.len))) 381 { 382 /* set new desired SSID */ 383 os_memoryCopy (pSme->hOS, &(pSme->tSsid.str[ 0 ]), &(pParam->content.smeDesiredSSID.str[ 0 ]), pParam->content.smeDesiredSSID.len); 384 pSme->tSsid.len = pParam->content.smeDesiredSSID.len; 385 386 pSme->uScanCount = 0; 387 388 /* now send a disconnect event */ 389 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 390 } 391 break; 392 393 case SME_DESIRED_SSID_ACT_PARAM: 394 395 if (pParam->content.smeDesiredSSID.len > MAX_SSID_LEN) 396 { 397 return PARAM_VALUE_NOT_VALID; /* SSID length is out of range */ 398 } 399 400 pSme->bRadioOn = TI_TRUE; 401 402 /* if new value is different than current one */ 403 if ((pSme->tSsid.len != pParam->content.smeDesiredSSID.len) || 404 (0 != os_memoryCompare (pSme->hOS, (TI_UINT8 *)&(pSme->tSsid.str[ 0 ]), 405 (TI_UINT8 *)&(pParam->content.smeDesiredSSID.str[ 0 ]), pSme->tSsid.len))) 406 { 407 /* set new desired SSID */ 408 os_memoryCopy (pSme->hOS, &(pSme->tSsid.str[ 0 ]), &(pParam->content.smeDesiredSSID.str[ 0 ]), pParam->content.smeDesiredSSID.len); 409 pSme->tSsid.len = pParam->content.smeDesiredSSID.len; 410 } 411 /* also set SSID type and connect required flag */ 412 if (OS_802_11_SSID_JUNK (pSme->tSsid.str, pSme->tSsid.len)) 413 { 414 pSme->eSsidType = SSID_TYPE_INVALID; 415 pSme->bConnectRequired = TI_FALSE; 416 } 417 else if (0 == pSme->tSsid.len) 418 { 419 pSme->eSsidType = SSID_TYPE_ANY; 420 pSme->bConnectRequired = TI_TRUE; 421 } 422 else 423 { 424 pSme->eSsidType = SSID_TYPE_SPECIFIC; 425 pSme->bConnectRequired = TI_TRUE; 426 } 427 pSme->uScanCount = 0; 428 429 /* if junk SSID */ 430 if(TI_FALSE == pSme->bConnectRequired) 431 { 432 pSme->bConstantScan = TI_FALSE; 433 } 434 435 /* now send a disconnect event */ 436 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 437 break; 438 439 case SME_DESIRED_BSSID_PARAM: 440 /* if new value is different than current one */ 441 if (TI_FALSE == MAC_EQUAL (pSme->tBssid, pParam->content.smeDesiredBSSID)) 442 { 443 /* set new BSSID */ 444 MAC_COPY (pSme->tBssid, pParam->content.smeDesiredBSSID); 445 pSme->uScanCount = 0; 446 /* now send a disconnect event */ 447 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 448 } 449 break; 450 451 case SME_CONNECTION_MODE_PARAM: 452 /* if new value is different than current one */ 453 if (pSme->eConnectMode != pParam->content.smeConnectionMode) 454 { 455 /* set new connection mode */ 456 pSme->eConnectMode = pParam->content.smeConnectionMode; 457 pSme->uScanCount = 0; 458 if (CONNECT_MODE_AUTO == pSme->eConnectMode) 459 { 460 pSme->hScanResultTable = pSme->hSmeScanResultTable; 461 } 462 else if (CONNECT_MODE_MANUAL == pSme->eConnectMode) 463 { 464 pSme->hScanResultTable = pSme->hScanCncnScanResulTable; 465 } 466 /* now send a disconnect event */ 467 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 468 } 469 break; 470 471 case SME_DESIRED_BSS_TYPE_PARAM: 472 /* if new value is different than current one */ 473 if (pSme->eBssType != pParam->content.smeDesiredBSSType) 474 { 475 /* set new BSS type */ 476 pSme->eBssType = pParam->content.smeDesiredBSSType; 477 pSme->uScanCount = 0; 478 /* now send a disconnect event */ 479 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 480 } 481 break; 482 483 case SME_WSC_PB_MODE_PARAM: 484 485 if (pParam->content.siteMgrWSCMode.WSCMode != TIWLN_SIMPLE_CONFIG_OFF) 486 { 487 pSme->bConstantScan = TI_TRUE; 488 pSme->uScanCount = 0; 489 /* now send a disconnect event */ 490 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 491 } 492 else 493 { 494 pSme->bConstantScan = TI_FALSE; 495 } 496 break; 497 498 default: 499 TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_SetParam: unrecognized param type %d\n", pParam->paramType); 500 return PARAM_NOT_SUPPORTED; 501 /* break;*/ 502 } 503 504 return TI_OK; 505 } 506 507 /** 508 * \fn sme_GetParam 509 * \brief Retrieves a parameter from the SME 510 * 511 * Retrieves a parameter from the SME 512 * 513 * \param hSme - handle to the SME object 514 * \param pParam - pointer to the param to retrieve 515 * \return PARAM_NOT_SUPPORTED for an unrecognized parameter, TI_OK if successfull. 516 * \sa sme_SetParam 517 */ 518 TI_STATUS sme_GetParam (TI_HANDLE hSme, paramInfo_t *pParam) 519 { 520 TSme *pSme = (TSme*)hSme; 521 522 TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_GetParam: param type is 0x%x\n", pParam->paramType); 523 524 switch (pParam->paramType) 525 { 526 case SME_RADIO_ON_PARAM: 527 pParam->content.smeRadioOn = pSme->bRadioOn; 528 break; 529 530 case SME_DESIRED_SSID_ACT_PARAM: 531 pParam->content.smeDesiredSSID.len = pSme->tSsid.len; 532 os_memoryCopy (pSme->hOS, &(pParam->content.smeDesiredSSID.str[ 0 ]), 533 &(pSme->tSsid.str[ 0 ]), pSme->tSsid.len); 534 break; 535 536 case SME_DESIRED_BSSID_PARAM: 537 MAC_COPY (pParam->content.smeDesiredBSSID, pSme->tBssid); 538 break; 539 540 case SME_CONNECTION_MODE_PARAM: 541 pParam->content.smeConnectionMode = pSme->eConnectMode; 542 break; 543 544 case SME_DESIRED_BSS_TYPE_PARAM: 545 pParam->content.smeDesiredBSSType = pSme->eBssType; 546 break; 547 548 case SME_CONNECTION_STATUS_PARAM: 549 switch (genSM_GetCurrentState (pSme->hSmeSm)) 550 { 551 case SME_SM_STATE_IDLE: 552 pParam->content.smeSmConnectionStatus = eDot11RadioDisabled; 553 break; 554 case SME_SM_STATE_WAIT_CONNECT: 555 pParam->content.smeSmConnectionStatus = eDot11Disassociated; 556 break; 557 case SME_SM_STATE_SCANNING: 558 pParam->content.smeSmConnectionStatus = eDot11Scaning; 559 break; 560 case SME_SM_STATE_CONNECTING: 561 pParam->content.smeSmConnectionStatus = eDot11Connecting; 562 break; 563 case SME_SM_STATE_CONNECTED: 564 pParam->content.smeSmConnectionStatus = eDot11Associated; 565 break; 566 case SME_SM_STATE_DISCONNECTING: 567 pParam->content.smeSmConnectionStatus = eDot11Disassociated; 568 break; 569 } 570 break; 571 572 default: 573 TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_GetParam: unrecognized param type %d\n", pParam->paramType); 574 return PARAM_NOT_SUPPORTED; 575 /* break;*/ 576 } 577 578 return TI_OK; 579 } 580 581 /** 582 * \fn sme_ScanResultCB 583 * \brief Callback function from scan concentrator for results and scan complete indications 584 * 585 * Callback function from scan concentrator for results and scan complete indications 586 * 587 * \param hSme - handle to the SME object 588 * \param eStatus - the reason for calling the CB 589 * \param pFrameInfo - frame information (if the CB is called due to received frame) 590 * \param uSPSStatus - SPS attened channels (if the CB is called to inidcate an SPS scan complete) 591 * \return None 592 */ 593 void sme_ScanResultCB (TI_HANDLE hSme, EScanCncnResultStatus eStatus, 594 TScanFrameInfo* pFrameInfo, TI_UINT16 uSPSStatus) 595 { 596 TSme *pSme = (TSme*)hSme; 597 paramInfo_t param; 598 599 switch (eStatus) 600 { 601 /* a frame was received - update the scan result table */ 602 case SCAN_CRS_RECEIVED_FRAME: 603 TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received frame from BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); 604 605 /* 606 * in auto mode in order to find country IE only !!! 607 * filter frames according to desired SSID, in case we are also trying to find 608 * country IE in passive scan, to avoid a table overflow (in manual mode, the SME table must be equal to the app 609 * table, the app is responsible to decide which SSIDs to use for scan) 610 */ 611 if (CONNECT_MODE_AUTO == pSme->eConnectMode) 612 { 613 if (SSID_TYPE_SPECIFIC == pSme->eSsidType) 614 { 615 #ifndef XCC_MODULE_INCLUDED 616 if ((pSme->tSsid.len == pFrameInfo->parsedIEs->content.iePacket.pSsid->hdr[ 1 ]) && 617 (0 == os_memoryCompare (pSme->hOS, (TI_UINT8 *)&(pSme->tSsid.str[ 0 ]), 618 (TI_UINT8 *)&(pFrameInfo->parsedIEs->content.iePacket.pSsid->serviceSetId[ 0 ]), 619 pSme->tSsid.len))) 620 #endif 621 { 622 if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo)) 623 { 624 TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update specific entry for BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); 625 } 626 } 627 } 628 else 629 { 630 if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo)) 631 { 632 TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update entry for BSSID %02x:%02x:%02x:%02x:%02x:%02x because table is full\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); 633 } 634 } 635 } 636 else 637 /* manual mode */ 638 { 639 if (TI_OK != scanResultTable_UpdateEntry (pSme->hSmeScanResultTable, pFrameInfo->bssId, pFrameInfo)) 640 { 641 TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update application scan entry for BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); 642 } 643 } 644 break; 645 646 /* scan was completed successfully */ 647 case SCAN_CRS_SCAN_COMPLETE_OK: 648 /* an error occured, try selecting a site anyway */ 649 case SCAN_CRS_SCAN_ABORTED_FW_RESET: 650 case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY: 651 case SCAN_CRS_SCAN_FAILED: 652 case SCAN_CRS_TSF_ERROR: 653 TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received scan complete indication with status %d\n", eStatus); 654 655 /* stablizie the scan result table - delete its contenst if no results were recived during last scan */ 656 scanResultTable_SetStableState (pSme->hScanResultTable); 657 658 if (CONNECT_MODE_AUTO == pSme->eConnectMode) 659 { 660 661 /* try to select a site */ 662 pSme->pCandidate = sme_Select (hSme); 663 664 /* if no matching site was found */ 665 if (NULL == pSme->pCandidate) 666 { 667 /* for IBSS or any, if no entries where found, add the self site */ 668 if (pSme->eBssType == BSS_INFRASTRUCTURE) 669 { 670 TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: No candidate available, sending connect failure\n"); 671 672 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 673 break; 674 } 675 676 { 677 TI_UINT8 uDesiredChannel; 678 679 param.paramType = SITE_MGR_DESIRED_CHANNEL_PARAM; 680 siteMgr_getParam(pSme->hSiteMgr, ¶m); 681 uDesiredChannel = param.content.siteMgrDesiredChannel; 682 683 if (uDesiredChannel >= SITE_MGR_CHANNEL_A_MIN) 684 { 685 param.content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ; 686 } 687 else 688 { 689 param.content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ; 690 } 691 692 /* 693 update the regulatory domain with the selected band 694 */ 695 /* Check if the selected channel is valid according to regDomain */ 696 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; 697 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; 698 param.content.channelCapabilityReq.channelNum = uDesiredChannel; 699 700 regulatoryDomain_getParam (pSme->hRegDomain,¶m); 701 if (!param.content.channelCapabilityRet.channelValidity) 702 { 703 TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "IBSS SELECT FAILURE - No channel !!!\n\n"); 704 705 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 706 707 break; 708 } 709 710 pSme->pCandidate = (TSiteEntry *)addSelfSite(pSme->hSiteMgr); 711 712 if (pSme->pCandidate == NULL) 713 { 714 TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "IBSS SELECT FAILURE - could not open self site !!!\n\n"); 715 716 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 717 718 break; 719 } 720 721 #ifdef REPORT_LOG 722 TRACE6(pSme->hReport, REPORT_SEVERITY_CONSOLE,"%%%%%%%%%%%%%% SELF SELECT SUCCESS, bssid: %X-%X-%X-%X-%X-%X %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5]); 723 WLAN_OS_REPORT (("%%%%%%%%%%%%%% SELF SELECT SUCCESS, bssid: %02x.%02x.%02x.%02x.%02x.%02x %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5])); 724 #endif 725 } 726 } 727 728 /* a connection candidate is available, send a connect event */ 729 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme); 730 } 731 break; 732 733 /* 734 * scan was stopped according to SME request (should happen when moving to disconnecting from scanning), send a 735 * connect failure event to move out of disconnecting 736 */ 737 case SCAN_CRS_SCAN_STOPPED: 738 TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received scan stopped indication\n"); 739 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 740 break; 741 742 default: 743 TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: received unrecognized status %d\n", eStatus); 744 break; 745 } 746 } 747 748 /** 749 * \fn sme_MeansurementScanResult 750 * \brief Callback function from Meansurement for results 751 * 752 * Callback function from Meansurement for results used for scans wehen the SME is in Meansurement. 753 * 754 * \param hSme - handle to the SME object 755 * \param pFrameInfo - frame information (if the CB is called due to received frame) 756 * \return None 757 */ 758 void sme_MeansurementScanResult (TI_HANDLE hSme, EScanCncnResultStatus eStatus, TScanFrameInfo* pFrameInfo) 759 { 760 TSme *pSme = (TSme*)hSme; 761 762 switch (eStatus) 763 { 764 /* a frame was received - update the scan result table */ 765 case SCAN_CRS_RECEIVED_FRAME: 766 TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_MeansurementScanResult: received frame from BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); 767 768 if (TI_OK != scanResultTable_UpdateEntry (pSme->hSmeScanResultTable, pFrameInfo->bssId, pFrameInfo)) 769 { 770 TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_MeansurementScanResult: unable to update entry for BSSID %02x:%02x:%02x:%02x:%02x:%02x because table is full\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); 771 } 772 break; 773 774 /* scan was completed successfully */ 775 case SCAN_CRS_SCAN_COMPLETE_OK: 776 /* an error occured, try selecting a site anyway */ 777 case SCAN_CRS_SCAN_ABORTED_FW_RESET: 778 case SCAN_CRS_SCAN_STOPPED: 779 case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY: 780 case SCAN_CRS_SCAN_FAILED: 781 case SCAN_CRS_TSF_ERROR: 782 TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_MeansurementScanResult: received scan complete indication with status %d\n", eStatus); 783 784 /* stablizie the scan result table - delete its contenst if no results were recived during last scan */ 785 scanResultTable_SetStableState (pSme->hSmeScanResultTable); 786 break; 787 788 default: 789 TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_AppScanResult: received unrecognized status %d\n", eStatus); 790 break; 791 } 792 793 } 794 795 796 /** 797 * \fn Function declaration 798 * \brief Function brief description goes here 799 * 800 * Function detailed description goes here 801 * 802 * \note Note is indicated here 803 * \param Parameter name - parameter description 804 * \param 805 * \return Return code is detailed here 806 * \sa Reference to other relevant functions 807 */ 808 void sme_ReportConnStatus (TI_HANDLE hSme, mgmtStatus_e eStatusType, TI_UINT32 uStatusCode) 809 { 810 TSme *pSme = (TSme*)hSme; 811 812 TRACE2(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ReportConnStatus: statusType = %d, uStatusCode = %d\n", eStatusType, uStatusCode); 813 814 /* Act according to status */ 815 switch (eStatusType) 816 { 817 /* connection was successful */ 818 case STATUS_SUCCESSFUL: 819 pSme->bAuthSent = TI_TRUE; 820 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_SUCCESS, hSme); 821 break; 822 823 case STATUS_ASSOC_REJECT: 824 case STATUS_SECURITY_FAILURE: 825 case STATUS_AP_DEAUTHENTICATE: 826 case STATUS_AP_DISASSOCIATE: 827 case STATUS_ROAMING_TRIGGER: 828 case STATUS_AUTH_REJECT: 829 /* Indicate the authentication and/or association was sent to the AP */ 830 pSme->bAuthSent = TI_TRUE; 831 832 /* keep the disassociation status and code, for sending event to user-mode */ 833 pSme->tDisAssoc.eMgmtStatus = eStatusType; 834 pSme->tDisAssoc.uStatusCode = uStatusCode; 835 836 /* try to find the next connection candidate */ 837 pSme->pCandidate = sme_Select (hSme); 838 /* if the next connection candidate exists */ 839 if (NULL != pSme->pCandidate) 840 { 841 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme); 842 } 843 else 844 { 845 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 846 } 847 break; 848 849 /* Note that in case of unspecified status we won't update the status. This is done since this function could be called twice */ 850 /* for example: apConn called this function and than SME called conn_stop and this function is called again */ 851 /* we use this status at SME, if != 0 means that assoc frame sent */ 852 case STATUS_UNSPECIFIED: 853 pSme->bAuthSent = TI_TRUE; 854 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 855 break; 856 857 default: 858 TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ReportConnStatus: unknown statusType = %d\n", eStatusType); 859 break; 860 } 861 } 862 863 /** 864 * \fn sme_ReportApConnStatus 865 * \brief Used by AP connection (and Soft-gemini) modules to report connection status 866 * 867 * Used by AP connection (and Soft-gemini) modules to report connection status 868 * 869 * \param hSme - handle to the SME object 870 * \param eStatusType - connection status 871 * \param uStatus code - extended status information (if available) 872 * \return None 873 * \sa sme_ReportConnStatus 874 */ 875 void sme_ReportApConnStatus (TI_HANDLE hSme, mgmtStatus_e eStatusType, TI_UINT32 uStatusCode) 876 { 877 TSme *pSme = (TSme*)hSme; 878 879 TRACE2(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ReportApConnStatus: statusType = %d, uStatusCode = %d\n", eStatusType, uStatusCode); 880 881 /* Act according to status */ 882 switch (eStatusType) 883 { 884 885 /* SG re-select */ 886 case STATUS_SG_RESELECT: 887 pSme->bReselect = TI_TRUE; 888 pSme->bConnectRequired = TI_TRUE; 889 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 890 break; 891 892 /* shouldn't happen (not from AP conn) */ 893 case STATUS_SUCCESSFUL: 894 TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ReportApConnStatus: received STATUS_SUCCESSFUL\n"); 895 break; 896 897 case STATUS_UNSPECIFIED: 898 case STATUS_AUTH_REJECT: 899 case STATUS_ASSOC_REJECT: 900 case STATUS_SECURITY_FAILURE: 901 case STATUS_AP_DEAUTHENTICATE: 902 case STATUS_AP_DISASSOCIATE: 903 case STATUS_ROAMING_TRIGGER: 904 905 /* keep the disassociation status and code, for sending event to user-mode */ 906 pSme->tDisAssoc.eMgmtStatus = eStatusType; 907 pSme->tDisAssoc.uStatusCode = uStatusCode; 908 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); 909 break; 910 911 case STATUS_DISCONNECT_DURING_CONNECT: 912 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 913 break; 914 915 default: 916 TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ReportApConnStatus: received unrecognized status: %d\n", eStatusType); 917 918 } 919 } 920 921 /** 922 * \fn sme_ConnectScanReport 923 * \brief get the handler to the Scan Result Table used for connection to AP. 924 * 925 * \param hSme - handle to the SME object 926 * \param uStatus code - extended status information (if available) 927 * \return None 928 */ 929 void sme_ConnectScanReport (TI_HANDLE hSme, TI_HANDLE *hScanResultTable) 930 { 931 TSme *pSme = (TSme*)hSme; 932 933 *hScanResultTable = pSme->hScanResultTable; 934 } 935 936 /** 937 * \fn sme_MeasureScanReport 938 * \brief get the handler to the Sme Scan Result Table. 939 * 940 * \param hSme - handle to the SME object 941 * \param uStatus code - extended status information (if available) 942 * \return None 943 */ 944 void sme_MeasureScanReport (TI_HANDLE hSme, TI_HANDLE *hScanResultTable) 945 { 946 TSme *pSme = (TSme*)hSme; 947 948 *hScanResultTable = pSme->hSmeScanResultTable; 949 } 950 951 952 /** 953 * \fn SME_ConnectRequired 954 * \brief start connection sequence by set the flag ConnectRequired and issue DISCONNECT event. 955 * called by CommandDispatcher in OSE OS. 956 * 957 * \param hSme - handle to the SME object 958 * \return None 959 * \sa SME_Disconnect 960 */ 961 void SME_ConnectRequired (TI_HANDLE hSme) 962 { 963 TSme *pSme = (TSme*)hSme; 964 965 pSme->bRadioOn = TI_TRUE; 966 pSme->uScanCount = 0; 967 pSme->bConnectRequired = TI_TRUE; 968 969 /* now send a disconnect event */ 970 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 971 } 972 973 /** 974 * \fn SME_Disconnect 975 * \brief perform disconnect by clear the flag ConnectRequired and issue DISCONNECT event. 976 * 977 * \param hSme - handle to the SME object 978 * \return None 979 * \sa SME_ConnectRequired 980 */ 981 void SME_Disconnect (TI_HANDLE hSme) 982 { 983 TSme *pSme = (TSme*)hSme; 984 985 pSme->bConnectRequired = TI_FALSE; 986 /* turn off WSC PB mode */ 987 pSme->bConstantScan = TI_FALSE; 988 989 /* now send a disconnect event */ 990 sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_DISCONNECT, hSme); 991 } 992 993 void sme_SmEvent(TI_HANDLE hGenSm, TI_UINT32 uEvent, void* pData) 994 { 995 TSme *pSme = (TSme*)pData; 996 TGenSM *pGenSM = (TGenSM*)hGenSm; 997 998 TRACE2(pSme->hReport, REPORT_SEVERITY_INFORMATION, "sme_SmEvent: Current State = %d, sending event %d\n", (pGenSM->uCurrentState), (uEvent)); 999 genSM_Event(pGenSM, uEvent, pData); 1000 } 1001