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