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