/* * requestHandler.c * * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name Texas Instruments nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** \file RequestHandler.c * \brief RequestHandler module interface * * \see RequestHandler.h */ /****************************************************************************************************/ /* */ /* MODULE: RequestHandler.c */ /* PURPOSE: RequestHandler module interface. */ /* This module handle the incoming measurement requests. The object handle */ /* data base that stores all measurement requests from the last incoming. */ /* This module export interface function for sceduling the next requests to be */ /* executed and stores all relevent fields for constructing a measurement report. */ /* */ /****************************************************************************************************/ #define __FILE_ID__ FILE_ID_4 #include "report.h" #include "osApi.h" #include "paramOut.h" #include "requestHandler.h" #ifdef XCC_MODULE_INCLUDED #include "XCCRMMngrParam.h" #endif /* allocation vector */ #define REQUEST_HANDLER_INIT_BIT (1) #define DOT11_MEASUREMENT_REQUEST_ELE_ID (38) /********************************************************************************/ /* Internal functions prototypes. */ /********************************************************************************/ static void release_module(requestHandler_t *pRequestHandler, TI_UINT32 initVec); static TI_STATUS insertMeasurementIEToQueue(TI_HANDLE hRequestHandler, TI_UINT16 frameToken, EMeasurementMode measurementMode, TI_UINT8 *pData, TI_UINT8 *singelRequestLen); /********************************************************************************/ /* Interface functions Implementation. */ /********************************************************************************/ /******************************************************************************** * requestHandler_create * ******************************************************************************** DESCRIPTION: RequestHandler module creation function, called by the measurement in creation phase. performs the following: - Allocate the RequestHandler handle INPUT: hOs - Handle to OS OUTPUT: RETURN: Handle to the RequestHandler module on success, NULL otherwise ************************************************************************/ TI_HANDLE requestHandler_create(TI_HANDLE hOs) { requestHandler_t *pRequestHandler = NULL; TI_UINT32 initVec = 0; /* allocating the RequestHandler object */ pRequestHandler = os_memoryAlloc(hOs,sizeof(requestHandler_t)); if (pRequestHandler == NULL) return NULL; initVec |= (1 << REQUEST_HANDLER_INIT_BIT); return(pRequestHandler); } /************************************************************************ * requestHandler_config * ************************************************************************ DESCRIPTION: RequestHandler module configuration function, called by the measurement in configuration phase. performs the following: - Reset & initiailzes local variables - Init the handles to be used by the module INPUT: hRequestHandler - RequestHandler handle. List of handles to be used by the module OUTPUT: RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS RequestHandler_config(TI_HANDLE hRequestHandler, TI_HANDLE hReport, TI_HANDLE hOs) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; /* init variables */ pRequestHandler->parserRequestIEHdr = NULL; pRequestHandler->numOfWaitingRequests = 0; /* indicating empty data base */ pRequestHandler->activeRequestID = -1; /* */ pRequestHandler->hReport = hReport; pRequestHandler->hOs = hOs; /* Clearing the Request Array , mostly due to parallel bit */ os_memoryZero(pRequestHandler->hOs, pRequestHandler->reqArr, MAX_NUM_REQ * sizeof(MeasurementRequest_t)); TRACE0(pRequestHandler->hReport, REPORT_SEVERITY_INIT, ": RequestHandler configured successfully\n"); return TI_OK; } /*********************************************************************** * requestHandler_setParam *********************************************************************** DESCRIPTION: RequestHandler set param function, called by the following: - config mgr in order to set a parameter receiving from the OS abstraction layer. - From inside the dirver INPUT: hRequestHandler - RequestHandler handle. pParam - Pointer to the parameter OUTPUT: RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_setParam(TI_HANDLE hRequestHandler, paramInfo_t *pParam) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; switch(pParam->paramType) { /* case RequestHandler_PARAM_TYPE:*/ /* break;*/ default: TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_ERROR, ": Set param, Params is not supported, %d\n\n", pParam->paramType); return PARAM_NOT_SUPPORTED; } /* return TI_OK; - unreachable */ } /*********************************************************************** * requestHandler_getParam *********************************************************************** DESCRIPTION: RequestHandler get param function, called by the following: - config mgr in order to get a parameter from the OS a bstraction layer. - From inside the dirver INPUT: hRequestHandler - RequestHandler handle. pParam - Pointer to the parameter OUTPUT: RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_getParam(TI_HANDLE hRequestHandler, paramInfo_t *pParam) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; /* TI_STATUS status;*/ switch(pParam->paramType) { /*case RequestHandler_PARAM:*/ /*return status;*/ default: TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_ERROR, ": Get param, Params is not supported, %d\n\n", pParam->paramType); return PARAM_NOT_SUPPORTED; } /* return TI_OK; - unreachable */ } /************************************************************************ * RequestHandler_destroy * ************************************************************************ DESCRIPTION: RequestHandler module destroy function, called by the config mgr in the destroy phase performs the following: - Free all memory aloocated by the module INPUT: hRequestHandler - RequestHandler handle. OUTPUT: RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_destroy(TI_HANDLE hRequestHandler) { requestHandler_t * pRequestHandler = (requestHandler_t *)hRequestHandler; TI_UINT32 initVec; if (pRequestHandler == NULL) return TI_OK; initVec = 0xFFFF; release_module(pRequestHandler, initVec); return TI_OK; } /************************************************************************ * requestHandler_insertRequests * ************************************************************************ DESCRIPTION: RequestHandler module parsing function, called by the measurement object when measuremnt request frame is received. performs the following: - Parsers the measurement request frame. - Inserts all requests into the queue. - Initializes each request according to the its frame token, measurement token, measurement type, parallel, channel number, duration time and scan mode. - The function updates the numOfWaitingRequests variable and set to zero the activeReqId. Note: The activeReqId contains the index for the first request that should be executed or to the current active request. INPUT: hRequestHandler - RequestHandler handle. measurementMode - The MEasurement Object Mode. measurementFrameReq - The New Frame request that was received. OUTPUT: RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_insertRequests(TI_HANDLE hRequestHandler, EMeasurementMode measurementMode, TMeasurementFrameRequest measurementFrameReq) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; TI_INT32 requestsLen = measurementFrameReq.requestsLen; TI_UINT8 singelRequestLen = 0; TI_UINT8 *requests = measurementFrameReq.requests; if (requestsLen < 2) { TRACE0(pRequestHandler->hReport, REPORT_SEVERITY_ERROR, ": Invalid length of the data.\n"); return TI_NOK; } /* Inserting all measurement request into the queues */ while (requestsLen > 0) { if(insertMeasurementIEToQueue(hRequestHandler, measurementFrameReq.hdr->dialogToken, measurementMode, requests, &singelRequestLen) != TI_OK ) { requestHandler_clearRequests(hRequestHandler); return TI_NOK; } requestsLen -= singelRequestLen; requests += singelRequestLen; } pRequestHandler->activeRequestID = 0; TRACE2(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Inserted into queue: activeRequestID = %d, numOfWaitingRequests = %d\n", pRequestHandler->activeRequestID, pRequestHandler->numOfWaitingRequests); return TI_OK; } /************************************************************************ * requestHandler_getNextReq * ************************************************************************ DESCRIPTION: RequestHandler module function for retrieving the requests that should be executed. performs the following: - returns pointers to one request/several requests that should be performed in parallel. Note: The function updates the numOfWaitingRequests internal varaible ONLY IF the returned request/s are going to be executed immediatly (isForActivation = TI_TRUE). INPUT: hRequestHandler - RequestHandler handle. isForActivation - A flag that indicates if the returned request/s are going to be executed immediatly OUTPUT: pRequest - pointer contains the address in which the next requests for activation should be inserted. numOfRequests - indicates how many requests should be activated in parallel. RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_getNextReq(TI_HANDLE hRequestHandler, TI_BOOL isForActivation, MeasurementRequest_t *pRequest[], TI_UINT8* numOfRequests) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; TI_UINT8 requestIndex = pRequestHandler->activeRequestID; TI_UINT8 loopIndex = 0; TRACE2(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Looking for requests. activeRequestID = %d, numOfWaitingRequests = %d\n", pRequestHandler->activeRequestID, pRequestHandler->numOfWaitingRequests); if(pRequestHandler->numOfWaitingRequests <= 0) return TI_NOK; do{ pRequest[loopIndex] = &(pRequestHandler->reqArr[requestIndex]); requestIndex++; loopIndex++; } while ( (loopIndex < pRequestHandler->numOfWaitingRequests) && (pRequestHandler->reqArr[requestIndex].isParallel) ); *numOfRequests = loopIndex; TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Found %d requests to execute in parallel.\n", loopIndex); if(isForActivation == TI_TRUE) { pRequestHandler->numOfWaitingRequests -= loopIndex; TRACE1(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Requests were queried for activation so decreasing numOfWaitingRequests to %d\n", pRequestHandler->numOfWaitingRequests); } return TI_OK; } /************************************************************************ * requestHandler_getCurrentExpiredReq * ************************************************************************ DESCRIPTION: RequestHandler module function for retrieving the request that finished its execution. performs the following: - returns pointers to the request that finished its execution in. INPUT: hRequestHandler - RequestHandler handle. requestIndex - Index of request in the queue OUTPUT: pRequest - pointer contains the addresse of the request that finished its execution. RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_getCurrentExpiredReq(TI_HANDLE hRequestHandler, TI_UINT8 requestIndex, MeasurementRequest_t **pRequest) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; requestIndex += pRequestHandler->activeRequestID; *pRequest = &(pRequestHandler->reqArr[requestIndex]); return TI_OK; } /************************************************************************ * requestHandler_clearRequests * ************************************************************************ DESCRIPTION: RequestHandler module function for cleaning the data base. performs the following: - Clears all requests from the queue by setting the activeReqId and numOfWaitingRequests variables. Note: The function does not actually zero all queue variables or destroy the object. INPUT: hRequestHandler - RequestHandler handle. OUTPUT: None RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_clearRequests(TI_HANDLE hRequestHandler) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; pRequestHandler->numOfWaitingRequests = 0; pRequestHandler->activeRequestID = -1; /* Clearing the Request Array , mostly due to parallel bit */ os_memoryZero(pRequestHandler->hOs,pRequestHandler->reqArr, MAX_NUM_REQ * sizeof(MeasurementRequest_t)); TRACE2(pRequestHandler->hReport, REPORT_SEVERITY_INFORMATION, ": Request queue has been cleared. activeRequestID = %d, numOfWaitingRequests = %d\n", pRequestHandler->activeRequestID, pRequestHandler->numOfWaitingRequests); return TI_OK; } /************************************************************************ * requestHandler_getFrameToken * ************************************************************************ DESCRIPTION: RequestHandler module function for getting the token of the frame that is now being processed. INPUT: hRequestHandler - RequestHandler handle. OUTPUT: frameToken RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_getFrameToken(TI_HANDLE hRequestHandler,TI_UINT16 *frameToken ) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; if(pRequestHandler->activeRequestID == -1) return TI_NOK; *frameToken = pRequestHandler->reqArr[0].frameToken; return TI_OK; } /************************************************************************ * requestHandler_setRequestParserFunction * ************************************************************************ DESCRIPTION: RequestHandler module function for setting the function that parasers a request IE. INPUT: hRequestHandler - RequestHandler handle. parserRequestIE - A pointer to the function. OUTPUT: RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ TI_STATUS requestHandler_setRequestParserFunction(TI_HANDLE hRequestHandler, parserRequestIEHdr_t parserRequestIEHdr) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; pRequestHandler->parserRequestIEHdr = parserRequestIEHdr; return TI_OK; } /********************************************************************************/ /* Internal functions Implementation. */ /********************************************************************************/ /************************************************************************ * insertMeasurementIEToQueue * ************************************************************************ DESCRIPTION: The function inserts measurement request of one received measurement request information element. INPUT: hRequestHandler - A Handler to the Request Handler Object. frameToken - Frame token of the received frame in which This current measurement request IE is included. measurementObjMode - XCC or SPECTRUM_MNGMNT dataLen - pointer to the data length that is left. pData - pointer to the data. OUTPUT: singelRequestLen - The Length of the request that was inserted to the queue. RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ static TI_STATUS insertMeasurementIEToQueue(TI_HANDLE hRequestHandler, TI_UINT16 frameToken, EMeasurementMode measurementObjMode, TI_UINT8 *pData, TI_UINT8 *singelRequestLen) { requestHandler_t *pRequestHandler = (requestHandler_t *)hRequestHandler; TI_UINT16 HeaderLen; TI_UINT8 measurementMode; TI_UINT8 parallelBit; TI_UINT8 enableBit; TI_UINT16 measurementToken; MeasurementRequest_t *pCurrRequest = &(pRequestHandler->reqArr[pRequestHandler->numOfWaitingRequests]); if (pRequestHandler->parserRequestIEHdr(pData, &HeaderLen, &measurementToken) != TI_OK) { return TI_NOK; } pCurrRequest->frameToken = frameToken; pCurrRequest->measurementToken = measurementToken; pData += HeaderLen; /*** Getting the Measurement Mode ***/ measurementMode = *pData++; /* getting parallel bit */ parallelBit = measurementMode & 0x1; /* getting Enable bit */ enableBit = (measurementMode & 0x2)>>1; /* checking enable bit, the current implementation does not support enable bit which set to one, so there is no need to check request/report bits */ if(enableBit == 1) return TI_OK; pCurrRequest->isParallel = parallelBit; /* Getting the Measurement Mode */ pCurrRequest->Type = (EMeasurementType)(*pData++); /* Inserting the request that is included in the current measurement request IE. */ pCurrRequest->channelNumber = *pData++; pCurrRequest->ScanMode = (EMeasurementScanMode)(*pData++); /* IN dot11h - Spare = 0 */ COPY_WLAN_WORD(&pCurrRequest->DurationTime, pData); *singelRequestLen = HeaderLen + 6; pRequestHandler->numOfWaitingRequests ++; return TI_OK; } /*********************************************************************** * release_module *********************************************************************** DESCRIPTION: Called by the destroy function or by the create function (on failure). Go over the vector, for each bit that is set, release the corresponding module. INPUT: pRequestHandler - RequestHandler pointer. initVec - Vector that contains a bit set for each module thah had been initiualized OUTPUT: RETURN: TI_OK on success, TI_NOK otherwise ************************************************************************/ static void release_module(requestHandler_t *pRequestHandler, TI_UINT32 initVec) { if ( initVec & (1 << REQUEST_HANDLER_INIT_BIT) ) os_memoryFree(pRequestHandler->hOs, pRequestHandler, sizeof(requestHandler_t)); initVec = 0; }