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