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, ¶m);
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,¶m);
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