1 /* 2 * requestHandler.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /** \file RequestHandler.c 35 * \brief RequestHandler module interface 36 * 37 * \see RequestHandler.h 38 */ 39 40 /****************************************************************************************************/ 41 /* */ 42 /* MODULE: RequestHandler.c */ 43 /* PURPOSE: RequestHandler module interface. */ 44 /* This module handle the incoming measurement requests. The object handle */ 45 /* data base that stores all measurement requests from the last incoming. */ 46 /* This module export interface function for sceduling the next requests to be */ 47 /* executed and stores all relevent fields for constructing a measurement report. */ 48 /* */ 49 /****************************************************************************************************/ 50 #define __FILE_ID__ FILE_ID_4 51 #include "report.h" 52 #include "osApi.h" 53 #include "paramOut.h" 54 #include "requestHandler.h" 55 56 #ifdef XCC_MODULE_INCLUDED 57 #include "XCCRMMngrParam.h" 58 #endif 59 60 /* allocation vector */ 61 #define REQUEST_HANDLER_INIT_BIT (1) 62 63 #define DOT11_MEASUREMENT_REQUEST_ELE_ID (38) 64 65 /********************************************************************************/ 66 /* Internal functions prototypes. */ 67 /********************************************************************************/ 68 static void release_module(requestHandler_t *pRequestHandler, TI_UINT32 initVec); 69 70 static TI_STATUS insertMeasurementIEToQueue(TI_HANDLE hRequestHandler, 71 TI_UINT16 frameToken, 72 EMeasurementMode measurementMode, 73 TI_UINT8 *pData, 74 TI_UINT8 *singelRequestLen); 75 76 /********************************************************************************/ 77 /* Interface functions Implementation. */ 78 /********************************************************************************/ 79 80 81 /******************************************************************************** 82 * requestHandler_create * 83 ******************************************************************************** 84 DESCRIPTION: RequestHandler module creation function, called by the measurement in 85 creation phase. performs the following: 86 87 - Allocate the RequestHandler handle 88 89 INPUT: hOs - Handle to OS 90 91 OUTPUT: 92 93 RETURN: Handle to the RequestHandler module on success, NULL otherwise 94 ************************************************************************/ 95 TI_HANDLE requestHandler_create(TI_HANDLE hOs) 96 { 97 requestHandler_t *pRequestHandler = NULL; 98 TI_UINT32 initVec = 0; 99 100 101 /* allocating the RequestHandler object */ 102 pRequestHandler = os_memoryAlloc(hOs,sizeof(requestHandler_t)); 103 104 if (pRequestHandler == NULL) 105 return NULL; 106 107 initVec |= (1 << REQUEST_HANDLER_INIT_BIT); 108 109 return(pRequestHandler); 110 } 111 112 /************************************************************************ 113 * requestHandler_config * 114 ************************************************************************ 115 DESCRIPTION: RequestHandler module configuration function, called by the measurement 116 in configuration phase. performs the following: 117 - Reset & initiailzes local variables 118 - Init the handles to be used by the module 119 120 INPUT: hRequestHandler - RequestHandler handle. 121 List of handles to be used by the module 122 123 OUTPUT: 124 125 RETURN: TI_OK on success, TI_NOK otherwise 126 127 ************************************************************************/ 128 TI_STATUS RequestHandler_config(TI_HANDLE hRequestHandler, 129 TI_HANDLE hReport, 130 TI_HANDLE hOs) 131 { 132 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 133 134 135 /* init variables */ 136 pRequestHandler->parserRequestIEHdr = NULL; 137 pRequestHandler->numOfWaitingRequests = 0; /* indicating empty data base */ 138 pRequestHandler->activeRequestID = -1; /* */ 139 pRequestHandler->hReport = hReport; 140 pRequestHandler->hOs = hOs; 141 142 /* Clearing the Request Array , mostly due to parallel bit */ 143 os_memoryZero(pRequestHandler->hOs, pRequestHandler->reqArr, MAX_NUM_REQ * sizeof(MeasurementRequest_t)); 144 145 TRACE0(pRequestHandler->hReport, REPORT_SEVERITY_INIT, ": RequestHandler configured successfully\n"); 146 147 return TI_OK; 148 } 149 150 /*********************************************************************** 151 * requestHandler_setParam 152 *********************************************************************** 153 DESCRIPTION: RequestHandler set param function, called by the following: 154 - config mgr in order to set a parameter receiving from 155 the OS abstraction layer. 156 - From inside the dirver 157 158 INPUT: hRequestHandler - RequestHandler handle. 159 pParam - Pointer to the parameter 160 161 OUTPUT: 162 163 RETURN: TI_OK on success, TI_NOK otherwise 164 165 ************************************************************************/ 166 TI_STATUS requestHandler_setParam(TI_HANDLE hRequestHandler, 167 paramInfo_t *pParam) 168 { 169 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 170 171 switch(pParam->paramType) 172 { 173 /* case RequestHandler_PARAM_TYPE:*/ 174 175 /* break;*/ 176 177 default: 178 TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_ERROR, ": Set param, Params is not supported, %d\n\n", pParam->paramType); 179 return PARAM_NOT_SUPPORTED; 180 } 181 182 /* return TI_OK; - unreachable */ 183 } 184 185 /*********************************************************************** 186 * requestHandler_getParam 187 *********************************************************************** 188 DESCRIPTION: RequestHandler get param function, called by the following: 189 - config mgr in order to get a parameter from the OS a 190 bstraction layer. 191 - From inside the dirver 192 193 INPUT: hRequestHandler - RequestHandler handle. 194 pParam - Pointer to the parameter 195 196 OUTPUT: 197 198 RETURN: TI_OK on success, TI_NOK otherwise 199 200 ************************************************************************/ 201 TI_STATUS requestHandler_getParam(TI_HANDLE hRequestHandler, 202 paramInfo_t *pParam) 203 { 204 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 205 /* TI_STATUS status;*/ 206 207 switch(pParam->paramType) 208 { 209 /*case RequestHandler_PARAM:*/ 210 211 212 /*return status;*/ 213 214 default: 215 TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_ERROR, ": Get param, Params is not supported, %d\n\n", pParam->paramType); 216 return PARAM_NOT_SUPPORTED; 217 } 218 219 /* return TI_OK; - unreachable */ 220 } 221 222 /************************************************************************ 223 * RequestHandler_destroy * 224 ************************************************************************ 225 DESCRIPTION: RequestHandler module destroy function, called by the config 226 mgr in the destroy phase 227 performs the following: 228 - Free all memory aloocated by the module 229 230 INPUT: hRequestHandler - RequestHandler handle. 231 232 OUTPUT: 233 234 RETURN: TI_OK on success, TI_NOK otherwise 235 236 ************************************************************************/ 237 TI_STATUS requestHandler_destroy(TI_HANDLE hRequestHandler) 238 { 239 requestHandler_t * pRequestHandler = (requestHandler_t *)hRequestHandler; 240 TI_UINT32 initVec; 241 242 if (pRequestHandler == NULL) 243 return TI_OK; 244 245 initVec = 0xFFFF; 246 release_module(pRequestHandler, initVec); 247 248 return TI_OK; 249 } 250 251 /************************************************************************ 252 * requestHandler_insertRequests * 253 ************************************************************************ 254 DESCRIPTION: RequestHandler module parsing function, called by the 255 measurement object when measuremnt request frame is received. 256 performs the following: 257 - Parsers the measurement request frame. 258 - Inserts all requests into the queue. 259 - Initializes each request according to the its frame 260 token, measurement token, measurement type, parallel, 261 channel number, duration time and scan mode. 262 - The function updates the numOfWaitingRequests variable 263 and set to zero the activeReqId. 264 265 Note: The activeReqId contains the index for the first request 266 that should be executed or to the current active request. 267 268 INPUT: hRequestHandler - RequestHandler handle. 269 measurementMode - The MEasurement Object Mode. 270 measurementFrameReq - The New Frame request that was received. 271 272 OUTPUT: 273 274 RETURN: TI_OK on success, TI_NOK otherwise 275 ************************************************************************/ 276 TI_STATUS requestHandler_insertRequests(TI_HANDLE hRequestHandler, 277 EMeasurementMode measurementMode, 278 TMeasurementFrameRequest measurementFrameReq) 279 { 280 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 281 TI_INT32 requestsLen = measurementFrameReq.requestsLen; 282 TI_UINT8 singelRequestLen = 0; 283 TI_UINT8 *requests = measurementFrameReq.requests; 284 285 if (requestsLen < 2) 286 { 287 TRACE0(pRequestHandler->hReport, REPORT_SEVERITY_ERROR, ": Invalid length of the data.\n"); 288 289 return TI_NOK; 290 } 291 292 /* Inserting all measurement request into the queues */ 293 while (requestsLen > 0) 294 { 295 if(insertMeasurementIEToQueue(hRequestHandler, 296 measurementFrameReq.hdr->dialogToken, 297 measurementMode, 298 requests, 299 &singelRequestLen) != TI_OK ) 300 { 301 requestHandler_clearRequests(hRequestHandler); 302 return TI_NOK; 303 } 304 305 requestsLen -= singelRequestLen; 306 requests += singelRequestLen; 307 308 } 309 310 pRequestHandler->activeRequestID = 0; 311 312 TRACE2(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Inserted into queue: activeRequestID = %d, numOfWaitingRequests = %d\n", pRequestHandler->activeRequestID, pRequestHandler->numOfWaitingRequests); 313 314 return TI_OK; 315 } 316 317 /************************************************************************ 318 * requestHandler_getNextReq * 319 ************************************************************************ 320 DESCRIPTION: RequestHandler module function for retrieving the requests that 321 should be executed. 322 performs the following: 323 - returns pointers to one request/several requests that 324 should be performed in parallel. 325 Note: The function updates the numOfWaitingRequests internal 326 varaible ONLY IF the returned request/s are going to be 327 executed immediatly (isForActivation = TI_TRUE). 328 329 INPUT: hRequestHandler - RequestHandler handle. 330 331 isForActivation - A flag that indicates if the returned 332 request/s are going to be executed immediatly 333 334 OUTPUT: pRequest - pointer contains the address in which the 335 next requests for activation should be inserted. 336 337 numOfRequests - indicates how many requests should be activated 338 in parallel. 339 340 RETURN: TI_OK on success, TI_NOK otherwise 341 ************************************************************************/ 342 TI_STATUS requestHandler_getNextReq(TI_HANDLE hRequestHandler, 343 TI_BOOL isForActivation, 344 MeasurementRequest_t *pRequest[], 345 TI_UINT8* numOfRequests) 346 { 347 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 348 TI_UINT8 requestIndex = pRequestHandler->activeRequestID; 349 TI_UINT8 loopIndex = 0; 350 351 TRACE2(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Looking for requests. activeRequestID = %d, numOfWaitingRequests = %d\n", pRequestHandler->activeRequestID, pRequestHandler->numOfWaitingRequests); 352 353 if(pRequestHandler->numOfWaitingRequests <= 0) 354 return TI_NOK; 355 356 do{ 357 pRequest[loopIndex] = &(pRequestHandler->reqArr[requestIndex]); 358 requestIndex++; 359 loopIndex++; 360 } 361 while ( (loopIndex < pRequestHandler->numOfWaitingRequests) && 362 (pRequestHandler->reqArr[requestIndex].isParallel) ); 363 364 *numOfRequests = loopIndex; 365 366 TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Found %d requests to execute in parallel.\n", loopIndex); 367 368 if(isForActivation == TI_TRUE) 369 { 370 pRequestHandler->numOfWaitingRequests -= loopIndex; 371 372 TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Requests were queried for activation so decreasing numOfWaitingRequests to %d\n", pRequestHandler->numOfWaitingRequests); 373 } 374 375 return TI_OK; 376 } 377 378 /************************************************************************ 379 * requestHandler_getCurrentExpiredReq * 380 ************************************************************************ 381 DESCRIPTION: RequestHandler module function for retrieving the request that 382 finished its execution. 383 performs the following: 384 - returns pointers to the request that 385 finished its execution in. 386 387 INPUT: hRequestHandler - RequestHandler handle. 388 requestIndex - Index of request in the queue 389 390 OUTPUT: pRequest - pointer contains the addresse of the 391 request that finished its execution. 392 393 RETURN: TI_OK on success, TI_NOK otherwise 394 ************************************************************************/ 395 TI_STATUS requestHandler_getCurrentExpiredReq(TI_HANDLE hRequestHandler, 396 TI_UINT8 requestIndex, 397 MeasurementRequest_t **pRequest) 398 { 399 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 400 401 requestIndex += pRequestHandler->activeRequestID; 402 403 *pRequest = &(pRequestHandler->reqArr[requestIndex]); 404 405 return TI_OK; 406 } 407 408 409 /************************************************************************ 410 * requestHandler_clearRequests * 411 ************************************************************************ 412 DESCRIPTION: RequestHandler module function for cleaning the data base. 413 performs the following: 414 - Clears all requests from the queue by setting 415 the activeReqId and numOfWaitingRequests variables. 416 Note: The function does not actually zero all queue 417 variables or destroy the object. 418 419 INPUT: hRequestHandler - RequestHandler handle. 420 421 OUTPUT: None 422 423 RETURN: TI_OK on success, TI_NOK otherwise 424 ************************************************************************/ 425 TI_STATUS requestHandler_clearRequests(TI_HANDLE hRequestHandler) 426 { 427 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 428 429 pRequestHandler->numOfWaitingRequests = 0; 430 pRequestHandler->activeRequestID = -1; 431 432 /* Clearing the Request Array , mostly due to parallel bit */ 433 os_memoryZero(pRequestHandler->hOs,pRequestHandler->reqArr, 434 MAX_NUM_REQ * sizeof(MeasurementRequest_t)); 435 436 TRACE2(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Request queue has been cleared. activeRequestID = %d, numOfWaitingRequests = %d\n", pRequestHandler->activeRequestID, pRequestHandler->numOfWaitingRequests); 437 438 return TI_OK; 439 } 440 441 442 443 /************************************************************************ 444 * requestHandler_getFrameToken * 445 ************************************************************************ 446 DESCRIPTION: RequestHandler module function for getting the token of the 447 frame that is now being processed. 448 449 INPUT: hRequestHandler - RequestHandler handle. 450 451 452 OUTPUT: frameToken 453 454 RETURN: TI_OK on success, TI_NOK otherwise 455 ************************************************************************/ 456 TI_STATUS requestHandler_getFrameToken(TI_HANDLE hRequestHandler,TI_UINT16 *frameToken ) 457 { 458 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 459 460 if(pRequestHandler->activeRequestID == -1) 461 return TI_NOK; 462 463 *frameToken = pRequestHandler->reqArr[0].frameToken; 464 465 return TI_OK; 466 } 467 468 /************************************************************************ 469 * requestHandler_setRequestParserFunction * 470 ************************************************************************ 471 DESCRIPTION: RequestHandler module function for setting the function that 472 parasers a request IE. 473 474 INPUT: hRequestHandler - RequestHandler handle. 475 parserRequestIE - A pointer to the function. 476 477 478 OUTPUT: 479 480 RETURN: TI_OK on success, TI_NOK otherwise 481 ************************************************************************/ 482 TI_STATUS requestHandler_setRequestParserFunction(TI_HANDLE hRequestHandler, 483 parserRequestIEHdr_t parserRequestIEHdr) 484 { 485 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 486 487 pRequestHandler->parserRequestIEHdr = parserRequestIEHdr; 488 489 return TI_OK; 490 } 491 492 /********************************************************************************/ 493 /* Internal functions Implementation. */ 494 /********************************************************************************/ 495 496 /************************************************************************ 497 * insertMeasurementIEToQueue * 498 ************************************************************************ 499 DESCRIPTION: The function inserts measurement request of one received 500 measurement request information element. 501 502 INPUT: hRequestHandler - A Handler to the Request Handler Object. 503 frameToken - Frame token of the received frame in which 504 This current measurement request IE is included. 505 measurementObjMode - XCC or SPECTRUM_MNGMNT 506 dataLen - pointer to the data length that is left. 507 pData - pointer to the data. 508 509 OUTPUT: singelRequestLen - The Length of the request that was inserted 510 to the queue. 511 512 RETURN: TI_OK on success, TI_NOK otherwise 513 ************************************************************************/ 514 static TI_STATUS insertMeasurementIEToQueue(TI_HANDLE hRequestHandler, 515 TI_UINT16 frameToken, 516 EMeasurementMode measurementObjMode, 517 TI_UINT8 *pData, 518 TI_UINT8 *singelRequestLen) 519 { 520 requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; 521 522 TI_UINT16 HeaderLen; 523 TI_UINT8 measurementMode; 524 TI_UINT8 parallelBit; 525 TI_UINT8 enableBit; 526 TI_UINT16 measurementToken; 527 528 MeasurementRequest_t *pCurrRequest = &(pRequestHandler->reqArr[pRequestHandler->numOfWaitingRequests]); 529 530 if (pRequestHandler->parserRequestIEHdr(pData, &HeaderLen, &measurementToken) != TI_OK) 531 { 532 return TI_NOK; 533 } 534 535 pCurrRequest->frameToken = frameToken; 536 pCurrRequest->measurementToken = measurementToken; 537 538 pData += HeaderLen; 539 540 /*** Getting the Measurement Mode ***/ 541 measurementMode = *pData++; 542 543 /* getting parallel bit */ 544 parallelBit = measurementMode & 0x1; 545 546 /* getting Enable bit */ 547 enableBit = (measurementMode & 0x2)>>1; 548 549 /* checking enable bit, the current implementation does not support 550 enable bit which set to one, so there is no need to check request/report bits */ 551 if(enableBit == 1) 552 return TI_OK; 553 554 pCurrRequest->isParallel = parallelBit; 555 556 557 /* Getting the Measurement Mode */ 558 pCurrRequest->Type = (EMeasurementType)(*pData++); 559 560 /* Inserting the request that is included in the current measurement request IE. */ 561 pCurrRequest->channelNumber = *pData++; 562 563 pCurrRequest->ScanMode = (EMeasurementScanMode)(*pData++); /* IN dot11h - Spare = 0 */ 564 565 COPY_WLAN_WORD(&pCurrRequest->DurationTime, pData); 566 567 *singelRequestLen = HeaderLen + 6; 568 569 pRequestHandler->numOfWaitingRequests ++; 570 571 return TI_OK; 572 } 573 574 575 /*********************************************************************** 576 * release_module 577 *********************************************************************** 578 DESCRIPTION: Called by the destroy function or by the create function 579 (on failure). Go over the vector, for each bit that is 580 set, release the corresponding module. 581 582 INPUT: pRequestHandler - RequestHandler pointer. 583 initVec - Vector that contains a bit set for each 584 module thah had been initiualized 585 586 OUTPUT: 587 588 RETURN: TI_OK on success, TI_NOK otherwise 589 590 ************************************************************************/ 591 static void release_module(requestHandler_t *pRequestHandler, TI_UINT32 initVec) 592 { 593 594 if ( initVec & (1 << REQUEST_HANDLER_INIT_BIT) ) 595 os_memoryFree(pRequestHandler->hOs, pRequestHandler, sizeof(requestHandler_t)); 596 597 initVec = 0; 598 } 599 600 601 602 603 604 605