• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * GeneralUtil.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 #define __FILE_ID__  FILE_ID_52
35 #include "GeneralUtilApi.h"
36 #include "GeneralUtil.h"
37 #include "report.h"
38 #include "osApi.h"
39 
40 /*************************************************************************
41 *                        LIST OBJ                                        *
42 **************************************************************************
43 **************************************************************************
44 *
45  *	The list object mange the allocation and deallocation of generic element.
46  *  The obj create a list of N generic elements and fined a free entry for the Alloc process.
47  *  And free the entry for dealloc.
48  *
49  *
50 ***************************************************************************/
51 
52 
53 
54 /*************************************************************************
55 *                        List_create                                     *
56 **************************************************************************
57 * DESCRIPTION:	This function initializes the List data module.
58 *
59 * INPUT:		hOs - handle to Os Abstraction Layer
60 *				MaxNumOfElements - the number of elemnts that will be Managed by the list
61                 ContainerSize - The size of the basic data type managed by the list
62 * OUTPUT:
63 *
64 *
65 * RETURN:		Handle to the allocated List data control block
66 ************************************************************************/
List_create(TI_HANDLE hOs,int MaxNumOfElements,int ContainerSize)67 TI_HANDLE List_create(TI_HANDLE hOs,int MaxNumOfElements,int ContainerSize)
68 {
69     int index;
70     List_t *List;
71 
72 	if( hOs  == NULL )
73 	{
74 	    WLAN_OS_REPORT(("FATAL ERROR:List_create(): OS handle Error - Aborting\n"));
75 		return NULL;
76 	}
77 
78 	/* alocate List block */
79 	List = (List_t*)os_memoryAlloc(hOs, sizeof(List_t));
80 	if(List == NULL)
81 	    return NULL;
82 
83 
84     /* alocate the List of Elements */
85     List->ElementList =(ListElement_t*)os_memoryAlloc(hOs, (sizeof(ListElement_t)*MaxNumOfElements));
86 	if(List->ElementList == NULL)
87     {
88         os_memoryFree(List->hOs, List, sizeof(List_t));
89         return NULL;
90     }
91 
92     /*Allocate the Data containers*/
93     for(index=0;index<MaxNumOfElements;index++)
94     {
95         List->ElementList[index].Container = os_memoryAlloc(hOs,ContainerSize);
96         if(List->ElementList[index].Container == NULL)
97             break;
98         List->ElementList[index].Inuse = TI_FALSE;
99     }
100     if (index != MaxNumOfElements)  /*Not all the list element was allocated and*/
101     {                                /*therefore we free the entire list and rap it up*/
102        index--;
103        for(;index>=0;index--)
104             os_memoryFree(hOs,List->ElementList[index].Container,ContainerSize);
105        os_memoryFree(List->hOs, List->ElementList, (sizeof(ListElement_t)*MaxNumOfElements));
106        os_memoryFree(List->hOs,List,(sizeof(List_t)));
107        return NULL;
108 
109     }
110 
111     List->MaxNumOfElements = MaxNumOfElements;
112     List->ContainerSize = ContainerSize;
113 	return((TI_HANDLE)List);
114 }
115 
116 
117 /***************************************************************************
118 *							List_Destroy				                   *
119 ****************************************************************************
120 * DESCRIPTION:	This function unload the List data module.
121 *
122 * INPUTS:		hCtrlData - the object
123 *
124 * OUTPUT:
125 *
126 * RETURNS:		TI_OK - Unload succesfull
127 *				TI_NOK - Unload unsuccesfull
128 ***************************************************************************/
List_Destroy(TI_HANDLE hList)129 TI_STATUS List_Destroy(TI_HANDLE hList)
130 {
131     List_t* List = (List_t*)hList;
132     int index;
133 
134     if(List!=NULL)
135     {
136   	    if(List->ElementList != NULL)
137         {
138            for(index=0;index<List->MaxNumOfElements;index++)
139              os_memoryFree(List->hOs,List->ElementList[index].Container,List->ContainerSize);
140 
141            os_memoryFree(List->hOs,List->ElementList,(sizeof(ListElement_t)*List->MaxNumOfElements));
142         }
143         os_memoryFree(List->hOs, List, sizeof(List_t));
144     }
145     return TI_OK;
146 }
147 
148 /***************************************************************************
149 *							List_AllocElement   		                   *
150 ****************************************************************************
151 *
152 *
153 *    Fined an empty entry in the list and returns
154 *    a pointer to a memory that contains an element that not in use.
155 *
156 *    Note in multi Task environment we need to add semaphore to protect the
157 *    Function.
158 *
159 ***************************************************************************/
List_AllocElement(TI_HANDLE hList)160 TI_HANDLE List_AllocElement(TI_HANDLE hList)
161 {
162     List_t* List = (List_t*)hList;
163     int index;
164 
165     if (List == NULL)
166         return NULL;
167 
168     for(index=0;index<List->MaxNumOfElements;index++)
169     {
170         if(!(List->ElementList[index].Inuse))
171         {
172            List->ElementList[index].Inuse = TI_TRUE;
173            os_memoryZero(List->hOs,List->ElementList[index].Container,List->ContainerSize);
174            return((TI_HANDLE)List->ElementList[index].Container);
175         }
176     }
177     return NULL;
178 }
179 
180 
181 /***************************************************************************
182 *							List_FreeElement				               *
183 ****************************************************************************
184 *
185 *   Marks the entry that was allocated as free.
186 *   An alloc process can use this space.
187 *
188 *
189 *
190 ***************************************************************************/
List_FreeElement(TI_HANDLE hList,TI_HANDLE Container)191 TI_STATUS List_FreeElement(TI_HANDLE hList,TI_HANDLE Container)
192 {
193     List_t* List = (List_t*)hList;
194     int index;
195 
196     if (List == NULL)
197         return TI_NOK;
198 
199     for(index=0;index<List->MaxNumOfElements;index++)
200     {
201         if(List->ElementList[index].Container == Container)
202         {
203             if(!List->ElementList[index].Inuse)
204                 return TI_NOK;  /*double free not legal*/
205             List->ElementList[index].Inuse = TI_FALSE;
206             return TI_OK;
207         }
208     }
209     return TI_NOK;
210 }
211 
212 
213 /***************************************************************************
214 *							List_GetFirst				                   *
215 ****************************************************************************
216 *
217 *  For purposes of searching the element list (going over all the element in the list)
218 *  Get first is used to reset an index for the search.
219 *  This function is work combined with GetNext.
220 *
221 *   Note this function can't be used in multi Task environment.
222 *
223 ***************************************************************************/
List_GetFirst(TI_HANDLE hList)224 TI_HANDLE List_GetFirst(TI_HANDLE hList)
225 {
226     List_t* List = (List_t*)hList;
227     int index;
228 
229     if (List == NULL)
230         return NULL;
231 
232     for(index=0;index<List->MaxNumOfElements;index++)
233     {
234         if(List->ElementList[index].Inuse)
235         {
236            List->CurrentIndex = index;
237            return (List->ElementList[index].Container);
238         }
239     }
240     return NULL;
241 }
242 
243 
244 /***************************************************************************
245 *							List_GetNext				                   *
246 ****************************************************************************
247 *
248 *  This function returns the next element in the list till null
249 *  that indicate that there no more element or we have reached the end of the list.
250 *  This function is work combined with GetFirst.
251 *
252 *  Note this function can't be used in multi Task environment.
253 *
254 ***************************************************************************/
List_GetNext(TI_HANDLE hList)255 TI_HANDLE List_GetNext(TI_HANDLE hList)
256 {
257     List_t* List = (List_t*)hList;
258     int index;
259 
260     if (List == NULL)
261         return NULL;
262 
263     /* the code works fine even if the elment is the last*/
264     for(index=List->CurrentIndex+1;index<List->MaxNumOfElements;index++)
265     {
266         if(List->ElementList[index].Inuse)
267         {
268            List->CurrentIndex = index;
269            return (List->ElementList[index].Container);
270 
271         }
272     }
273     return NULL;
274 }
275 
276 
277 
278 
279 /***************************************************************************
280 *							DISTRIBUTOR MANAGER				               *
281 ****************************************************************************
282 ***************************************************************************
283 *
284  *    	PURPOSE:The distributor manger supplies
285  *       1. Register mechanism that has a callback function and the condition
286  *       (bit mask format) that will be used to distinguish if to call this callback.
287  *       2. Event occurrence function that go over all the registered function and compare
288  *       the input mask to the callback mask condition.
289  *
290  *
291  *
292 ***************************************************************************/
293 
294 
295 
296 /***************************************************************************
297 *							DistributorMgr_Create		                   *
298 ****************************************************************************
299 *
300 ***************************************************************************/
DistributorMgr_Create(TI_HANDLE hOs,int MaxNotifReqElment)301 TI_HANDLE DistributorMgr_Create(TI_HANDLE hOs , int MaxNotifReqElment)
302 {
303     DistributorMgr_t *DistributorMgr;
304 
305 	DistributorMgr = (DistributorMgr_t*)os_memoryAlloc(hOs, sizeof(DistributorMgr_t));
306 	if(DistributorMgr == NULL)
307         return NULL;
308     DistributorMgr->hOs = hOs;
309     DistributorMgr->DistributionList = (List_t*)List_create(hOs,MaxNotifReqElment,sizeof(NotifReqElment_t));
310     if (DistributorMgr->DistributionList == NULL)
311     {
312         os_memoryFree(hOs, DistributorMgr, sizeof(DistributorMgr_t));
313         return NULL;
314     }
315     return (TI_HANDLE)DistributorMgr;
316 }
317 
318 
319 
320 /************************************************************************/
321 /*               DistributorMgr_Destroy                                 */
322 /************************************************************************/
DistributorMgr_Destroy(TI_HANDLE hDistributorMgr)323 TI_STATUS DistributorMgr_Destroy(TI_HANDLE hDistributorMgr)
324 {
325     DistributorMgr_t *DistributorMgr =(DistributorMgr_t*)hDistributorMgr;
326 
327      if(DistributorMgr == NULL)
328         return TI_NOK;
329 
330     List_Destroy(DistributorMgr->DistributionList);
331 
332     os_memoryFree(DistributorMgr->hOs, hDistributorMgr, sizeof(DistributorMgr_t));
333 
334     return TI_OK;
335 
336 }
337 
338 /***************************************************************************
339 *						DistributorMgr_Reg				                   *
340 ****************************************************************************
341 *
342 *  Use by the client to register a callback function
343 *  with the mask condition that will trigger the call.
344 *
345 * input
346 *    TI_UINT16 Mask
347 *    TI_HANDLE CallBack
348 *    HANDLE Context
349 *    TI_UINT32 Cookie
350 *
351 *
352 ***************************************************************************/
DistributorMgr_Reg(TI_HANDLE hDistributorMgr,TI_UINT16 Mask,TI_HANDLE CallBack,TI_HANDLE Context,TI_UINT32 Cookie)353 TI_HANDLE DistributorMgr_Reg(TI_HANDLE hDistributorMgr,TI_UINT16 Mask,TI_HANDLE CallBack,
354                              TI_HANDLE Context,TI_UINT32 Cookie)
355 {
356     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
357     NotifReqElment_t *NotifReqElment;
358 
359    	if(DistributorMgr == NULL)
360         return NULL;
361 
362     NotifReqElment = (NotifReqElment_t*)List_AllocElement(DistributorMgr->DistributionList);
363     if (NotifReqElment == NULL)
364 		return NULL  ;
365 
366     NotifReqElment->CallBack = (GeneralEventCall_t)CallBack;
367     NotifReqElment->Mask = Mask;
368     NotifReqElment->Context = Context;
369     NotifReqElment->Cookie = Cookie;
370     NotifReqElment->HaltReq = TI_FALSE;
371     return (TI_HANDLE)NotifReqElment;
372 }
373 
374 
375 /***************************************************************************
376 *						DistributorMgr_ReReg				               *
377 ****************************************************************************
378 *
379 ***************************************************************************/
DistributorMgr_ReReg(TI_HANDLE hDistributorMgr,TI_HANDLE ReqElmenth,TI_UINT16 Mask,TI_HANDLE CallBack,TI_HANDLE Context,TI_UINT32 Cookie)380 TI_STATUS DistributorMgr_ReReg(TI_HANDLE hDistributorMgr,TI_HANDLE ReqElmenth ,TI_UINT16 Mask,TI_HANDLE CallBack,TI_HANDLE Context,TI_UINT32 Cookie)
381 {
382     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
383     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
384 
385    	if(DistributorMgr == NULL)
386         return TI_NOK;
387 
388     if (NotifReqElment == NULL)
389 		return TI_NOK;
390 
391     NotifReqElment->CallBack = (GeneralEventCall_t)CallBack;
392     NotifReqElment->Mask = Mask;
393     NotifReqElment->Context = Context;
394     NotifReqElment->Cookie = Cookie;
395     return TI_OK;
396 }
397 
398 
399 /***************************************************************************
400 *						DistributorMgr_AddToMask			               *
401 ****************************************************************************
402 *
403 * Use this function to add mask bit to the bit mask condition that triggers the Callback
404 *
405 *
406 ***************************************************************************/
DistributorMgr_AddToMask(TI_HANDLE hDistributorMgr,TI_HANDLE ReqElmenth,TI_UINT16 Mask)407 TI_STATUS DistributorMgr_AddToMask(TI_HANDLE hDistributorMgr,TI_HANDLE ReqElmenth,TI_UINT16 Mask)
408 {
409     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
410     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
411 
412     if(DistributorMgr == NULL)
413         return TI_NOK;
414 
415     if (NotifReqElment == NULL)
416 		return TI_NOK;
417 
418     NotifReqElment->Mask |= Mask;
419     return TI_OK;
420 }
421 
422 
423 /***************************************************************************
424 *						DistributorMgr_HaltNotif			               *
425 ****************************************************************************
426 *
427 * Use this function to add mask bit to the bit mask condition that triggers the Callback
428 *
429 *
430 ***************************************************************************/
DistributorMgr_HaltNotif(TI_HANDLE ReqElmenth)431 void DistributorMgr_HaltNotif(TI_HANDLE ReqElmenth)
432 {
433     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
434 
435     if (NotifReqElment == NULL)
436 	    return;
437 
438     NotifReqElment->HaltReq = TI_TRUE;
439 
440 }
441 
442 
443 /***************************************************************************
444 *						DistributorMgr_RestartNotif			               *
445 ****************************************************************************
446 *
447 * Use this function to add mask bit to the bit mask condition that triggers the Callback
448 *
449 *
450 ***************************************************************************/
DistributorMgr_RestartNotif(TI_HANDLE ReqElmenth)451 void DistributorMgr_RestartNotif(TI_HANDLE ReqElmenth)
452 {
453     NotifReqElment_t *NotifReqElment = (NotifReqElment_t*)ReqElmenth;
454 
455     if (NotifReqElment == NULL)
456 	    return;
457 
458     NotifReqElment->HaltReq = TI_FALSE;
459 
460 }
461 /***************************************************************************
462 *						DistributorMgr_UnReg				               *
463 ****************************************************************************
464 *
465 *
466 ***************************************************************************/
DistributorMgr_UnReg(TI_HANDLE hDistributorMgr,TI_HANDLE RegEventHandle)467 TI_STATUS DistributorMgr_UnReg(TI_HANDLE hDistributorMgr,TI_HANDLE RegEventHandle)
468 {
469     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
470 
471   	if(DistributorMgr == NULL)
472         return TI_NOK;
473 
474     return List_FreeElement(DistributorMgr->DistributionList, RegEventHandle);
475 }
476 
477 
478 /***************************************************************************
479 *						DistributorMgr_EventCall		                   *
480 ****************************************************************************
481 *
482 * When the client needs to invoke the callback calls function that corresponds
483 * to a specific event mask it will call this function with the desired mask.
484 * And event count that can be used to aggregate the events.
485 * that way calling this function not for every event
486 *
487 ***************************************************************************/
DistributorMgr_EventCall(TI_HANDLE hDistributorMgr,TI_UINT16 Mask,int EventCount)488 void DistributorMgr_EventCall(TI_HANDLE hDistributorMgr,TI_UINT16 Mask,int EventCount)
489 {
490     DistributorMgr_t *DistributorMgr = (DistributorMgr_t*)hDistributorMgr;
491     NotifReqElment_t *NotifReqElment;
492 
493     if(DistributorMgr == NULL)
494         return;
495 
496     NotifReqElment = (NotifReqElment_t*)List_GetFirst(DistributorMgr->DistributionList);
497 
498     while(NotifReqElment)
499     {
500         if((NotifReqElment->Mask & Mask) && !(NotifReqElment->HaltReq))
501         {
502             NotifReqElment->CallBack(NotifReqElment->Context,EventCount,Mask,
503                                      NotifReqElment->Cookie);
504         }
505         NotifReqElment = (NotifReqElment_t*)List_GetNext(DistributorMgr->DistributionList);
506     }
507 }
508 
509 
510 
511 /*******************************************************/
512