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