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