Home | History | Annotate | Download | only in Connection_Managment
      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, &param);
    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,&param);
    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