• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** \file ScanCncnDrvSM.c
2  *  \brief This file include the scan concentrator driver state machine module implementation
3  *  \author Ronen Kalish
4  *  \date 03-Jan-2005
5  */
6 /****************************************************************************
7 **+-----------------------------------------------------------------------+**
8 **|                                                                       |**
9 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
10 **| All rights reserved.                                                  |**
11 **|                                                                       |**
12 **| Redistribution and use in source and binary forms, with or without    |**
13 **| modification, are permitted provided that the following conditions    |**
14 **| are met:                                                              |**
15 **|                                                                       |**
16 **|  * Redistributions of source code must retain the above copyright     |**
17 **|    notice, this list of conditions and the following disclaimer.      |**
18 **|  * Redistributions in binary form must reproduce the above copyright  |**
19 **|    notice, this list of conditions and the following disclaimer in    |**
20 **|    the documentation and/or other materials provided with the         |**
21 **|    distribution.                                                      |**
22 **|  * Neither the name Texas Instruments nor the names of its            |**
23 **|    contributors may be used to endorse or promote products derived    |**
24 **|    from this software without specific prior written permission.      |**
25 **|                                                                       |**
26 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
27 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
28 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
29 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
30 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
31 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
32 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
33 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
34 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
35 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
36 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
37 **|                                                                       |**
38 **+-----------------------------------------------------------------------+**
39 ****************************************************************************/
40 
41 #include "ScanCncnDrvSM.h"
42 #include "MacServices_api.h"
43 #include "report.h"
44 #include "siteMgrApi.h"
45 #include "utils.h"
46 #include "regulatoryDomainApi.h"
47 #include "healthMonitor.h"
48 
49 
50 static TI_STATUS actionUnexpected( TI_HANDLE hScanCncn );
51 static TI_STATUS actionNop( TI_HANDLE hScanCncn );
52 
53 
54 /**
55  * \author Ronen Kalish\n
56  * \date 02-Jan-2005\n
57  * \brief Initialize the scan concentrator driver SM.
58  *
59  * Function Scope \e Public.\n
60  * \param hScanCncn - handle to the scan concentrator object.\n
61  * \return OK if successful, NOK otherwise.\n
62  */
scanConcentratorDrvSM_init(TI_HANDLE hScanCncn)63 TI_STATUS scanConcentratorDrvSM_init( TI_HANDLE hScanCncn )
64 {
65     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
66 
67     fsm_actionCell_t    smMatrix[ DRV_SCAN_NUM_OF_STATES ][ DRV_SCAN_NUM_OF_EVENTS ] =
68 	{
69 		/* next state and actions for IDLE state */
70 		{
71             {DRV_SCAN_STATE_SCR_REQUEST, scanConcentratorDrvSM_requestSCR},              /*"START_SCAN",*/
72 			{DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"SCR_PEND",  */
73 			{DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"SCR_REJECT",*/
74             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"PASSIVE_SCAN"*/
75             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"ACTIVE_SCAN"*/
76             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"ABORT_SCAN"*/
77             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"FW_RESET"*/
78             {DRV_SCAN_STATE_IDLE, actionNop},                                            /*"STOP_SCAN"*/
79             {DRV_SCAN_STATE_IDLE, actionUnexpected}                                      /*"SCAN_COMPLETE"*/
80 		},
81 
82 		/* next state and actions for SCR_REQUEST state */
83 		{
84             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"START_SCAN",*/
85 			{DRV_SCAN_STATE_SCR_WAIT, actionNop},                                        /*"SCR_PEND",  */
86 			{DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanRejected},                   /*"SCR_REJECT",*/
87             {DRV_SCAN_STATE_PASSIVE_SCANNING, scanConcentratorDrvSM_passiveScan},        /*"PASSIVE_SCAN"*/
88             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_activeScan},          /*"ACTIVE_SCAN"*/
89             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"ABORT_SCAN"*/
90             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"FW_RESET"*/
91             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"STOP_SCAN"*/
92             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected}                               /*"SCAN_COMPLETE"*/
93 		},
94 
95 		/* next state and actions for SCR_WAIT state */
96 		{
97             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected},                                 /*"START_SCAN",*/
98 			{DRV_SCAN_STATE_SCR_WAIT, actionNop},                                        /*"SCR_PEND",  */
99 			{DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanRejected},                   /*"SCR_REJECT",*/
100             {DRV_SCAN_STATE_PASSIVE_SCANNING, scanConcentratorDrvSM_passiveScan},        /*"PASSIVE_SCAN"*/
101             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_activeScan},          /*"ACTIVE_SCAN"*/
102             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected},                                 /*"ABORT_SCAN"*/
103             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected},                                 /*"FW_RESET"*/
104             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanRejected},                   /*"STOP_SCAN"*/
105             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected}                                  /*"SCAN_COMPLETE"*/
106 		},
107 
108         /* next state and actions for PASSIVE_SCANNING state */
109 		{
110             {DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"START_SCAN",*/
111 			{DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"SCR_PEND",  */
112 			{DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"SCR_REJECT",*/
113             {DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"PASSIVE_SCAN"*/
114             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_activeScan},          /*"ACTIVE_SCAN"*/
115             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"ABORT_SCAN"*/
116             {DRV_SCAN_STATE_PASSIVE_SCANNING, scanConcentratorDrvSM_recoveryDuringScan}, /*"FW_RESET"*/
117             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"STOP_SCAN"*/
118             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanComplete}                    /*"SCAN_COMPLETE"*/
119 		},
120 
121         /* next state and actions for ACTIVE_SCANNING state */
122 		{
123             {DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"START_SCAN",*/
124 			{DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"SCR_PEND",  */
125 			{DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"SCR_REJECT",*/
126             {DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"PASSIVE_SCAN"*/
127             {DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"ACTIVE_SCAN"*/
128             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"ABORT_SCAN"*/
129             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_recoveryDuringScan},  /*"FW_RESET"*/
130             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"STOP_SCAN"*/
131             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanComplete}                    /*"SCAN_COMPLETE"*/
132 
133 		},
134 
135         /* next state and actions for STOPPING state */
136 		{
137             {DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"START_SCAN",*/
138 			{DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"SCR_PEND",  */
139 			{DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"SCR_REJECT",*/
140             {DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"PASSIVE_SCAN"*/
141             {DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"ACTIVE_SCAN"*/
142             {DRV_SCAN_STATE_STOPPING, actionNop},                                        /*"ABORT_SCAN"*/
143             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_recoveryDuringScan},         /*"FW_RESET"*/
144             {DRV_SCAN_STATE_STOPPING, actionNop},                                        /*"STOP_SCAN"*/
145             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanComplete}                    /*"SCAN_COMPLETE"*/
146 		}
147     };
148 
149     /* initialize current state */
150     pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ] = DRV_SCAN_STATE_IDLE;
151 
152     /* configure the state machine */
153 	return fsm_Config( pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ], (fsm_Matrix_t)smMatrix,
154                        DRV_SCAN_NUM_OF_STATES, DRV_SCAN_NUM_OF_EVENTS,
155                        (fsm_eventActivation_t)scanConcentratorDrvSM_SMEvent, pScanConcentrator->hOS );
156 }
157 
158 
159 #ifdef REPORT_LOG
160 
161 /* state descriptions, for state machine logging */
162 static char stateDesc[ DRV_SCAN_NUM_OF_STATES ][ MAX_DESC_STRING_LEN ] =
163 {
164     "STATE_IDLE",
165     "STATE_SCR_REQUEST",
166     "STATE_SCR_WAIT",
167     "STATE_PASSIVE_SCANNING",
168     "STATE_ACTIVE_SCANNING",
169     "STATE_STOPPING"
170 };
171 
172 /* event descriptions, for state machine logging */
173 static char eventDesc[ DRV_SCAN_NUM_OF_EVENTS ][ MAX_DESC_STRING_LEN ] =
174 {
175     "EVENT_START_SCAN",
176     "EVENT_SCR_PEND",
177     "EVENT_SCR_REJECT",
178     "EVENT_PASSIVE_SCAN",
179     "EVENT_ACTIVE_SCAN",
180     "EVENT_ABORT_SCAN",
181     "EVENT_FW_RESET",
182     "EVENT_STOP_SCAN",
183     "EVENT_SCAN_COMPLETE"
184 };
185 
186 #endif
187 
188 /**
189  * \author Ronen Kalish\n
190  * \date 02-Jan-2005\n
191  * \brief Processes an event.
192  *
193  * Function Scope \e Public.\n
194  * \param hScanCncn - handle to the scan concentrator object.\n
195  * \param currentState - the current driver SM state.\n
196  * \param event - the event to handle.\n
197  * \return OK if successful, NOK otherwise.\n
198  */
scanConcentratorDrvSM_SMEvent(TI_HANDLE hScanCncn,scan_drvSMStates_e * currentState,scan_drvSMEvents_e event)199 TI_STATUS scanConcentratorDrvSM_SMEvent( TI_HANDLE hScanCncn, scan_drvSMStates_e* currentState,
200                                          scan_drvSMEvents_e event )
201 {
202     scanConcentrator_t *pScanConcentrator = (scanConcentrator_t *)hScanCncn;
203 	TI_STATUS status = OK;
204 	UINT8 nextState;
205 
206     /* obtain the next state */
207 	status = fsm_GetNextState( pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ], *(UINT8*)currentState,
208                                (UINT8)event, &nextState );
209 	if ( status != OK )
210 	{
211 		WLAN_REPORT_SM( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Failed getting driver scan next state.\n") );
212 		return NOK;
213 	}
214 
215     /* report the move */
216     WLAN_REPORT_SM( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
217                     ("DRIVER SCAN: <%s, %s> --> %s\n\n",
218                     stateDesc[*((UINT8*)currentState)],
219                     eventDesc[(UINT8)event],
220                     stateDesc[nextState]) );
221 
222     /* move */
223     return fsm_Event( pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ], (UINT8*)currentState, (UINT8)event, hScanCncn );
224 }
225 
226 /**
227  * \author Ronen Kalish\n
228  * \date 02-Jan-2005\n
229  * \brief SM action - handles a start scan event (by requesting the SCR)
230  *
231  * Function Scope \e Public.\n
232  * \param hScanCncn - handle to the scan concentrator object.\n
233  * \return OK if successful, NOK otherwise.\n
234  */
scanConcentratorDrvSM_requestSCR(TI_HANDLE hScanCncn)235 TI_STATUS scanConcentratorDrvSM_requestSCR( TI_HANDLE hScanCncn )
236 {
237     scr_clientRequestStatus_e scrReplyStatus;
238     scr_pendReason_e scrPendReason;
239 	scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
240 
241     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
242                              ("DRV SM: Requesting SCR.\n") );
243 
244     /* request the SCR as driver client, and act according to return status */
245     switch (  scrReplyStatus = scr_clientRequest( pScanConcentrator->hSCR, SCR_CID_DRIVER_FG_SCAN, &scrPendReason ) )
246     {
247     case SCR_CRS_PEND:
248         WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
249                                  ("DRV SM: SCR pending, pend reason: %d.\n", scrPendReason) );
250 
251         /* check the pending reason */
252         if ( SCR_PR_DIFFERENT_GROUP_RUNNING == scrPendReason )
253         {
254             /* send a reject event to the SM - would not scan if not in connecting mode! */
255             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_FAILED;
256             return scanConcentratorDrvSM_SMEvent( hScanCncn,
257                                                   (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
258                                                   DRV_SCAN_EVENT_SCR_REJECT );
259         }
260         else
261         {
262             /* send a pend event to the SM */
263             return scanConcentratorDrvSM_SMEvent( hScanCncn,
264                                                   (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
265                                                    DRV_SCAN_EVENT_SCR_PEND );
266         }
267  /*       break; - unreachable */
268 
269     case SCR_CRS_RUN:
270         /* send an event to the SM */
271         WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
272                                  ("DRV SM: SCR acquired.\n") );
273         return scanConcentratorDrvSM_SMEvent( hScanCncn,
274                                               (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
275                                               scanConcentrator_getNextDriverEvent( hScanCncn ) );
276 /*        break; - unreachable */
277 
278     default:
279         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
280                              ("DRV SM: SCR returned unrecognized status: %d.\n", scrReplyStatus) );
281 		pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_FAILED;
282         scanConcentratorDrvSM_SMEvent( hScanCncn,
283                                        (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
284                                        DRV_SCAN_EVENT_SCAN_COMPLETE );
285         return NOK;
286 /*        break; - unreachable */
287     }
288 
289  /*   return OK; - unreachable */
290 }
291 
292 /**
293  * \author Ronen Kalish\n
294  * \date 02-Jan-2005\n
295  * \brief SM action - handles a FW reset event (by calling the complete CB)
296  *
297  * Function Scope \e Public.\n
298  * \param hScanCncn - handle to the scan concentrator object.\n
299  * \return OK if successful, NOK otherwise.\n
300  */
scanConcentratorDrvSM_callCompleteCB(TI_HANDLE hScanCncn)301 TI_STATUS scanConcentratorDrvSM_callCompleteCB( TI_HANDLE hScanCncn )
302 {
303     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
304 
305     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
306                              ("DRV SM: calling complete CB.\n") );
307 
308     /* mark that no scan is currently running */
309     pScanConcentrator->currentRunningScanClient = SCAN_SCC_NO_CLIENT;
310 
311     /* notify scan complete to scan mngr */
312     if ( FALSE == pScanConcentrator->bInRequest )
313     {
314         pScanConcentrator->scanResultCB[ SCAN_SCC_DRIVER ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_DRIVER ],
315                                                         pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ],
316                                                         NULL, 0xffff );
317     }
318 
319     return OK;
320 }
321 
322 /**
323  * \author Ronen Kalish\n
324  * \date 02-Jan-2005\n
325  * \brief SM action - handles a passive scan event (by starting a passive scan)
326  *
327  * Function Scope \e Public.\n
328  * \param hScanCncn - handle to the scan concentrator object.\n
329  * \return OK if successful, NOK otherwise.\n
330  */
scanConcentratorDrvSM_passiveScan(TI_HANDLE hScanCncn)331 TI_STATUS scanConcentratorDrvSM_passiveScan( TI_HANDLE hScanCncn )
332 {
333     TI_STATUS status;
334     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
335     int i;
336 
337     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
338                              ("DRV SM: Sending passive scan command to scan SRV.\n") );
339 
340     /* mark that this scan is currently running */
341     pScanConcentrator->currentRunningScanClient = SCAN_SCC_DRIVER;
342 
343     /* if the requested scan type is not passive in the first place, change it to passive */
344     pScanConcentrator->drvScanRequestType = pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType;
345     if ( (SCAN_TYPE_NORMAL_ACTIVE == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType) ||
346          (SCAN_TYPE_TRIGGERED_ACTIVE == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType) )
347     {
348         pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType = SCAN_TYPE_NORMAL_PASSIVE;
349 
350         /* save requested SSID, and write broadcast SSID instead. This is done to find ANY beacon for .11d
351            and .11h, in case the desired SSID is not being broadcast in beacons */
352         os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->drvScanSsid),
353                        &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].desiredSsid), sizeof(ssid_t) );
354         pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].desiredSsid.len = 0;
355 
356         /* save max and min dwell time for all channels, and replace them with default values */
357         for ( i = 0; i < pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels; i++ )
358         {
359             pScanConcentrator->drvScanMaxDwellTime[ i ] =
360                 pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime;
361             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime =
362                 pScanConcentrator->initParams.passiveScanDwellTime;
363             pScanConcentrator->drvScanMinDwellTime[ i ] =
364                 pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime;
365             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime =
366                 pScanConcentrator->initParams.passiveScanDwellTime;
367 			if (pScanConcentrator->bUseSGParams)
368 			{
369 				/* increasing dwell time in case BT is active to compensate loss of dwelling time */
370 				pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime =
371 					(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime *
372 					(100 + pScanConcentrator->SGcompensationPercent)) / 100;
373 				pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime =
374 					(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime *
375 					(100 + pScanConcentrator->SGcompensationPercent)) / 100;
376 				WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
377                              ("SoftGemini compensation time for channel %d : min = %d, max = %d  .\n",
378 							 i,pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime,
379 							 pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime) );
380 
381 			}
382         }
383     }
384 
385     /* ask the reg domain which channels are allowed for the requested scan type */
386     scanConcentrator_verifyChannelsWithRegDomain( hScanCncn, &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]) );
387 
388     /* if no channels are available for scan, return negative result */
389     if ( 0 == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels )
390     {
391         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
392                              ("DRV SM: No cahnnels available for passive scan, quitting.\n") );
393         scanConcentratorDrvSM_handleScanError( hScanCncn );
394         return NOK;
395     }
396 
397     /* register for scan results with the MLME parser */
398     if ( OK != (status = mlmeParser_registerForBeaconAndProbeResp( pScanConcentrator->hMlme,
399                                                                    scanConcentrator_mlmeResultCB,
400                                                                    hScanCncn )) )
401     {
402         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
403                              ("DRV SM: MLME result registration failed.\n") );
404         scanConcentratorDrvSM_handleScanError( hScanCncn );
405         return NOK;
406     }
407 
408 	 /* stop built-in test timer, to avoid TX stuck due to heavy traffic and unknown scan result time originally at scanSrv*/
409 	healthMonitor_suspendPeriodicTest( pScanConcentrator->hHealthMonitor );
410 
411     /* call the scan SRV start scan */
412     if ( OK != (status = MacServices_scanSRV_scan( pScanConcentrator->hMacServices,
413                                               &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]),
414                                               FALSE,
415                                               FALSE,
416                                               FALSE,
417                                               POWER_SAVE_KEEP_CURRENT,
418                                               FALSE ,
419 											  NULL,NULL)) )
420     {
421         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
422                              ("DRV SM: scan SRV returned status %d, quitting driver passive scan.\n", status) );
423 
424         /* unregister at the MLME for scan result frames */
425         mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
426         scanConcentratorDrvSM_handleScanError( hScanCncn );
427         return NOK;
428     }
429 
430     return OK;
431 }
432 
433 /**
434  * \author Ronen Kalish\n
435  * \date 02-Jan-2005\n
436  * \brief SM action - handles an active scan event (by starting an active scan)
437  *
438  * Function Scope \e Public.\n
439  * \param hScanCncn - handle to the scan concentrator object.\n
440  * \return OK if successful, NOK otherwise.\n
441  */
scanConcentratorDrvSM_activeScan(TI_HANDLE hScanCncn)442 TI_STATUS scanConcentratorDrvSM_activeScan( TI_HANDLE hScanCncn )
443 {
444     TI_STATUS status;
445     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
446 
447     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
448                              ("DRV SM: Sending active scan command to scan SRV.\n") );
449 
450     /* mark that this scan is currently running */
451     pScanConcentrator->currentRunningScanClient = SCAN_SCC_DRIVER;
452 
453     /* ask the reg domain which channels are allowed for the requested scan type */
454     scanConcentrator_verifyChannelsWithRegDomain( hScanCncn, &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]) );
455 
456     /* if no channels are available for scan, return negative result */
457     if ( 0 == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels )
458     {
459         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
460                              ("DRV SM: No cahnnels available for active scan, quitting.\n") );
461         scanConcentratorDrvSM_handleScanError( hScanCncn );
462         return NOK;
463     }
464 
465 
466     /* register for scan results with the MLME parser */
467     if ( OK != mlmeParser_registerForBeaconAndProbeResp( pScanConcentrator->hMlme,
468                                                          scanConcentrator_mlmeResultCB,
469                                                          hScanCncn ) )
470     {
471         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
472                              ("DRV SM: MLME result registration failed.\n") );
473         scanConcentratorDrvSM_handleScanError( hScanCncn );
474         return NOK;
475     }
476 
477 	/* stop built-in test timer, to avoid TX stuck due to heavy traffic and unknown scan result time originally at scanSrv*/
478 	healthMonitor_suspendPeriodicTest( pScanConcentrator->hHealthMonitor );
479 
480     if ( OK != (status = MacServices_scanSRV_scan( pScanConcentrator->hMacServices,
481                                        &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]),
482                                        FALSE,
483                                        FALSE,
484                                        FALSE,
485                                        POWER_SAVE_KEEP_CURRENT,
486                                        FALSE ,
487 									   NULL,NULL)) )
488     {
489         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
490                              ("DRV SM: scan SRV returned status %d, quitting driver active scan.\n", status) );
491 	    /* unregister at the MLME for scan result frames */
492         mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
493         scanConcentratorDrvSM_handleScanError( hScanCncn );
494         return NOK;
495     }
496 
497     return OK;
498 }
499 
500 /**
501  * \author Ronen Kalish\n
502  * \date 02-Jan-2005\n
503  * \brief SM action - handles an abort scan or stop scan event (by stopping the actual scan)
504  *
505  * Function Scope \e Public.\n
506  * \param hScanCncn - handle to the scan concentrator object.\n
507  * \return OK if successful, NOK otherwise.\n
508  */
scanConcentratorDrvSM_abortScan(TI_HANDLE hScanCncn)509 TI_STATUS scanConcentratorDrvSM_abortScan( TI_HANDLE hScanCncn )
510 {
511     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
512 
513     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
514                              ("DRV SM: aborting scan.\n") );
515 
516     /* call the scan SRV stop scan (don't exit driver mode, as it wasn't entered for driver scan */
517     MacServices_scanSRV_stopScan( pScanConcentrator->hMacServices, FALSE , NULL , NULL );
518 
519     return OK;
520 }
521 
522 /**
523  * \author Ronen Kalish\n
524  * \date 10-July-2005\n
525  * \brief SM action - handles a recovery event (calls the scan SRV abort on FW reset and than finishes scan)
526  *
527  * Function Scope \e Public.\n
528  * \param hScanCncn - handle to the scan concentrator object.\n
529  * \return OK if successful, NOK otherwise.\n
530  */
scanConcentratorDrvSM_recoveryDuringScan(TI_HANDLE hScanCncn)531 TI_STATUS scanConcentratorDrvSM_recoveryDuringScan( TI_HANDLE hScanCncn )
532 {
533     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
534 
535     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
536                              ("DRV SM: Recovery occured!.\n") );
537 
538     /* reset the scan SRV */
539     MacServices_scanSRV_stopOnFWReset( pScanConcentrator->hMacServices );
540 
541     /* send a scan complete event to the SM */
542     return scanConcentratorDrvSM_SMEvent( hScanCncn,
543                                           (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
544                                           DRV_SCAN_EVENT_SCAN_COMPLETE );
545 }
546 
547 /**
548  * \author Ronen Kalish\n
549  * \date 02-Jan-2005\n
550  * \brief SM action - handles a scan complete event (by releasing the SCR and calling the scan complete CB)
551  *
552  * Function Scope \e Public.\n
553  * \param hScanCncn - handle to the scan concentrator object.\n
554  * \return OK if successful, NOK otherwise.\n
555  */
scanConcentratorDrvSM_scanComplete(TI_HANDLE hScanCncn)556 TI_STATUS scanConcentratorDrvSM_scanComplete( TI_HANDLE hScanCncn )
557 {
558     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
559 
560     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
561                              ("DRV SM: Scan is complete.\n") );
562 
563 	/* unregister at the MLME for scan result frames */
564     mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
565 
566     /* mark that this scan is no longer running */
567     pScanConcentrator->currentRunningScanClient = SCAN_SCC_NO_CLIENT;
568 
569     /* release the SCR */
570     scr_clientComplete( pScanConcentrator->hSCR, SCR_CID_DRIVER_FG_SCAN );
571 
572     /* notify the scan complete to the scan mngr */
573     if ( FALSE == pScanConcentrator->bInRequest )
574     {
575         pScanConcentrator->scanResultCB[ SCAN_SCC_DRIVER ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_DRIVER ],
576                                                             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ],
577                                                             NULL, 0xffff );
578     }
579 
580     return OK;
581 }
582 
583 /**
584  * \author Ronen Kalish\n
585  * \date 02-Jan-2005\n
586  * \brief SM action - handles a scan reject event (abort scan before scan actually started)\n
587  *
588  * Function Scope \e Public.\n
589  * \param hScanCncn - handle to the scan concentrator object.\n
590  * \return OK if successful, NOK otherwise.\n
591  */
scanConcentratorDrvSM_scanRejected(TI_HANDLE hScanCncn)592 TI_STATUS scanConcentratorDrvSM_scanRejected( TI_HANDLE hScanCncn )
593 {
594     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
595 
596     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
597                              ("DRV SM: Scan is Rejected.\n") );
598 
599     /* release the SCR */
600     scr_clientComplete( pScanConcentrator->hSCR, SCR_CID_DRIVER_FG_SCAN );
601 
602     /* notify the scan complete to the scan mngr */
603     if ( FALSE == pScanConcentrator->bInRequest )
604     {
605         pScanConcentrator->scanResultCB[ SCAN_SCC_DRIVER ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_DRIVER ],
606                                                             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ],
607                                                             NULL, 0xffff );
608     }
609 
610     return OK;
611 }
612 
613 /**
614  * \author Ronen Kalish\n
615  * \date 11-Jan-2005\n
616  * \brief Handles an unexpected event.\n
617  *
618  * Function Scope \e Private.\n
619  * \param hScanCncn - handle to the scan concentrator object.\n
620  * \return always OK.\n
621  */
actionUnexpected(TI_HANDLE hScanCncn)622 TI_STATUS actionUnexpected( TI_HANDLE hScanCncn )
623 {
624     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
625 
626     WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Driver scan state machine error, unexpected Event, state=%d\n\n",
627 																	  pScanConcentrator->clientSMState[SCAN_SCC_DRIVER] ) );
628 
629     return OK;
630 }
631 
632 /**
633  * \author Ronen Kalish\n
634  * \date 10-Jan-2005\n
635  * \brief Handles an event that doesn't require any action.\n
636  *
637  * Function Scope \e Private.\n
638  * \param hScanCncn - handle to the scan concentrator object.\n
639  * \return always OK.\n
640  */
actionNop(TI_HANDLE hScanCncn)641 TI_STATUS actionNop( TI_HANDLE hScanCncn )
642 {
643     return OK;
644 }
645 
646 /**
647  * \author Ronen Kalish\n
648  * \date 09-Jan-2005\n
649  * \brief Determines the next event to send to the driver SM (when a scan can be run)\n
650  *
651  * Function Scope \e Private.\n
652  * \param hScanCncn - handle to the scan concentrator object.\n
653  * \return the next event to use with the driver SM.\n
654  */
scanConcentrator_getNextDriverEvent(TI_HANDLE hScanCncn)655 scan_drvSMEvents_e scanConcentrator_getNextDriverEvent( TI_HANDLE hScanCncn )
656 {
657     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
658     paramInfo_t         param;
659     BOOL                is_801_11d_enabled, is_801_11h_enabled;
660     int					i;
661 
662     /* getting regulatory Domain status - is 802.11d enabled ? */
663     param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM;
664     regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain,&param );
665     is_801_11d_enabled = param.content.regulatoryDomainEnabled;
666 
667     param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
668     regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain,&param );
669 	is_801_11h_enabled = param.content.spectrumManagementEnabled;
670 
671     /* The next event (or rather, scan type) is determined according to the driver SM state.
672        The order is passive-active, when either the active or passive scan can be eliminated (but the order is kept).
673      */
674     switch (pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ])
675     {
676     /* active scan already performed, send a scan complete event */
677     case DRV_SCAN_STATE_ACTIVE_SCANNING:
678     /* Stop or abort is in progress, also send a scan complete event */
679     case DRV_SCAN_STATE_STOPPING:
680         return DRV_SCAN_EVENT_SCAN_COMPLETE;
681 /*        break; - unreachable */
682 
683     /* passive scan already performed, check if active scan is needed. */
684     case DRV_SCAN_STATE_PASSIVE_SCANNING:
685         /* first, restore the user requested scan type, */
686         pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType = pScanConcentrator->drvScanRequestType;
687         /* the user desired SSID */
688         os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].desiredSsid),
689                        &(pScanConcentrator->drvScanSsid), sizeof(ssid_t) );
690         /* and dwell times for all channels */
691         for ( i = 0; i < pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels; i++ )
692         {
693             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime =
694                 pScanConcentrator->drvScanMaxDwellTime[ i ];
695             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime =
696                 pScanConcentrator->drvScanMinDwellTime[ i ];
697         }
698 
699         /* send scan complete event if:
700            1. The requested scan type is passive
701            2. .11d is enabled and no country IE is available
702          */
703 
704 		/* Get country code status */
705 		param.paramType			 = REGULATORY_DOMAIN_IS_COUNTRY_FOUND;
706 		param.content.eRadioBand = pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band;
707 		regulatoryDomain_getParam(pScanConcentrator->hRegulatoryDomain,&param);
708 
709         if ( (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
710              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
711              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_SPS) ||
712              ((TRUE == is_801_11d_enabled) &&
713               ( !param.content.bIsCountryFound )) )
714         {
715             return DRV_SCAN_EVENT_SCAN_COMPLETE;
716         }
717         /* otherwise, send active scan event */
718         else
719         {
720             /* Very ugly - but nowhere better to do it...
721                If we continue to active scan after passive scan, we are already registered
722                in the MLME parser. We MUST unregister here, or else the registration at
723                the active scan call will fail */
724             mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
725             return DRV_SCAN_EVENT_ACTIVE_SCAN;
726         }
727 /*        break; - unreachable */
728 
729     /* no scan already performed, any scan can be issued */
730     case DRV_SCAN_STATE_SCR_WAIT:
731     case DRV_SCAN_STATE_SCR_REQUEST:
732         /* do a passive scan if:
733            1. it was requested
734            2. .11d is enabled and country is unknown
735            3. .11h is enabled and the scan is on A band (always perform passive before active, to validate channels)
736          */
737 
738 		/* Get country code status */
739 		param.paramType			 = REGULATORY_DOMAIN_IS_COUNTRY_FOUND;
740 		param.content.eRadioBand = pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band ;
741 		regulatoryDomain_getParam(pScanConcentrator->hRegulatoryDomain,&param);
742 
743         if ( (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
744              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
745              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_SPS) ||
746              ((TRUE == is_801_11d_enabled) &&
747               (!param.content.bIsCountryFound)) ||
748              ((TRUE == is_801_11h_enabled) &&
749               (RADIO_BAND_5_0_GHZ == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band)) )
750         {
751             return DRV_SCAN_EVENT_PASSIVE_SCAN;
752         }
753         /* else, do an active scan if
754          */
755         else
756         {
757             return DRV_SCAN_EVENT_ACTIVE_SCAN;
758         }
759 /*        break; - unreachable */
760 
761     default:
762         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
763                              ("DRV SM: State %d is invalid to obtain next event", pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]) );
764         break;
765     }
766 
767     return DRV_SCAN_EVENT_SCAN_COMPLETE;
768 }
769 
770 /**
771  * \author Ronen Kalish\n
772  * \date 07-Feb-2005\n
773  * \brief Handles an error during scan operation
774  *
775  * Function Scope \e Private.\n
776  * \param hScanCncn - handle to the scan concentrator object.\n
777  */
scanConcentratorDrvSM_handleScanError(TI_HANDLE hScanCncn)778 void scanConcentratorDrvSM_handleScanError( TI_HANDLE hScanCncn )
779 {
780     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
781 
782     /* mark the return status */
783     pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_FAILED;
784 
785     /* send a scan complete event */
786     scanConcentratorDrvSM_SMEvent( hScanCncn,
787                                    (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
788                                    DRV_SCAN_EVENT_SCAN_COMPLETE );
789 }
790