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