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/********************************************************************************/ 68static void release_module(requestHandler_t *pRequestHandler, TI_UINT32 initVec); 69 70static 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 ******************************************************************************** 84DESCRIPTION: RequestHandler module creation function, called by the measurement in 85 creation phase. performs the following: 86 87 - Allocate the RequestHandler handle 88 89INPUT: hOs - Handle to OS 90 91OUTPUT: 92 93RETURN: Handle to the RequestHandler module on success, NULL otherwise 94************************************************************************/ 95TI_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 ************************************************************************ 115DESCRIPTION: 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 120INPUT: hRequestHandler - RequestHandler handle. 121 List of handles to be used by the module 122 123OUTPUT: 124 125RETURN: TI_OK on success, TI_NOK otherwise 126 127************************************************************************/ 128TI_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 145TRACE0(pRequestHandler->hReport, REPORT_SEVERITY_INIT, ": RequestHandler configured successfully\n"); 146 147 return TI_OK; 148} 149 150/*********************************************************************** 151 * requestHandler_setParam 152 *********************************************************************** 153DESCRIPTION: 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 158INPUT: hRequestHandler - RequestHandler handle. 159 pParam - Pointer to the parameter 160 161OUTPUT: 162 163RETURN: TI_OK on success, TI_NOK otherwise 164 165************************************************************************/ 166TI_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: 178TRACE1(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 *********************************************************************** 188DESCRIPTION: 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 193INPUT: hRequestHandler - RequestHandler handle. 194 pParam - Pointer to the parameter 195 196OUTPUT: 197 198RETURN: TI_OK on success, TI_NOK otherwise 199 200************************************************************************/ 201TI_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: 215TRACE1(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 ************************************************************************ 225DESCRIPTION: 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 230INPUT: hRequestHandler - RequestHandler handle. 231 232OUTPUT: 233 234RETURN: TI_OK on success, TI_NOK otherwise 235 236************************************************************************/ 237TI_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 ************************************************************************ 254DESCRIPTION: 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 268INPUT: hRequestHandler - RequestHandler handle. 269 measurementMode - The MEasurement Object Mode. 270 measurementFrameReq - The New Frame request that was received. 271 272OUTPUT: 273 274RETURN: TI_OK on success, TI_NOK otherwise 275************************************************************************/ 276TI_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 312TRACE2(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 ************************************************************************ 320DESCRIPTION: 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 329INPUT: hRequestHandler - RequestHandler handle. 330 331 isForActivation - A flag that indicates if the returned 332 request/s are going to be executed immediatly 333 334OUTPUT: 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 340RETURN: TI_OK on success, TI_NOK otherwise 341************************************************************************/ 342TI_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 351TRACE2(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 366TRACE1(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 372TRACE1(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 ************************************************************************ 381DESCRIPTION: 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 387INPUT: hRequestHandler - RequestHandler handle. 388 requestIndex - Index of request in the queue 389 390OUTPUT: pRequest - pointer contains the addresse of the 391 request that finished its execution. 392 393RETURN: TI_OK on success, TI_NOK otherwise 394************************************************************************/ 395TI_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 ************************************************************************ 412DESCRIPTION: 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 419INPUT: hRequestHandler - RequestHandler handle. 420 421OUTPUT: None 422 423RETURN: TI_OK on success, TI_NOK otherwise 424************************************************************************/ 425TI_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 436TRACE2(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 ************************************************************************ 446DESCRIPTION: RequestHandler module function for getting the token of the 447 frame that is now being processed. 448 449INPUT: hRequestHandler - RequestHandler handle. 450 451 452OUTPUT: frameToken 453 454RETURN: TI_OK on success, TI_NOK otherwise 455************************************************************************/ 456TI_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 ************************************************************************ 471DESCRIPTION: RequestHandler module function for setting the function that 472 parasers a request IE. 473 474INPUT: hRequestHandler - RequestHandler handle. 475 parserRequestIE - A pointer to the function. 476 477 478OUTPUT: 479 480RETURN: TI_OK on success, TI_NOK otherwise 481************************************************************************/ 482TI_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 ************************************************************************ 499DESCRIPTION: The function inserts measurement request of one received 500 measurement request information element. 501 502INPUT: 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 509OUTPUT: singelRequestLen - The Length of the request that was inserted 510 to the queue. 511 512RETURN: TI_OK on success, TI_NOK otherwise 513************************************************************************/ 514static 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 durationTime; 527 TI_UINT16 measurementToken; 528 529 MeasurementRequest_t *pCurrRequest = &(pRequestHandler->reqArr[pRequestHandler->numOfWaitingRequests]); 530 531 if (pRequestHandler->parserRequestIEHdr(pData, &HeaderLen, &measurementToken) != TI_OK) 532 { 533 return TI_NOK; 534 } 535 536 pCurrRequest->frameToken = frameToken; 537 pCurrRequest->measurementToken = measurementToken; 538 539 pData += HeaderLen; 540 541 /*** Getting the Measurement Mode ***/ 542 measurementMode = *pData++; 543 544 /* getting parallel bit */ 545 parallelBit = measurementMode & 0x1; 546 547 /* getting Enable bit */ 548 enableBit = (measurementMode & 0x2)>>1; 549 550 /* checking enable bit, the current implementation does not support 551 enable bit which set to one, so there is no need to check request/report bits */ 552 if(enableBit == 1) 553 return TI_OK; 554 555 pCurrRequest->isParallel = parallelBit; 556 557 558 /* Getting the Measurement Mode */ 559 pCurrRequest->Type = (EMeasurementType)(*pData++); 560 561 /* Inserting the request that is included in the current measurement request IE. */ 562 pCurrRequest->channelNumber = *pData++; 563 564 pCurrRequest->ScanMode = (EMeasurementScanMode)(*pData++); /* IN dot11h - Spare = 0 */ 565 566 os_memoryCopy(pRequestHandler->hOs, &durationTime, pData, 2); 567 durationTime = ENDIAN_HANDLE_WORD(durationTime); 568 pCurrRequest->DurationTime = durationTime; 569 570 *singelRequestLen = HeaderLen + 6; 571 572 pRequestHandler->numOfWaitingRequests ++; 573 574 return TI_OK; 575} 576 577 578/*********************************************************************** 579 * release_module 580 *********************************************************************** 581DESCRIPTION: Called by the destroy function or by the create function 582 (on failure). Go over the vector, for each bit that is 583 set, release the corresponding module. 584 585INPUT: pRequestHandler - RequestHandler pointer. 586 initVec - Vector that contains a bit set for each 587 module thah had been initiualized 588 589OUTPUT: 590 591RETURN: TI_OK on success, TI_NOK otherwise 592 593************************************************************************/ 594static void release_module(requestHandler_t *pRequestHandler, TI_UINT32 initVec) 595{ 596 597 if ( initVec & (1 << REQUEST_HANDLER_INIT_BIT) ) 598 os_memoryFree(pRequestHandler->hOs, pRequestHandler, sizeof(requestHandler_t)); 599 600 initVec = 0; 601} 602 603 604 605 606 607 608