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