• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
sme_Create(TI_HANDLE hOS)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  */
sme_Init(TStadHandlesList * pStadHandles)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  */
sme_SetDefaults(TI_HANDLE hSme,TSmeModifiedInitParams * pModifiedInitParams,TSmeInitParams * pInitParams)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  */
sme_SetScanResultTable(TI_HANDLE hSme,TI_HANDLE hScanResultTable)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  */
sme_Destroy(TI_HANDLE hSme)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  */
sme_Start(TI_HANDLE hSme)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  */
sme_Stop(TI_HANDLE hSme)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  */
sme_Restart(TI_HANDLE hSme)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  */
sme_SetParam(TI_HANDLE hSme,paramInfo_t * pParam)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  */
sme_GetParam(TI_HANDLE hSme,paramInfo_t * pParam)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  */
sme_ScanResultCB(TI_HANDLE hSme,EScanCncnResultStatus eStatus,TScanFrameInfo * pFrameInfo,TI_UINT16 uSPSStatus)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  */
sme_MeansurementScanResult(TI_HANDLE hSme,EScanCncnResultStatus eStatus,TScanFrameInfo * pFrameInfo)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  */
sme_ReportConnStatus(TI_HANDLE hSme,mgmtStatus_e eStatusType,TI_UINT32 uStatusCode)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  */
sme_ReportApConnStatus(TI_HANDLE hSme,mgmtStatus_e eStatusType,TI_UINT32 uStatusCode)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  */
sme_ConnectScanReport(TI_HANDLE hSme,TI_HANDLE * hScanResultTable)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  */
sme_MeasureScanReport(TI_HANDLE hSme,TI_HANDLE * hScanResultTable)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  */
SME_ConnectRequired(TI_HANDLE hSme)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  */
SME_Disconnect(TI_HANDLE hSme)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 
sme_SmEvent(TI_HANDLE hGenSm,TI_UINT32 uEvent,void * pData)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