• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ScanCncnSm.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  ScanCncnSm.c
35  *  \brief Scan concentrator state machine implementation
36  *
37  *  \see   ScanCncnSm.h, ScanCncnSmSpecific.c
38  */
39 
40 
41 #define __FILE_ID__  FILE_ID_79
42 #include "osTIType.h"
43 #include "GenSM.h"
44 #include "ScanCncnSm.h"
45 #include "report.h"
46 
47 /* state machine action functions */
48 static void scanCncnSm_RequestScr       (TI_HANDLE hScanCncnClient);
49 static void scanCncnSm_StartScan        (TI_HANDLE hScanCncnClient);
50 static void scanCncnSm_StopScan         (TI_HANDLE hScanCncnClient);
51 static void scanCncnSm_ScanComplete     (TI_HANDLE hScanCncnClient);
52 static void scanCncnSm_Nop              (TI_HANDLE hScanCncnClient);
53 static void scanCncnSm_ActionUnexpected (TI_HANDLE hScanCncnClient);
54 static void scanCncnSm_RejectScan       (TI_HANDLE hScanCncnClient);
55 static void scanCncnSm_Recovery         (TI_HANDLE hScanCncnClient);
56 
57 
58 static TGenSM_actionCell tSmMatrix[ SCAN_CNCN_SM_NUMBER_OF_STATES ][ SCAN_CNCN_SM_NUMBER_OF_EVENTS ] =
59     {
60         { /* SCAN_CNCN_SM_STATE_IDLE */
61             { SCAN_CNCN_SM_STATE_SCR_WAIT, scanCncnSm_RequestScr },         /* SCAN_CNCN_SM_EVENT_START */
62             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ActionUnexpected },       /* SCAN_CNCN_SM_EVENT_RUN */
63             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ActionUnexpected },       /* SCAN_CNCN_SM_EVENT_SCAN_COMPLETE */
64             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ActionUnexpected },       /* SCAN_CNCN_SM_EVENT_STOP */
65             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ActionUnexpected },       /* SCAN_CNCN_SM_EVENT_ABORT */
66             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ActionUnexpected },       /* SCAN_CNCN_SM_EVENT_RECOVERY */
67             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ActionUnexpected }        /* SCAN_CNCN_SM_EVENT_REJECT */
68         },
69         { /* SCAN_CNCN_SM_STATE_SCR_WAIT */
70             { SCAN_CNCN_SM_STATE_SCR_WAIT, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_START */
71             { SCAN_CNCN_SM_STATE_SCANNING, scanCncnSm_StartScan },          /* SCAN_CNCN_SM_EVENT_RUN */
72             { SCAN_CNCN_SM_STATE_SCR_WAIT, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_SCAN_COMPLETE */
73             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_RejectScan },             /* SCAN_CNCN_SM_EVENT_STOP */
74             { SCAN_CNCN_SM_STATE_SCR_WAIT, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_ABORT */
75             { SCAN_CNCN_SM_STATE_SCR_WAIT, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_RECOVERY */
76             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_RejectScan }              /* SCAN_CNCN_SM_EVENT_REJECT */
77         },
78         { /* SCAN_CNCN_SM_STATE_SCANNING */
79             { SCAN_CNCN_SM_STATE_SCANNING, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_START */
80             { SCAN_CNCN_SM_STATE_SCANNING, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_RUN */
81             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ScanComplete },           /* SCAN_CNCN_SM_EVENT_SCAN_COMPLETE */
82             { SCAN_CNCN_SM_STATE_STOPPING, scanCncnSm_StopScan },           /* SCAN_CNCN_SM_EVENT_STOP */
83             { SCAN_CNCN_SM_STATE_STOPPING, scanCncnSm_StopScan },           /* SCAN_CNCN_SM_EVENT_ABORT */
84             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_Recovery },               /* SCAN_CNCN_SM_EVENT_RECOVERY */
85             { SCAN_CNCN_SM_STATE_SCANNING, scanCncnSm_ActionUnexpected }    /* SCAN_CNCN_SM_EVENT_REJECT */
86         },
87         { /* SCAN_CNCN_SM_STATE_STOPPING */
88             { SCAN_CNCN_SM_STATE_STOPPING, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_START */
89             { SCAN_CNCN_SM_STATE_STOPPING, scanCncnSm_ActionUnexpected },   /* SCAN_CNCN_SM_EVENT_RUN */
90             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_ScanComplete },           /* SCAN_CNCN_SM_EVENT_SCAN_COMPLETE */
91             { SCAN_CNCN_SM_STATE_STOPPING, scanCncnSm_Nop },                /* SCAN_CNCN_SM_EVENT_STOP */
92             { SCAN_CNCN_SM_STATE_STOPPING, scanCncnSm_Nop },                /* SCAN_CNCN_SM_EVENT_ABORT */
93             { SCAN_CNCN_SM_STATE_IDLE, scanCncnSm_Recovery },               /* SCAN_CNCN_SM_EVENT_RECOVERY */
94             { SCAN_CNCN_SM_STATE_STOPPING, scanCncnSm_ActionUnexpected }    /* SCAN_CNCN_SM_EVENT_REJECT */
95         }
96     };
97 
98 static TI_INT8*  uStateDescription[] =
99     {
100         "IDLE",
101         "SCR_WAIT",
102         "SCANNING",
103         "STOPPING"
104     };
105 
106 static TI_INT8*  uEventDescription[] =
107     {
108         "START",
109         "RUN",
110         "SCAN_COMPLETE",
111         "STOP",
112         "ABORT",
113         "RECOVERY",
114         "REJECT",
115     };
116 
117 /**
118  * \fn     scanCncnSm_Create
119  * \brief  Cerates a scan concentrator client object
120  *
121  * Cerates a scan concentrator client - allocates object and create a state-machine instance
122  *
123  * \param  hOS - handle to the OS object
124  * \return Handle to the new scan concentrator client object
125  * \sa     scanCncnSm_Init, scanCncnSm_Destroy
126  */
scanCncnSm_Create(TI_HANDLE hOS)127 TI_HANDLE scanCncnSm_Create (TI_HANDLE hOS)
128 {
129     TScanCncnClient *pScanCncnClient;
130 
131     /* allocate space for the scan concentartor client object */
132     pScanCncnClient = os_memoryAlloc (hOS, sizeof (TScanCncnClient));
133     if (NULL == pScanCncnClient)
134     {
135         WLAN_OS_REPORT (("scanCncnSm_Cretae: not enough space for scan concentrator client object\n"));
136         return NULL;
137     }
138 
139     /* store the OS object handle */
140     pScanCncnClient->hOS = hOS;
141 
142     /* allocate the state machine object */
143     pScanCncnClient->hGenSM = genSM_Create (hOS);
144     if (NULL == pScanCncnClient->hGenSM)
145     {
146         WLAN_OS_REPORT (("scanCncnSm_Cretae: not enough space for scan concentrator client state-machine\n"));
147         return NULL;
148     }
149 
150     /* return the new object */
151     return (TI_HANDLE)pScanCncnClient;
152 }
153 
154 /**
155  * \fn     scanCncnSm_Init
156  * \brief  Initialize a scan concentartor client object
157  *
158  * Initialize a scan concentartor client object - store handles and specific SM functions
159  *
160  * \note   Some of the values (e.g. scan result CB( are initialized from the main scan concentartor object)
161  * \param  hScanCncnClient - handle to the scan concnentrator client object
162  * \param  hReport - handle to the report object
163  * \param  hTWD - handle to the TWD object
164  * \param  hSCR - handle to the SCR object
165  * \param  hApConn - handle to the AP connection object
166  * \param  hMlme - handle to the MLME object
167  * \param  fScrRequest - SM specific SCR request finction
168  * \param  fScrRelease - SM specific SCR release finction
169  * \param  fStartScan - SM specific scan start finction
170  * \param  fStopScan - SM specific scan stop finction
171  * \param  fRecovery - SM specific recovery handling function
172  * \param  pScanSmName - state machine name
173  * \return None
174  * \sa     scanCncnSm_Cretae
175  */
scanCncnSm_Init(TI_HANDLE hScanCncnClient,TI_HANDLE hReport,TI_HANDLE hTWD,TI_HANDLE hSCR,TI_HANDLE hApConn,TI_HANDLE hMlme,TI_HANDLE hScanCncn,TScanPrivateSMFunction fScrRequest,TScanPrivateSMFunction fScrRelease,TScanPrivateSMFunction fStartScan,TScanPrivateSMFunction fStopScan,TScanPrivateSMFunction fRecovery,TI_INT8 * pScanSmName)176 void scanCncnSm_Init (TI_HANDLE hScanCncnClient, TI_HANDLE hReport, TI_HANDLE hTWD, TI_HANDLE hSCR,
177                       TI_HANDLE hApConn, TI_HANDLE hMlme, TI_HANDLE hScanCncn, TScanPrivateSMFunction fScrRequest,
178                       TScanPrivateSMFunction fScrRelease, TScanPrivateSMFunction fStartScan,
179                       TScanPrivateSMFunction fStopScan, TScanPrivateSMFunction fRecovery, TI_INT8* pScanSmName)
180 {
181     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
182 
183     /* store handles */
184     pScanCncnClient->hReport = hReport;
185     pScanCncnClient->hTWD = hTWD;
186     pScanCncnClient->hSCR = hSCR;
187     pScanCncnClient->hApConn = hApConn;
188     pScanCncnClient->hMlme = hMlme;
189     pScanCncnClient->hScanCncn = hScanCncn;
190 
191     /* store private functions */
192     pScanCncnClient->fScrRequest = fScrRequest;
193     pScanCncnClient->fScrRelease = fScrRelease;
194     pScanCncnClient->fStartScan = fStartScan;
195     pScanCncnClient->fStopScan = fStopScan;
196     pScanCncnClient->fRecovery = fRecovery;
197 
198     /* store SM name */
199     pScanCncnClient->pScanSmName = pScanSmName;
200 
201     /* initialize the state-machine */
202     genSM_Init (pScanCncnClient->hGenSM, hReport);
203     genSM_SetDefaults (pScanCncnClient->hGenSM, SCAN_CNCN_SM_NUMBER_OF_STATES, SCAN_CNCN_SM_NUMBER_OF_EVENTS,
204                        (TGenSM_matrix)tSmMatrix, SCAN_CNCN_SM_STATE_IDLE, pScanCncnClient->pScanSmName, uStateDescription,
205                        uEventDescription, __FILE_ID__);
206 }
207 
208 /**
209  * \fn     scanCncnSm_Destroy
210  * \brief  Destroys a scan concentartor client object
211  *
212  * Destroys a scan concentartor client object. destroys the state-machine object and
213  * de-allcoates system resources
214  *
215  * \param  hScanCncnClient - handle to the scan concnentrator client object
216  * \return None
217  * \sa     scanCncnSm_Cretae
218  */
scanCncnSm_Destroy(TI_HANDLE hScanCncnClient)219 void scanCncnSm_Destroy (TI_HANDLE hScanCncnClient)
220 {
221     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
222 
223     /* free the state-machine */
224     genSM_Unload (pScanCncnClient->hGenSM);
225 
226     /* Free object storage space */
227     os_memoryFree (pScanCncnClient->hOS, hScanCncnClient, sizeof (TScanCncnClient));
228 }
229 
230 /**
231  * \fn     scanCncnSm_RequestScr
232  * \brief  Scan concentartor SM action function for SCR request
233  *
234  * Calls the Sm specific SCR request function
235  *
236  * \param  hScanCncnClient - Handle to the scan concentrator client object
237  * \return None
238  */
scanCncnSm_RequestScr(TI_HANDLE hScanCncnClient)239 void scanCncnSm_RequestScr (TI_HANDLE hScanCncnClient)
240 {
241     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
242 
243     TRACE0(pScanCncnClient->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnSm_RequestScr: SM  requesting SCR\n");
244 
245     /*
246      * just call the specific SCR request function, it will send an event if necessary
247      * according to SCR return code by itself
248      */
249     pScanCncnClient->fScrRequest (hScanCncnClient);
250 }
251 
252 /**
253  * \fn     scanCncnSm_StartScan
254  * \brief  Scan concentrator SM action function for starting scan
255  *
256  * Register for MLME CB and call the SM specific scan start function
257  *
258  * \param  hScanCncnClient - Handle to the scan concentrator client object
259  * \return None
260  */
scanCncnSm_StartScan(TI_HANDLE hScanCncnClient)261 void scanCncnSm_StartScan (TI_HANDLE hScanCncnClient)
262 {
263     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
264 
265     TRACE0(pScanCncnClient->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnSm_StartScan: SM  attempting to start scan.\n");
266 
267     /* set scan result counter and flag */
268     pScanCncnClient->uResultCounter = 0;
269     pScanCncnClient->uResultExpectedNumber = 0;
270     pScanCncnClient->bScanCompletePending = TI_FALSE;
271 
272     /* call the specific start scan command. It will handle errors by itself */
273     pScanCncnClient->fStartScan (hScanCncnClient);
274 }
275 
276 /**
277  * \fn     scanCncnSm_StopScan
278  * \brief  Scan concentrator SM action function for stoping scan by outside request
279  *
280  * Calls the SM specific stop scan function
281  *
282  * \param  hScanCncnClient - Handle to the scan concentrator client object
283  * \return None
284  */
scanCncnSm_StopScan(TI_HANDLE hScanCncnClient)285 void scanCncnSm_StopScan (TI_HANDLE hScanCncnClient)
286 {
287     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
288 
289     TRACE0(pScanCncnClient->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnSm_StopScan: SM  is attempting to stop scan\n");
290 
291     /* call the scan SRV stop scan */
292     pScanCncnClient->fStopScan (hScanCncnClient);
293 }
294 
295 /**
296  * \fn     scanCncnSm_ScanComplete
297  * \brief  Scan concentrator SM action function for scan complete
298  *
299  * Unregister MLME, release SCR and call client scan complete CB, if not running within a request context
300  *
301  * \param  hScanCncnClient - Handle to the scan concentrator client object
302  * \return None
303  */
scanCncnSm_ScanComplete(TI_HANDLE hScanCncnClient)304 void scanCncnSm_ScanComplete (TI_HANDLE hScanCncnClient)
305 {
306     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
307 
308     TRACE0(pScanCncnClient->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnSm_ScanComplete: SM  received scan complete event\n");
309 
310     /* release the SCR */
311     pScanCncnClient->fScrRelease (hScanCncnClient);
312 
313     /* Call the client scan complete callback */
314     if (TI_FALSE == pScanCncnClient->bInRequest)
315     {
316         pScanCncnClient->tScanResultCB (pScanCncnClient->hScanResultCBObj,
317                                         pScanCncnClient->eScanResult, NULL, pScanCncnClient->uSPSScanResult);
318     }
319 }
320 
321 /**
322  * \fn     scanCncnSm_Nop
323  * \brief  Scan concentrator SM action function for no operation
324  *
325  * Used when no operation is required not due to an error
326  *
327  * \param  hScanCncnClient - Handle to the scan concentrator client object
328  * \return None
329  */
scanCncnSm_Nop(TI_HANDLE hScanCncnClient)330 void scanCncnSm_Nop (TI_HANDLE hScanCncnClient)
331 {
332 }
333 
334 /**
335  * \fn     ScanCncnSm_ActionUnexpected
336  * \brief  Scan concentrator SM action function for unexpected events
337  *
338  * Print an error message
339  *
340  * \param  hScanCncnClient - Handle to the scan concentrator client object
341  * \return None
342  */
scanCncnSm_ActionUnexpected(TI_HANDLE hScanCncnClient)343 void scanCncnSm_ActionUnexpected (TI_HANDLE hScanCncnClient)
344 {
345     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
346 
347     TRACE0(pScanCncnClient->hReport, REPORT_SEVERITY_ERROR , "ScanCncnSm_ActionUnexpected: Unexpected event for current state\n");
348 
349     /* mark the scan status as failed */
350     pScanCncnClient->eScanResult = SCAN_CRS_SCAN_FAILED;
351 }
352 
353 /**
354  * \fn     scanCncnSm_RejectScan
355  * \brief  Scan concentrator SM action function for rejecting a scan by the SCR
356  *
357  * Releases the SCR and calls the client scan complete CB, if not running within a request context
358  *
359  * \param  hScanCncnClient - Handle to the scan concentrator client object
360  * \return None
361  */
scanCncnSm_RejectScan(TI_HANDLE hScanCncnClient)362 void scanCncnSm_RejectScan (TI_HANDLE hScanCncnClient)
363 {
364     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
365 
366     TRACE0(pScanCncnClient->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnSm_RejectScan: SM  received reject event\n");
367 
368     /* release the SCR */
369     pScanCncnClient->fScrRelease (hScanCncnClient);
370 
371     /* Call the client scan complete CB */
372     if (TI_FALSE == pScanCncnClient->bInRequest)
373     {
374         pScanCncnClient->tScanResultCB (pScanCncnClient->hScanResultCBObj, pScanCncnClient->eScanResult,
375                                         NULL, pScanCncnClient->uSPSScanResult);
376     }
377 }
378 
379 /**
380  * \fn     scanCncnSm_Recovery
381  * \brief  Scan concentrator SM action function for handling recovery during scan
382  *
383  * Calls the SM specific recovery handling function and send a scan complete event. Used to stop timer
384  * on one-shot scans
385  *
386  * \param  hScanCncnClient - Handle to the scan concentrator client object
387  * \return None
388  */
scanCncnSm_Recovery(TI_HANDLE hScanCncnClient)389 void scanCncnSm_Recovery (TI_HANDLE hScanCncnClient)
390 {
391     TScanCncnClient *pScanCncnClient = (TScanCncnClient*)hScanCncnClient;
392 
393     TRACE0(pScanCncnClient->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnSm_Recovery: SM  received reject event\n");
394 
395     /* Call the recovery specific function */
396     pScanCncnClient->fRecovery (hScanCncnClient);
397 
398     /* Call the client scan complete callback */
399     if (TI_FALSE == pScanCncnClient->bInRequest)
400     {
401         pScanCncnClient->tScanResultCB (pScanCncnClient->hScanResultCBObj,
402                                         pScanCncnClient->eScanResult, NULL, pScanCncnClient->uSPSScanResult);
403     }
404 }
405 
406