1 /*
2 * scr.c
3 *
4 * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /** \file scr.c
35 * \brief This file include the SCR module implementation
36 *
37 * \see scr.h, scrApi.h
38 */
39
40 #define __FILE_ID__ FILE_ID_82
41 #include "tidef.h"
42 #include "report.h"
43 #include "osApi.h"
44 #include "scr.h"
45 #include "DrvMainModules.h"
46
47
48 /*
49 ***********************************************************************
50 * External data definitions.
51 ***********************************************************************
52 */
53
54 /**
55 * \brief This array holds configuration values for abort others field for different clients.\n
56 */
57 static EScrClientId abortOthers[ SCR_RESOURCE_NUM_OF_RESOURCES ][ SCR_CID_NUM_OF_CLIENTS ] =
58 /* APP_SCAN DRV_FG CONT_SCAN XCC_MSR BASIC_MSR CONNECT IMMED_SCN SWITCH_CHNL*/
59 {/* Serving channel resource */
60 { SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_BASIC_MEASURE, SCR_CID_BASIC_MEASURE, SCR_CID_BASIC_MEASURE },
61 /* periodic scan resource */
62 { SCR_CID_NO_CLIENT, SCR_CID_APP_SCAN, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT, SCR_CID_DRIVER_FG_SCAN,SCR_CID_NO_CLIENT, SCR_CID_NO_CLIENT }
63 };
64
65 /**
66 * \brief This array holds configuration values for the client status field for different clients and groups. \n
67 */
68 static TI_BOOL clientStatus[ SCR_RESOURCE_NUM_OF_RESOURCES ][ SCR_MID_NUM_OF_MODES ][ SCR_GID_NUM_OF_GROUPS ][ SCR_CID_NUM_OF_CLIENTS ] =
69 {
70 {/* serving channel resource */
71 {/* This is the table for Normal mode */
72 /* client status for idle group */
73 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
74 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
75 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
76 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
77 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
78 TI_FALSE, /**< client status for SCR_CID_CONNECT */
79 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
80 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
81 /* client status for DRV scan group */
82 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
83 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
84 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
85 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
86 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
87 TI_FALSE, /**< client status for SCR_CID_CONNECT */
88 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
89 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
90 /* client status for APP scan group */
91 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
92 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
93 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
94 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
95 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
96 TI_FALSE, /**< client status for SCR_CID_CONNECT */
97 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
98 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
99 /* client status for connect group */
100 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
101 TI_TRUE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
102 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
103 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
104 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
105 TI_TRUE, /**< client status for SCR_CID_CONNECT */
106 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
107 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
108 /* client status for connected group */
109 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
110 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
111 TI_TRUE, /**< client status for SCR_CID_CONT_SCAN */
112 TI_TRUE, /**< client status for SCR_CID_XCC_MEASURE */
113 TI_TRUE, /**< client status for SCR_CID_BASIC_MEASURE */
114 TI_FALSE, /**< client status for SCR_CID_CONNECT */
115 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
116 TI_TRUE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
117 /* client status for roaming group */
118 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
119 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
120 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
121 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
122 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
123 TI_TRUE, /**< client status for SCR_CID_CONNECT */
124 TI_TRUE, /**< client status for SCR_CID_IMMED_SCAN */
125 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ }
126 },
127
128 /* This is the table for the Soft gemini mode */
129
130 { /* client status for idle group */
131 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
132 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
133 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
134 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
135 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
136 TI_FALSE, /**< client status for SCR_CID_CONNECT */
137 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
138 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
139 /* client status for DRV scan group */
140 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
141 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
142 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
143 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
144 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
145 TI_FALSE, /**< client status for SCR_CID_CONNECT */
146 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
147 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
148 /* client status for APP scan group */
149 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
150 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
151 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
152 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
153 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
154 TI_FALSE, /**< client status for SCR_CID_CONNECT */
155 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
156 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
157 /* client status for connect group */
158 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
159 TI_TRUE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
160 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
161 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
162 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
163 TI_TRUE, /**< client status for SCR_CID_CONNECT */
164 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
165 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
166 /* client status for connected group */
167 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
168 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
169 TI_TRUE, /**< client status for SCR_CID_CONT_SCAN */
170 TI_TRUE, /**< client status for SCR_CID_XCC_MEASURE */
171 TI_TRUE, /**< client status for SCR_CID_BASIC_MEASURE */
172 TI_FALSE, /**< client status for SCR_CID_CONNECT */
173 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
174 TI_TRUE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
175 /* client status for roaming group */
176 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
177 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
178 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
179 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
180 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
181 TI_TRUE, /**< client status for SCR_CID_CONNECT */
182 TI_TRUE, /**< client status for SCR_CID_IMMED_SCAN */
183 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ }
184 }
185 },
186 {/* periodic-scan resource */
187 {/* This is the table for Normal mode */
188 /* client status for idle group */
189 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
190 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
191 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
192 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
193 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
194 TI_FALSE, /**< client status for SCR_CID_CONNECT */
195 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
196 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
197 /* client status for DRV scan gorup */
198 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
199 TI_TRUE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
200 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
201 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
202 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
203 TI_FALSE, /**< client status for SCR_CID_CONNECT */
204 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
205 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
206 /* client status for APP scan gorup */
207 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
208 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
209 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
210 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
211 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
212 TI_FALSE, /**< client status for SCR_CID_CONNECT */
213 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
214 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
215 /* client status for connect group */
216 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
217 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
218 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
219 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
220 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
221 TI_TRUE, /**< client status for SCR_CID_CONNECT */
222 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
223 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
224 /* client status for connected group */
225 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
226 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
227 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
228 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
229 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
230 TI_FALSE, /**< client status for SCR_CID_CONNECT */
231 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
232 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
233 /* client status for roaming group */
234 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
235 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
236 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
237 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
238 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
239 TI_TRUE, /**< client status for SCR_CID_CONNECT */
240 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
241 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ }
242 },
243
244 /* This is the table for the Soft gemini mode */
245
246 { /* client status for idle group */
247 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
248 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
249 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
250 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
251 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
252 TI_FALSE, /**< client status for SCR_CID_CONNECT */
253 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
254 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
255 /* client status for DRV scan gorup */
256 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
257 TI_TRUE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
258 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
259 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
260 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
261 TI_FALSE, /**< client status for SCR_CID_CONNECT */
262 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
263 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
264 /* client status for APP scan gorup */
265 { TI_TRUE, /**< client status for SCR_CID_APP_SCAN */
266 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
267 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
268 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
269 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
270 TI_FALSE, /**< client status for SCR_CID_CONNECT */
271 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
272 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
273 /* client status for connect group */
274 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
275 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
276 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
277 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
278 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
279 TI_TRUE, /**< client status for SCR_CID_CONNECT */
280 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
281 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
282 /* client status for connected group */
283 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
284 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
285 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
286 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
287 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
288 TI_FALSE, /**< client status for SCR_CID_CONNECT */
289 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
290 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ },
291 /* client status for roaming group */
292 { TI_FALSE, /**< client status for SCR_CID_APP_SCAN */
293 TI_FALSE, /**< client status for SCR_CID_DRIVER_FG_SCAN */
294 TI_FALSE, /**< client status for SCR_CID_CONT_SCAN */
295 TI_FALSE, /**< client status for SCR_CID_XCC_MEASURE */
296 TI_FALSE, /**< client status for SCR_CID_BASIC_MEASURE */
297 TI_TRUE, /**< client status for SCR_CID_CONNECT */
298 TI_FALSE, /**< client status for SCR_CID_IMMED_SCAN */
299 TI_FALSE, /**< client status for SCR_CID_SWITCH_CHANNEL */ }
300 }
301 }
302 };
303
304
305 /**
306 * \\n
307 * \date 01-Dec-2004\n
308 * \brief Creates the SCR object
309 *
310 * Function Scope \e Public.\n
311 * \param hOS - handle to the OS object.\n
312 * \return a handle to the SCR object.\n
313 */
scr_create(TI_HANDLE hOS)314 TI_HANDLE scr_create( TI_HANDLE hOS )
315 {
316 /* allocate the SCR object */
317 TScr *pScr = os_memoryAlloc( hOS, sizeof(TScr));
318
319 if ( NULL == pScr )
320 {
321 WLAN_OS_REPORT( ("ERROR: Failed to create SCR module"));
322 return NULL;
323 }
324
325 /* store the OS handle */
326 pScr->hOS = hOS;
327
328 return pScr;
329 }
330
331 /**
332 * \\n
333 * \date 01-Dec-2004\n
334 * \brief Finalizes the SCR object (freeing memory)
335 *
336 * Function Scope \e Public.\n
337 * \param hScr - handle to the SCR object.\n
338 */
scr_release(TI_HANDLE hScr)339 void scr_release( TI_HANDLE hScr )
340 {
341 TScr *pScr = (TScr*)hScr;
342
343 os_memoryFree( pScr->hOS, hScr, sizeof(TScr));
344 }
345
346 /**
347 * \\n
348 * \date 01-Dec-2004\n
349 * \brief Initializes the SCR object
350 *
351 * \param pStadHandles - The driver modules handles
352 * \return void
353 */
scr_init(TStadHandlesList * pStadHandles)354 void scr_init (TStadHandlesList *pStadHandles)
355 {
356 TScr *pScr = (TScr*)(pStadHandles->hSCR);
357 TI_UINT32 i, j;
358
359 /* store the report object */
360 pScr->hReport = pStadHandles->hReport;
361
362 /* mark current group as idle */
363 pScr->currentGroup = SCR_GID_IDLE;
364
365 /* mark current mode as normal */
366 pScr->currentMode = SCR_MID_NORMAL;
367
368 /* signal not within request process */
369 pScr->statusNotficationPending = TI_FALSE;
370
371 /* mark that no client is currently running */
372 for (i = 0; i < SCR_RESOURCE_NUM_OF_RESOURCES; i++)
373 {
374 pScr->runningClient[ i ] = SCR_CID_NO_CLIENT;
375 }
376
377 /* initialize client array */
378 for (i = 0; i < SCR_CID_NUM_OF_CLIENTS; i++ )
379 {
380 for (j = 0; j < SCR_RESOURCE_NUM_OF_RESOURCES; j++)
381 {
382 pScr->clientArray[ i ].state[ j ] = SCR_CS_IDLE;
383 pScr->clientArray[ i ].currentPendingReason[ j ] = SCR_PR_NONE;
384 }
385 pScr->clientArray[ i ].clientRequestCB = NULL;
386 pScr->clientArray[ i ].ClientRequestCBObj = NULL;
387 }
388
389 TRACE0(pScr->hReport, REPORT_SEVERITY_INIT , ".....SCR configured successfully\n");
390 }
391
392 /**
393 * \\n
394 * \date 01-Dec-2004\n
395 * \brief Registers the callback function to be used per client.
396 *
397 * Function Scope \e Public.\n
398 * \param hScr - handle to the SCR object.\n
399 * \param client - the client ID.\n
400 * \param callbackFunc - the address of the callback function to use.\n
401 * \param callbackObj - the handle of the object to pass to the callback function (the client object).\n
402 */
scr_registerClientCB(TI_HANDLE hScr,EScrClientId client,TScrCB callbackFunc,TI_HANDLE callbackObj)403 void scr_registerClientCB( TI_HANDLE hScr,
404 EScrClientId client,
405 TScrCB callbackFunc,
406 TI_HANDLE callbackObj )
407 {
408 TScr *pScr = (TScr*)hScr;
409
410 #ifdef TI_DBG
411 if (client >= SCR_CID_NUM_OF_CLIENTS)
412 {
413 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to register callback for invalid client %d\n", client);
414 return;
415 }
416 #endif
417 pScr->clientArray[ client ].clientRequestCB = callbackFunc;
418 pScr->clientArray[ client ].ClientRequestCBObj = callbackObj;
419 }
420
421 /**
422 * \\n
423 * \date 01-Dec-2004\n
424 * \brief Notifies the running process upon a firmware reset.
425 *
426 * Function Scope \e Public.\n
427 * \param hScr - handle to the SCR object.\n
428 */
scr_notifyFWReset(TI_HANDLE hScr)429 void scr_notifyFWReset( TI_HANDLE hScr )
430 {
431 TScr *pScr = (TScr*)hScr;
432 TI_UINT32 uResourceIndex;
433
434 /* check both resources */
435 for (uResourceIndex = 0; uResourceIndex < SCR_RESOURCE_NUM_OF_RESOURCES; uResourceIndex++)
436 {
437 /* if a client is currently running, notify it of the recovery event */
438 if ( SCR_CID_NO_CLIENT != pScr->runningClient[ uResourceIndex ] )
439 {
440 TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "FW reset occured. Client %d Notified.\n", pScr->runningClient[ uResourceIndex ]);
441 if ( NULL != pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB )
442 {
443 pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB( pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].ClientRequestCBObj,
444 SCR_CRS_FW_RESET, (EScrResourceId)uResourceIndex, SCR_PR_NONE );
445 }
446 else
447 {
448 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", pScr->runningClient[ uResourceIndex ]);
449 }
450 }
451 #ifdef TI_DBG
452 else
453 {
454 TRACE0( pScr->hReport, REPORT_SEVERITY_INFORMATION, "FW reset occured. No client was running.\n");
455 }
456 #endif
457 }
458 }
459
460 /**
461 * \\n
462 * \date 27-April-2005\n
463 * \brief Changes the current SCR group.\n
464 *
465 * Function Scope \e Public.\n
466 * \param hScr - handle to the SCR object.\n
467 * \param newGroup - the new group to use.\n
468 */
scr_setGroup(TI_HANDLE hScr,EScrGroupId newGroup)469 void scr_setGroup( TI_HANDLE hScr, EScrGroupId newGroup )
470 {
471 TScr *pScr = (TScr*)hScr;
472 TI_UINT32 i, uResourceIndex;
473 EScrClientId highestPending;
474
475 TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Setting group %d.\n", newGroup);
476
477 #ifdef TI_DBG
478 if (newGroup >= SCR_GID_NUM_OF_GROUPS)
479 {
480 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to set invalid group to %d\n", newGroup);
481 return;
482 }
483 #endif
484
485 /* keep the new group */
486 pScr->currentGroup = newGroup;
487
488 /* check both resources */
489 for (uResourceIndex = 0; uResourceIndex < SCR_RESOURCE_NUM_OF_RESOURCES; uResourceIndex++)
490 {
491 /* for all pending clients */
492 for ( i = 0; i < SCR_CID_NUM_OF_CLIENTS; i++ )
493 {
494 /* if the pending reason has escalated */
495 if ( (pScr->clientArray[ i ].state[ uResourceIndex ] == SCR_CS_PENDING) && /* the client is pending */
496 (pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] < SCR_PR_DIFFERENT_GROUP_RUNNING) && /* the client was enabled in the previous group */
497 (TI_FALSE == clientStatus[ uResourceIndex ][ pScr->currentMode ][ newGroup ][ i ])) /* the client is not enabled in the new group */
498 {
499 /* mark the new pending reason */
500 pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] = SCR_PR_DIFFERENT_GROUP_RUNNING;
501
502 /* notify the client of the change, using its callback */
503 if ( NULL != pScr->clientArray[ i ].clientRequestCB )
504 {
505 pScr->clientArray[ i ].clientRequestCB( pScr->clientArray[ i ].ClientRequestCBObj,
506 SCR_CRS_PEND, (EScrResourceId)uResourceIndex, SCR_PR_DIFFERENT_GROUP_RUNNING );
507 }
508 else
509 {
510 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", i);
511 }
512 }
513 }
514
515
516 /*
517 * if no client is running call the highest pending client
518 * (after group change, previously pending clients may be enabled)
519 */
520 if ( SCR_CID_NO_CLIENT == pScr->runningClient[ uResourceIndex ] )
521 {
522 highestPending = scrFindHighest( hScr, SCR_CS_PENDING, uResourceIndex,
523 (SCR_CID_NUM_OF_CLIENTS - 1), 0 );
524 if (( SCR_CID_NO_CLIENT != highestPending ) && (highestPending < SCR_CID_NUM_OF_CLIENTS))
525 {
526 pScr->clientArray[ highestPending ].state[ uResourceIndex ] = SCR_CS_RUNNING;
527 pScr->clientArray[ highestPending ].currentPendingReason[ uResourceIndex ] = SCR_PR_NONE;
528 pScr->runningClient[ uResourceIndex ] = (EScrClientId)highestPending;
529 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
530 {
531 pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
532 SCR_CRS_RUN, (EScrResourceId)uResourceIndex, SCR_PR_NONE );
533 }
534 else
535 {
536 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
537 }
538 }
539 }
540 }
541 }
542
543 /**
544 * \\n
545 * \date 23-Nov-2005\n
546 * \brief Changes the current SCR mode.\n
547 *
548 * Function Scope \e Public.\n
549 * \param hScr - handle to the SCR object.\n
550 * \param newMode - the new mode to use.\n
551 */
scr_setMode(TI_HANDLE hScr,EScrModeId newMode)552 void scr_setMode( TI_HANDLE hScr, EScrModeId newMode )
553 {
554 TScr *pScr = (TScr*)hScr;
555 #ifdef SCR_ABORT_NOTIFY_ENABLED
556 TI_UINT32 i, uResourceIndex;
557 EScrClientId highestPending;
558 #endif
559
560 TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Setting mode %d.\n", newMode);
561
562 #ifdef TI_DBG
563 if (newMode >= SCR_MID_NUM_OF_MODES)
564 {
565 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to set invalid mode to %d\n", newMode);
566 return;
567 }
568 #endif
569
570 /* keep the new mode */
571 pScr->currentMode = newMode;
572
573 #ifdef SCR_ABORT_NOTIFY_ENABLED
574
575 for (uResourceIndex = 0; uResourceIndex < SCR_RESOURCE_NUM_OF_RESOURCES; uResourceIndex++)
576 {
577 /* Stage I : if someone is running and shouldn't be running in the new mode - Abort it */
578 if ( (SCR_CID_NO_CLIENT != pScr->runningClient[ uResourceIndex ]) &&
579 (TI_FALSE == clientStatus[ uResourceIndex ][ pScr->currentMode ][ pScr->currentGroup ][ pScr->runningClient[ uResourceIndex ] ]))
580 {
581 /* abort the running client */
582 pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].state[ uResourceIndex ] = SCR_CS_ABORTING;
583 if ( NULL != pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB )
584 {
585 TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Sending abort request to client %d for resource %d\n", pScr->runningClient[ uResourceIndex ], uResourceIndex);
586 pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].clientRequestCB( pScr->clientArray[ pScr->runningClient[ uResourceIndex ] ].ClientRequestCBObj,
587 SCR_CRS_ABORT,
588 (EScrResourceId)uResourceIndex,
589 SCR_PR_NONE );
590 }
591 else
592 {
593 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", pScr->runningClient[ uResourceIndex ]);
594 }
595 }
596
597 /* Stage II : notify escalated pending reason */
598 /* for all pending clients */
599 for ( i = 0; i < SCR_CID_NUM_OF_CLIENTS; i++ )
600 {
601 /* if the pending reason has escalated */
602 if ( (pScr->clientArray[ i ].state[ uResourceIndex ] == SCR_CS_PENDING) && /* the client is pending */
603 (pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] < SCR_PR_DIFFERENT_GROUP_RUNNING) && /* the client was enabled in the previous group */
604 (TI_FALSE == clientStatus[ uResourceIndex ][ pScr->currentMode ][ pScr->currentGroup ][ i ])) /* the client is not enabled in the new group/mode */
605 {
606 /* mark the new pending reason */
607 pScr->clientArray[ i ].currentPendingReason[ uResourceIndex ] = SCR_PR_DIFFERENT_GROUP_RUNNING;
608
609 /* notify the client of the change, using its callback */
610 if ( NULL != pScr->clientArray[ i ].clientRequestCB )
611 {
612 pScr->clientArray[ i ].clientRequestCB( pScr->clientArray[ i ].ClientRequestCBObj,
613 SCR_CRS_PEND, (EScrResourceId)uResourceIndex,
614 SCR_PR_DIFFERENT_GROUP_RUNNING );
615 }
616 else
617 {
618 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", i);
619 }
620 }
621 }
622
623
624 /* Stage III : call Highest Pending Client who is enabled in the new mode */
625 if ( SCR_CID_NO_CLIENT == pScr->runningClient[ uResourceIndex ] )
626 {
627 highestPending = scrFindHighest( hScr, SCR_CS_PENDING, uResourceIndex,
628 (SCR_CID_NUM_OF_CLIENTS - 1), 0 );
629 if (SCR_CID_NO_CLIENT != highestPending)
630 {
631 pScr->clientArray[ highestPending ].state[ uResourceIndex ] = SCR_CS_RUNNING;
632 pScr->clientArray[ highestPending ].currentPendingReason[ uResourceIndex ] = SCR_PR_NONE;
633 pScr->runningClient[ uResourceIndex ] = (EScrClientId)highestPending;
634 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
635 {
636 pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
637 SCR_CRS_RUN, (EScrResourceId)uResourceIndex,
638 SCR_PR_NONE );
639 }
640 else
641 {
642 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
643 }
644 }
645 }
646 }
647 #endif /* SCR_ABORT_NOTIFY_ENABLED */
648 }
649
650
651 /**
652 * \\n
653 * \date 01-Dec-2004\n
654 * \brief Request the channel use by a client
655 *
656 * Function Scope \e Public.\n
657 * \param hScr - handle to the SCR object.\n
658 * \param client - the client ID requesting the channel.\n
659 * \param resource - the requested resource.\n
660 * \param pPendReason - the reason for a pend reply.\n
661 * \return The request status.\n
662 * \retval SCR_CRS_REJECT the channel cannot be allocated to this client.
663 * \retval SCR_CRS_PEND the channel is currently busy, and this client had been placed on the waiting list.
664 * \retval SCR_CRS_RUN the channel is allocated to this client.
665 */
scr_clientRequest(TI_HANDLE hScr,EScrClientId client,EScrResourceId eResource,EScePendReason * pPendReason)666 EScrClientRequestStatus scr_clientRequest( TI_HANDLE hScr, EScrClientId client,
667 EScrResourceId eResource, EScePendReason* pPendReason )
668 {
669 TScr *pScr = (TScr*)hScr;
670
671 TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "scr_clientRequest: Client %d requesting the channel for resource %d.\n", client, eResource);
672
673 #ifdef TI_DBG
674 if (client >= SCR_CID_NUM_OF_CLIENTS)
675 {
676 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to request SCR for invalid client %d\n", client);
677 return SCR_CRS_PEND;
678 }
679 if (SCR_RESOURCE_NUM_OF_RESOURCES <= eResource)
680 {
681 TRACE2( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to request SCR by client %d for invalid resource %d\n", client, eResource);
682 return SCR_CRS_PEND;
683 }
684 #endif
685
686 *pPendReason = SCR_PR_NONE;
687
688 /* check if already inside a request - shouldn't happen!!! */
689 if ( TI_TRUE == pScr->statusNotficationPending )
690 {
691 TRACE0( pScr->hReport, REPORT_SEVERITY_ERROR, "request call while already in request!\n");
692 return SCR_CRS_PEND;
693 }
694
695 /* check if current running client is requesting */
696 if ( client == pScr->runningClient[ eResource ] )
697 {
698 TRACE2( pScr->hReport, REPORT_SEVERITY_WARNING, "Client %d re-requesting SCR for resource %d\n", client, eResource);
699 return SCR_CRS_RUN;
700 }
701
702 TRACE5( pScr->hReport, REPORT_SEVERITY_INFORMATION, "scr_clientRequest: is client enabled = %d. eResource=%d,currentMode=%d,currentGroup=%d,client=%d,\n", clientStatus[ eResource ][ pScr->currentMode ][ pScr->currentGroup ][ client ], eResource, pScr->currentMode, pScr->currentGroup, client);
703
704 /* check if the client is enabled in the current group */
705 if ( TI_TRUE != clientStatus[ eResource ][ pScr->currentMode ][ pScr->currentGroup ][ client ])
706 {
707 pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
708 pScr->clientArray[ client ].currentPendingReason[ eResource ]
709 = *pPendReason = SCR_PR_DIFFERENT_GROUP_RUNNING;
710 return SCR_CRS_PEND;
711 }
712
713 /* check if a there's no running client at the moment */
714 if ( SCR_CID_NO_CLIENT == pScr->runningClient[ eResource ] )
715 {
716 /* no running or aborted client - allow access */
717 TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Resource %d allocated to client: %d\n", eResource, client);
718 pScr->clientArray[ client ].state[ eResource ] = SCR_CS_RUNNING;
719 pScr->runningClient[ eResource ] = client;
720 return SCR_CRS_RUN;
721 }
722
723 /* check if any client is aborting at the moment */
724 if ( SCR_CS_ABORTING == pScr->clientArray[ pScr->runningClient[ eResource ] ].state[ eResource ] )
725 {
726 /* a client is currently aborting, but there still might be a pending client with higher priority
727 than the client currently requesting the SCR. If such client exists, the requesting client is
728 notified that it is pending because of this pending client, rather than the one currently aborting.
729 */
730 EScrClientId highestPending;
731 highestPending = scrFindHighest( hScr, SCR_CS_PENDING, eResource,
732 (SCR_CID_NUM_OF_CLIENTS - 1), client );
733 if ( (SCR_CID_NO_CLIENT == highestPending) ||
734 (highestPending < client))
735 {
736 /* if the requesting client has higher priority than the current highest priority pending client,
737 the current highest priority pending client should be notified that its pending reason has
738 changed (it is no longer waiting for current running client to abort, but for the requesting
739 client to finish, once the current has aborted */
740 if ( (highestPending != SCR_CID_NO_CLIENT) &&
741 (SCR_PR_OTHER_CLIENT_ABORTING == pScr->clientArray[ highestPending ].currentPendingReason[ eResource ]))
742 {
743
744 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
745 {
746 pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
747 SCR_CRS_PEND, eResource, SCR_PR_OTHER_CLIENT_RUNNING );
748 }
749 else
750 {
751 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
752 }
753 }
754 pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_ABORTING;
755 }
756 else
757 {
758 pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_RUNNING;
759 }
760 pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
761 return SCR_CRS_PEND;
762 }
763
764 /* check if a client with higher priority is running */
765 if (pScr->runningClient[ eResource ] > client)
766 {
767 pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
768 pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_RUNNING;
769 return SCR_CRS_PEND;
770 }
771
772 /* if the client is not supposed to abort lower priority clients */
773 if ( (SCR_CID_NO_CLIENT == abortOthers[ eResource ][ client ]) || /* client is not supposed to abort any other client */
774 (pScr->runningClient[ eResource ] > abortOthers[ eResource ][ client ])) /* client is not supposed to abort running client */
775 {
776 /* wait for the lower priority client */
777 pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
778 pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_RUNNING;
779 return SCR_CRS_PEND;
780 }
781
782 /* at this point, there is a lower priority client running, that should be aborted: */
783 /* mark the requesting client as pending (until the abort process will be completed) */
784 pScr->clientArray[ client ].state[ eResource ] = SCR_CS_PENDING;
785
786 /* mark that we are in the middle of a request (if a re-entrance will occur in the complete) */
787 pScr->statusNotficationPending = TI_TRUE;
788
789 /* abort the running client */
790 pScr->clientArray[ pScr->runningClient[ eResource ] ].state[ eResource ] = SCR_CS_ABORTING;
791 if ( NULL != pScr->clientArray[ pScr->runningClient[ eResource ] ].clientRequestCB )
792 {
793 TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Sending abort request to client %d for resource %d\n", pScr->runningClient[ eResource ], eResource);
794 pScr->clientArray[ pScr->runningClient[ eResource ] ].clientRequestCB( pScr->clientArray[ pScr->runningClient[ eResource ] ].ClientRequestCBObj,
795 SCR_CRS_ABORT, eResource,
796 SCR_PR_NONE );
797 }
798 else
799 {
800 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", pScr->runningClient[ eResource ]);
801 }
802
803 /* mark that we have finished the request process */
804 pScr->statusNotficationPending = TI_FALSE;
805
806 /* return the current status (in case the completion changed the client status to run) */
807 if ( SCR_CS_RUNNING == pScr->clientArray[ client ].state[ eResource ] )
808 {
809 TRACE1( pScr->hReport, REPORT_SEVERITY_INFORMATION, "channel allocated to client: %d\n", client);
810 return SCR_CRS_RUN;
811 }
812 else
813 {
814 pScr->clientArray[ client ].currentPendingReason[ eResource ] = *pPendReason = SCR_PR_OTHER_CLIENT_ABORTING;
815 return SCR_CRS_PEND;
816 }
817 }
818
819 /**
820 * \\n
821 * \date 01-Dec-2004\n
822 * \brief Notifies the SCR that the client doe not require the channel any longer
823 *
824 * This function can be called both by clients that are in possession of the channel, and by
825 * clients that are pending to use the channel.\n
826 * Function Scope \e Public.\n
827 * \param hScr - handle to the SCR object.\n
828 * \param client - the client releasing the channel.\n
829 * \param eResource - the resource being released.\n
830 * \return TI_OK if successful, TI_NOK otherwise.\n
831 */
scr_clientComplete(TI_HANDLE hScr,EScrClientId client,EScrResourceId eResource)832 void scr_clientComplete( TI_HANDLE hScr, EScrClientId client, EScrResourceId eResource )
833 {
834 TScr *pScr = (TScr*)hScr;
835 EScrClientId highestPending;
836
837 TRACE2( pScr->hReport, REPORT_SEVERITY_INFORMATION, "Client %d releasing resource %d.\n", client, eResource);
838
839 #ifdef TI_DBG
840 if (client >= SCR_CID_NUM_OF_CLIENTS)
841 {
842 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to release SCR for invalid client %d\n", client);
843 return;
844 }
845 if (SCR_RESOURCE_NUM_OF_RESOURCES <= eResource)
846 {
847 TRACE2( pScr->hReport, REPORT_SEVERITY_ERROR, "Attempting to release invalid resource %d by client %d\n", eResource, client);
848 return;
849 }
850 #endif
851
852 /* mark client state as idle */
853 pScr->clientArray[ client ].state[ eResource ] = SCR_CS_IDLE;
854 pScr->clientArray[ client ].currentPendingReason[ eResource ] = SCR_PR_NONE;
855
856 /* if completing client is running (or aborting) */
857 if ( pScr->runningClient[ eResource ] == client )
858 {
859 /* mark no running client */
860 pScr->runningClient[ eResource ] = SCR_CID_NO_CLIENT;
861
862 /* find the pending client with highest priority */
863 highestPending = scrFindHighest( hScr, SCR_CS_PENDING, eResource, (SCR_CID_NUM_OF_CLIENTS-1), 0 );
864
865 /* if a pending client exists */
866 if (( SCR_CID_NO_CLIENT != highestPending ) && (highestPending < SCR_CID_NUM_OF_CLIENTS))
867 {
868 /* mark the client with highest priority as running */
869 pScr->clientArray[ highestPending ].state[ eResource ] = SCR_CS_RUNNING;
870 pScr->clientArray[ highestPending ].currentPendingReason[ eResource ] = SCR_PR_NONE;
871 pScr->runningClient[ eResource ] = highestPending;
872
873 /* if the SCR is not called from within a client request (re-entrance) */
874 if ( TI_FALSE == pScr->statusNotficationPending )
875 {
876 if ( NULL != pScr->clientArray[ highestPending ].clientRequestCB )
877 {
878 pScr->clientArray[ highestPending ].clientRequestCB( pScr->clientArray[ highestPending ].ClientRequestCBObj,
879 SCR_CRS_RUN, eResource, SCR_PR_NONE );
880 }
881 else
882 {
883 TRACE1( pScr->hReport, REPORT_SEVERITY_ERROR, "Trying to call client %d callback, which is NULL\n", highestPending);
884 }
885 }
886 }
887 }
888 }
889
890 /**
891 * \\n
892 * \date 01-Dec-2004\n
893 * \brief Searches the client database for a client with matching state, from startFrom to endAt (inclusive).
894 * \brief Only searches for clients that are enabled at the current group!!!!\n
895 *
896 * Function Scope \e Private.\n
897 * \param hScr - handle to the SCR object.\n
898 * \param requiredState - the state to match.\n
899 * \param eResource - the resource to macth.\n
900 * \param startFrom - the highest priority to begin searching from.\n
901 * \param endAt - the lowest priority to include in the search
902 * \return the client ID if found, SCR_CID_NO_CLIENT if not found.\n
903 */
scrFindHighest(TI_HANDLE hScr,EScrClientState requiredState,EScrResourceId eResource,TI_UINT32 startFrom,TI_UINT32 endAt)904 EScrClientId scrFindHighest( TI_HANDLE hScr,
905 EScrClientState requiredState,
906 EScrResourceId eResource,
907 TI_UINT32 startFrom,
908 TI_UINT32 endAt )
909 {
910 TScr *pScr = (TScr*)hScr;
911 TI_INT32 i, iStartFrom, iEndAt;
912
913 /*
914 * signed indexes are used to avoid an overflow in the for loop when endAt equals zero
915 * and the unsigned i is "reduced" to overflow to 4 Billion
916 */
917 iStartFrom = (TI_INT32)startFrom;
918 iEndAt = (TI_INT32)endAt;
919
920 /* loop on all clients, from start to end */
921 for ( i = iStartFrom; i >= iEndAt; i-- )
922 {
923 /* check if the client state matches the required state */
924 if ( (TI_TRUE == clientStatus[ eResource ][ pScr->currentMode ][ pScr->currentGroup ][ i ]) && /* client is enabled in current group */
925 (requiredState == pScr->clientArray[ i ].state[ eResource ])) /* client is in required state */
926 {
927 /* and if so, return the client index */
928 return (EScrClientId)i;
929 }
930 }
931
932 return SCR_CID_NO_CLIENT;
933 }
934