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 */
57static 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 */
68static 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 */
314TI_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 */
339void 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 */
354void 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 */
403void 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 */
429void 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 */
469void 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 */
552void 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 */
666EScrClientRequestStatus 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 */
832void 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 */
904EScrClientId 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