1/*
2 * TrafficMonitor.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/***************************************************************************/
35/*                                                                         */
36/*              MODULE:         TrafficMonitor.c                           */
37/*              PURPOSE:        Traffic Monitor                            */
38/*                                                                         */
39/***************************************************************************/
40#define __FILE_ID__  FILE_ID_55
41#include "TrafficMonitorAPI.h"
42#include "TrafficMonitor.h"
43#include "DataCtrl_Api.h"
44#include "osApi.h"
45#include "report.h"
46#include "timer.h"
47#include "DrvMainModules.h"
48
49
50/* Percentage of max down events test interval to use in our "traffic down" timer */
51#define MIN_INTERVAL_PERCENT 50
52
53/*#define TRAFF_TEST*/
54#ifdef TRAFF_TEST
55/*for TEST Function*/
56TI_HANDLE TestTrafficMonitor;
57TI_HANDLE TestEventTimer;
58TI_HANDLE Alert1;
59TI_HANDLE Alert2;
60TI_HANDLE Alert3;
61TI_HANDLE Alert4;
62void PrintElertStus();
63void TestEventFunc (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured);
64#endif
65
66
67/************************************************************************/
68/*           Function prototype                                         */
69/************************************************************************/
70static void TimerMonitor_TimeOut (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured);
71static void TrafficMonitor_updateBW(BandWidth_t *pBandWidth, TI_UINT32 uCurrentTS);
72static TI_UINT32 TrafficMonitor_calcBW(BandWidth_t *pBandWidth, TI_UINT32 uCurrentTS);
73static TI_BOOL isThresholdDown(TrafficAlertElement_t *AlertElement,TI_UINT32 CurrentTime);
74static TI_BOOL isThresholdUp(TrafficAlertElement_t *AlertElement , TI_UINT32 CurrentTime);
75static void SimpleByteAggregation(TI_HANDLE TraffElem,int Count);
76static void SimpleFrameAggregation(TI_HANDLE TraffElem,int Count);
77static TI_HANDLE TrafficMonitor_ExitFunc(TrafficMonitor_t *TrafficMonitor,TI_HANDLE hOs);
78static TI_STATUS FindRstElemEntryIndex (TrafficMonitor_t *TrafficMonitor,TrafficAlertElement_t  *TrafficAlertElement,int *Index);
79static TI_STATUS TrafficMonitor_SetMask(TrafficMonitor_t *TrafficMonitor,TrafficAlertElement_t *TrafficAlertElement,TraffEvntOptNum_t MaskType);
80
81static void TrafficMonitor_UpdateDownTrafficTimerState (TI_HANDLE hTrafficMonitor);
82static void TrafficMonitor_ChangeDownTimerStatus (TI_HANDLE hTrafficMonitor, TI_UINT32 downEventsFound, TI_UINT32 minIntervalTime);
83
84/************************************************************************/
85/*                      TrafficMonitor_create                           */
86/************************************************************************/
87TI_HANDLE TrafficMonitor_create(TI_HANDLE hOs)
88{
89    TrafficMonitor_t *TrafficMonitor;
90
91    /* Allocate the data structure TrafficMonitor*/
92        TrafficMonitor = (TrafficMonitor_t*)os_memoryAlloc(hOs, sizeof(TrafficMonitor_t));
93        if (TrafficMonitor == NULL)
94        return NULL;
95
96    os_memoryZero(hOs,TrafficMonitor,sizeof(TrafficMonitor_t));
97
98#ifdef TRAFF_TEST
99	TestEventTimer = NULL;
100#endif
101
102    TrafficMonitor->hOs = hOs;
103
104    /*Creates the list that will hold all the registered alert requests*/
105    TrafficMonitor->NotificationRegList = List_create(hOs,MAX_MONITORED_REQ,sizeof(TrafficAlertElement_t));
106    if (TrafficMonitor->NotificationRegList == NULL)
107        return TrafficMonitor_ExitFunc(TrafficMonitor,hOs);
108
109    return (TI_HANDLE)TrafficMonitor;
110}
111
112
113/************************************************************************/
114/*                    TrafficMonitor_ExitFunc                           */
115/************************************************************************/
116static TI_HANDLE TrafficMonitor_ExitFunc(TrafficMonitor_t *TrafficMonitor,TI_HANDLE hOs)
117{
118    if (TrafficMonitor)
119    {
120        if(TrafficMonitor->hTrafficMonTimer)
121        {
122            tmr_DestroyTimer (TrafficMonitor->hTrafficMonTimer);
123        }
124        os_memoryFree(hOs, TrafficMonitor, sizeof(TrafficMonitor_t));
125    }
126    return NULL;
127}
128
129
130
131/************************************************************************/
132/*                    TrafficMonitor_config                             */
133/************************************************************************/
134void TrafficMonitor_Init (TStadHandlesList *pStadHandles, TI_UINT32 BWwindowMs)
135{
136    TrafficMonitor_t *TrafficMonitor = (TrafficMonitor_t *)(pStadHandles->hTrafficMon);
137    TI_UINT32 uCurrTS = os_timeStampMs (TrafficMonitor->hOs);
138
139    /* Create the base threshold timer that will serve all the down thresholds*/
140    TrafficMonitor->hTrafficMonTimer = tmr_CreateTimer (pStadHandles->hTimer);
141
142    TrafficMonitor->Active = TI_FALSE;
143
144    TrafficMonitor->hRxData = pStadHandles->hRxData;
145    TrafficMonitor->hTxCtrl = pStadHandles->hTxCtrl;
146    TrafficMonitor->hTimer  = pStadHandles->hTimer;
147
148        /*Init All the bandwidth elements in the system */
149	os_memoryZero(TrafficMonitor->hOs,&TrafficMonitor->DirectTxFrameBW,sizeof(BandWidth_t));
150	os_memoryZero(TrafficMonitor->hOs,&TrafficMonitor->DirectRxFrameBW,sizeof(BandWidth_t));
151	TrafficMonitor->DirectRxFrameBW.auFirstEventsTS[0] = uCurrTS;
152	TrafficMonitor->DirectTxFrameBW.auFirstEventsTS[0] = uCurrTS;
153
154    /*Registering to the RX module for notification.*/
155    TrafficMonitor->RxRegReqHandle = rxData_RegNotif (pStadHandles->hRxData,
156                                                      DIRECTED_FRAMES_RECV,
157                                                      TrafficMonitor_Event,
158                                                      TrafficMonitor,
159                                                      RX_TRAFF_MODULE);
160
161    /*Registering to the TX module for notification .*/
162    TrafficMonitor->TxRegReqHandle = txCtrlParams_RegNotif (pStadHandles->hTxCtrl,
163                                                            DIRECTED_FRAMES_XFER,
164                                                            TrafficMonitor_Event,
165                                                            TrafficMonitor,
166                                                            TX_TRAFF_MODULE);
167
168    TrafficMonitor->DownTimerEnabled = TI_FALSE;
169    TrafficMonitor->trafficDownTestIntervalPercent = MIN_INTERVAL_PERCENT;
170
171#ifdef TRAFF_TEST
172    TestTrafficMonitor = TrafficMonitor;
173    TestEventTimer = tmr_CreateTimer (pStadHandles->hTimer);
174    tmr_StartTimer (TestEventTimer, TestEventFunc, (TI_HANDLE)TrafficMonitor, 5000, TI_TRUE);
175#endif
176}
177
178/************************************************************************/
179/*                TrafficMonitor_Start                                  */
180/************************************************************************/
181TI_STATUS TrafficMonitor_Start(TI_HANDLE hTrafficMonitor)
182{
183    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
184    TrafficAlertElement_t *AlertElement;
185    TI_UINT32 CurentTime;
186
187
188    if(TrafficMonitor == NULL)
189        return TI_NOK;
190
191    /*starts the bandwidth TIMER*/
192    if(!TrafficMonitor->Active) /*To prevent double call to timer start*/
193    {
194        TrafficMonitor_UpdateDownTrafficTimerState (TrafficMonitor);
195    }
196
197    AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
198    CurentTime = os_timeStampMs(TrafficMonitor->hOs);
199
200    /* go over all the Down elements and reload the timer*/
201    while(AlertElement)
202    {
203        if(AlertElement->CurrentState != ALERT_WAIT_FOR_RESET)
204        {
205            AlertElement->EventCounter = 0;
206            AlertElement->TimeOut = AlertElement->TimeIntervalMs + CurentTime;
207        }
208        AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
209    }
210    TrafficMonitor->Active = TI_TRUE;
211
212    return TI_OK;
213}
214
215
216
217/************************************************************************/
218/*              TrafficMonitor_Stop                                     */
219/************************************************************************/
220TI_STATUS TrafficMonitor_Stop(TI_HANDLE hTrafficMonitor)
221{
222    TrafficMonitor_t       *pTrafficMonitor = (TrafficMonitor_t*)hTrafficMonitor;
223    TrafficAlertElement_t  *AlertElement;
224
225    if (pTrafficMonitor == NULL)
226    {
227        return TI_NOK;
228    }
229
230    if (pTrafficMonitor->Active) /*To prevent double call to timer stop*/
231    {
232
233        pTrafficMonitor->Active = TI_FALSE;
234
235        pTrafficMonitor->DownTimerEnabled = TI_FALSE;
236        tmr_StopTimer (pTrafficMonitor->hTrafficMonTimer);
237    }
238
239    /* Set all events state to ALERT_OFF to enable them to "kick" again once after TrafficMonitor is started */
240    AlertElement = (TrafficAlertElement_t*)List_GetFirst(pTrafficMonitor->NotificationRegList);
241
242    while(AlertElement)
243    {
244        AlertElement->CurrentState = ALERT_OFF;
245        AlertElement = (TrafficAlertElement_t*)List_GetNext(pTrafficMonitor->NotificationRegList);
246    }
247
248    return TI_OK;
249}
250
251
252
253/************************************************************************/
254/*                  TrafficMonitor_Destroy                              */
255/************************************************************************/
256TI_STATUS TrafficMonitor_Destroy(TI_HANDLE hTrafficMonitor)
257{
258    TrafficMonitor_t *TrafficMonitor = (TrafficMonitor_t*)hTrafficMonitor;
259
260    if (TrafficMonitor)
261    {
262        /*Unregister from the RX/TX module for the required notification*/
263        txCtrlParams_UnRegNotif(TrafficMonitor->hTxCtrl,TrafficMonitor->TxRegReqHandle);
264        rxData_UnRegNotif(TrafficMonitor->hRxData,TrafficMonitor->RxRegReqHandle);
265
266        if(TrafficMonitor->NotificationRegList)
267        {
268            List_Destroy(TrafficMonitor->NotificationRegList);
269        }
270
271        if(TrafficMonitor->hTrafficMonTimer)
272        {
273            tmr_DestroyTimer (TrafficMonitor->hTrafficMonTimer);
274        }
275
276#ifdef TRAFF_TEST
277		if (TestEventTimer)
278		{
279			tmr_DestroyTimer (TestEventTimer);
280		}
281#endif
282
283        os_memoryFree(TrafficMonitor->hOs, TrafficMonitor, sizeof(TrafficMonitor_t));
284
285        return TI_OK;
286    }
287
288    return TI_NOK;
289}
290
291
292/***********************************************************************
293 *                        TrafficMonitor_RegEvent
294 ***********************************************************************
295DESCRIPTION: Reg event processing function, Perform the following:
296
297
298INPUT:          hTrafficMonitor -       Traffic Monitor the object.
299
300            TrafficAlertRegParm -       structure which include values to set for
301                                                the requested Alert event
302
303            AutoResetCreate - is only relevant to edge alerts.
304                  If AutoResetCreate flag is set to true then the registration function will create a conjunction reset element automatic
305                 this reset element will be with the same threshold but opposite in direction
306
307                 If AutoResetCreate flag is set to false then the reset element will be supplied afterward by the user with the function
308                 TrafficMonitor_SetRstCondition() the alert will not be active till the reset function will be set.
309
310OUTPUT:
311
312RETURN:     TrafficAlertElement pointer on success, NULL otherwise
313
314************************************************************************/
315TI_HANDLE TrafficMonitor_RegEvent(TI_HANDLE hTrafficMonitor,TrafficAlertRegParm_t *TrafficAlertRegParm,TI_BOOL AutoResetCreate)
316{
317    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
318    TrafficAlertElement_t  *TrafficAlertElement;
319    TI_UINT32 CurentTime ;
320
321    if(TrafficMonitor == NULL)
322       return NULL;
323
324    CurentTime = os_timeStampMs(TrafficMonitor->hOs);
325
326    /*Gets a TrafficAlertElement_t memory from the list to assign to the registered request*/
327    TrafficAlertElement = (TrafficAlertElement_t*)List_AllocElement(TrafficMonitor->NotificationRegList);
328    if (TrafficAlertElement == NULL)
329    {   /* add print*/
330                return NULL  ;
331    }
332
333    /*Init the alert element with the registered parameters.*/
334    TrafficAlertElement->CallBack = TrafficAlertRegParm->CallBack;
335    TrafficAlertElement->Context  = TrafficAlertRegParm->Context;
336    TrafficAlertElement->Cookie  = TrafficAlertRegParm->Cookie;
337    TrafficAlertElement->Direction = TrafficAlertRegParm->Direction;
338    TrafficAlertElement->Threshold = TrafficAlertRegParm->Threshold;
339    TrafficAlertElement->Trigger = TrafficAlertRegParm->Trigger;
340    TrafficAlertElement->TimeIntervalMs = TrafficAlertRegParm->TimeIntervalMs;
341    TrafficAlertElement->TimeOut = CurentTime + TrafficAlertRegParm->TimeIntervalMs;
342    TrafficAlertElement->EventCounter = 0;
343    TrafficMonitor_SetMask(TrafficMonitor,TrafficAlertElement,TrafficAlertRegParm->MonitorType);
344
345    TrafficAlertElement->CurrentState = ALERT_OFF;
346    TrafficAlertElement->AutoCreated = TI_FALSE;
347    TrafficAlertElement->Enabled = TI_FALSE;
348    /*In case that this is an Edge alert there is a need for a reset condition element*/
349    /*corresponding to the Alert request but opposite in the direction.*/
350    /*Note that the reset condition for this (new) reset element, is the Alert Element it self.*/
351    if(TrafficAlertElement->Trigger == TRAFF_EDGE)
352    {
353        if(AutoResetCreate)
354        {
355            /*Gets a TrafficAlertElement_t memory from the list to assign to the reset elemnt*/
356            TrafficAlertElement->ResetElment[0] = (TrafficAlertElement_t*)List_AllocElement(TrafficMonitor->NotificationRegList);
357            if( TrafficAlertElement->ResetElment[0] == NULL)
358            {
359                List_FreeElement(TrafficMonitor->NotificationRegList,TrafficAlertElement);
360                return NULL;
361            }
362
363            /*
364             copy the Traffic Element init params to the reset Elemnt Except for
365             the direction and the call back that is set to null the CurrentState set to disable.
366             And the reset condition,that points to the muster alert.
367             */
368            os_memoryCopy(TrafficMonitor->hOs,TrafficAlertElement->ResetElment[0],TrafficAlertElement,sizeof(TrafficAlertElement_t));
369            TrafficAlertElement->ResetElment[0]->CallBack = NULL;
370            /*opposite in the direction from the TrafficAlertElement->Direction*/
371            if (TrafficAlertRegParm->Direction == TRAFF_UP)
372                TrafficAlertElement->ResetElment[0]->Direction = TRAFF_DOWN;
373            else
374                TrafficAlertElement->ResetElment[0]->Direction = TRAFF_UP;
375            TrafficAlertElement->ResetElment[0]->CurrentState = ALERT_WAIT_FOR_RESET;
376            TrafficAlertElement->ResetElment[0]->ResetElment[0] = TrafficAlertElement;
377            TrafficAlertElement->ResetElment[0]->AutoCreated = TI_TRUE;
378
379            TrafficAlertElement->ResetElment[0]->RstWasAssigned = TI_TRUE;
380            TrafficAlertElement->RstWasAssigned = TI_TRUE;
381
382        }
383        else/* The reset element will be supplied afterward by the user in the meanwhile disable the alert till then*/
384        {
385            TrafficAlertElement->RstWasAssigned = TI_FALSE;
386            TrafficAlertElement->CurrentState = ALERT_WAIT_FOR_RESET;
387        }
388
389    }
390
391    TrafficMonitor_UpdateDownTrafficTimerState (TrafficMonitor);
392
393    return TrafficAlertElement;
394}
395
396
397/************************************************************************/
398/*                  FindRstElemEntryIndex                               */
399/************************************************************************/
400/* Gets a TrafficAlertElement_t memory from the list to assign to the reset elemnt
401 * for internal use
402 ************************************************************************/
403static TI_STATUS FindRstElemEntryIndex (TrafficMonitor_t *TrafficMonitor,TrafficAlertElement_t  *TrafficAlertElement,int *Index)
404{
405    int i;
406    /*Find an empty Rst element entry*/
407    for(i=0;(i<MAX_RST_ELMENT_PER_ALERT) && TrafficAlertElement->ResetElment[i];i++);
408    if(i == MAX_RST_ELMENT_PER_ALERT)
409        return TI_NOK;
410    *Index  = i;
411    return TI_OK;
412}
413
414/************************************************************************/
415/*                  TrafficMonitor_SetMask                              */
416/************************************************************************/
417/*
418 *      Convert the Mask from the types that declared in the
419 *  TrafficMonitorAPI to the types that are used in the Rx Tx modules.
420 *  And update the TX and RX module of the new event req
421 *  Sets the aggregation function that corresponds to the specific mask type
422 ************************************************************************/
423static TI_STATUS TrafficMonitor_SetMask(TrafficMonitor_t *TrafficMonitor,TrafficAlertElement_t *TrafficAlertElement,TraffEvntOptNum_t MaskType)
424{
425    TI_UINT32 TxMask = 0;
426    TI_UINT32 RxMask = 0;
427
428   switch(MaskType) {
429   case TX_RX_DIRECTED_FRAMES:
430        TxMask = DIRECTED_FRAMES_XFER;
431        RxMask = DIRECTED_FRAMES_RECV;
432        TrafficAlertElement->ActionFunc = SimpleFrameAggregation;
433        break;
434   case TX_ALL_MSDU_FRAMES:
435        TxMask = DIRECTED_FRAMES_XFER|MULTICAST_FRAMES_XFER|BROADCAST_FRAMES_XFER;
436        TrafficAlertElement->ActionFunc = SimpleFrameAggregation;
437    break;
438   case RX_ALL_MSDU_FRAMES:
439        RxMask = DIRECTED_FRAMES_RECV|MULTICAST_FRAMES_RECV|BROADCAST_FRAMES_RECV;
440        TrafficAlertElement->ActionFunc = SimpleFrameAggregation;
441        break;
442   case TX_RX_ALL_MSDU_FRAMES:
443        TxMask = DIRECTED_FRAMES_XFER|MULTICAST_FRAMES_XFER|BROADCAST_FRAMES_XFER;
444        RxMask = DIRECTED_FRAMES_RECV|MULTICAST_FRAMES_RECV|BROADCAST_FRAMES_RECV;
445        TrafficAlertElement->ActionFunc = SimpleFrameAggregation;
446        break;
447    case TX_RX_ALL_MSDU_IN_BYTES:
448        TxMask = DIRECTED_BYTES_XFER|MULTICAST_BYTES_XFER|BROADCAST_BYTES_XFER;
449        RxMask = DIRECTED_BYTES_RECV|MULTICAST_BYTES_RECV|BROADCAST_BYTES_RECV;
450        TrafficAlertElement->ActionFunc = SimpleByteAggregation;
451        break;
452   case TX_RX_DIRECTED_IN_BYTES:
453        TxMask = DIRECTED_BYTES_XFER;
454        RxMask = DIRECTED_BYTES_RECV;
455        TrafficAlertElement->ActionFunc = SimpleByteAggregation;
456    break;
457   case TX_RX_ALL_802_11_DATA_IN_BYTES:
458        TxMask = DIRECTED_BYTES_XFER | MULTICAST_BYTES_XFER;
459        RxMask = DIRECTED_BYTES_RECV | MULTICAST_BYTES_RECV;
460        TrafficAlertElement->ActionFunc = SimpleByteAggregation;
461    break;
462   case TX_RX_ALL_802_11_DATA_FRAMES:
463        TxMask = DIRECTED_FRAMES_XFER | MULTICAST_FRAMES_XFER;
464        RxMask = DIRECTED_FRAMES_RECV | MULTICAST_FRAMES_RECV;
465        TrafficAlertElement->ActionFunc = SimpleFrameAggregation;
466    break;
467   default:
468        WLAN_OS_REPORT(("TrafficMonitor_SetMask - unknown parameter: %d\n", MaskType));
469       return TI_NOK;
470   }
471
472
473   if(RxMask)
474   {
475       TrafficAlertElement->MonitorMask[RX_TRAFF_MODULE] = RxMask;
476       if(rxData_AddToNotifMask(TrafficMonitor->hRxData,TrafficMonitor->RxRegReqHandle,RxMask) == TI_NOK)
477           return TI_NOK;
478   }
479
480   if(TxMask)
481   {
482       TrafficAlertElement->MonitorMask[TX_TRAFF_MODULE] = TxMask;
483       if(txCtrlParams_AddToNotifMask(TrafficMonitor->hTxCtrl,TrafficMonitor->TxRegReqHandle,TxMask) == TI_NOK)
484           return TI_NOK;
485   }
486
487   return TI_OK;
488}
489
490
491/***********************************************************************
492 *                        TrafficMonitor_SetRstCondition
493 ***********************************************************************
494DESCRIPTION: Reg event processing function, Perform the following:
495             Sets the given reset element to the Alert element.
496             if MutualRst is set, then The operation is done vise versa .
497
498INPUT:          hTrafficMonitor -       Traffic Monitor the object.
499
500            EventHandle -         Alert event
501
502            ResetEventHandle  Alert Event that will be  used to as the rest for above.
503
504            MutualRst - if the 2 elements are used to reset One another.
505
506NOTE        If the reset element event condition is the same as the alert element the user
507            have to check the that threshold is bigger or smaller according to the direction
508            else it can create a deadlock
509
510OUTPUT:
511
512RETURN:     TI_OK on success, TI_NOK otherwise
513
514************************************************************************/
515TI_STATUS TrafficMonitor_SetRstCondition(TI_HANDLE hTrafficMonitor, TI_HANDLE EventHandle,TI_HANDLE ResetEventHandle,TI_BOOL MutualRst)
516{
517    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
518    TrafficAlertElement_t *TrafficAlertElement = (TrafficAlertElement_t*)EventHandle;
519    TrafficAlertElement_t *TrafficResetAlertElement = (TrafficAlertElement_t*)ResetEventHandle;
520    int i,x;
521    TI_UINT32 CurentTime ;
522
523    if((TrafficMonitor == NULL) || (EventHandle == NULL) || (TrafficResetAlertElement == NULL))
524        return TI_NOK;
525
526
527    CurentTime = os_timeStampMs(TrafficMonitor->hOs);
528
529    /*
530    Check that validity of the reset condition
531    1.The reset condition is edge.
532    2.The direction is opposite from the main alert.
533    3.The threshold is bigger or smaller according to the direction
534    This condition is not checked but the user have check it else it can create a deadlock..
535    */
536    if((TrafficResetAlertElement->Trigger != TRAFF_EDGE) || (TrafficAlertElement->Trigger != TRAFF_EDGE))
537        return TI_NOK;
538    if(TrafficResetAlertElement->Direction == TrafficAlertElement->Direction)
539        return TI_NOK;
540
541
542    /*Find an empty Rst element entry*/
543    if(FindRstElemEntryIndex(TrafficMonitor,TrafficResetAlertElement,&i) == TI_NOK)
544        return TI_NOK;
545
546    TrafficResetAlertElement->ResetElment[i] = TrafficAlertElement;
547
548    /*if we know for sure that No Rst Element was assigned
549    therefore that element was in disable mode and we have to enable it.*/
550    if (!(TrafficAlertElement->RstWasAssigned))
551    {
552        TrafficAlertElement->RstWasAssigned = TI_TRUE;
553        TrafficAlertElement->CurrentState = ALERT_OFF;
554        TrafficAlertElement->TimeOut = CurentTime + TrafficAlertElement->TimeIntervalMs;
555        TrafficAlertElement->EventCounter =0;
556    }
557
558
559    if(MutualRst)
560    {
561      /*Find an empty Rst element entry in the TempRstAlertElement*/
562      if(FindRstElemEntryIndex(TrafficMonitor,TrafficAlertElement,&x) == TI_NOK)
563      {
564        /*this clean up is not complete*/
565        TrafficResetAlertElement->ResetElment[i] = NULL;
566        return TI_NOK;
567      }
568
569      TrafficAlertElement->ResetElment[x] = TrafficResetAlertElement;
570      /*if know for sure that No Rst Element was assigned
571      therefore that element was in disable mode and we have to enable it.*/
572      if (!(TrafficResetAlertElement->RstWasAssigned))
573      {
574        TrafficResetAlertElement->RstWasAssigned = TI_TRUE;
575        TrafficResetAlertElement->CurrentState = ALERT_OFF;
576        TrafficResetAlertElement->TimeOut = CurentTime + TrafficAlertElement->TimeIntervalMs;
577        TrafficResetAlertElement->EventCounter = 0;
578      }
579    }
580    return TI_OK;
581}
582
583
584/************************************************************************/
585/*               TrafficMonitor_CleanRelatedRef                         */
586/************************************************************************/
587void TrafficMonitor_CleanRelatedRef(TrafficMonitor_t *TrafficMonitor,TrafficAlertElement_t *TrafficAlertElement)
588{
589
590    int i;
591    TrafficAlertElement_t *AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
592
593    /* go over all the Down elements and check for alert ResetElment that ref to TrafficAlertElement*/
594    while(AlertElement)
595    {
596        for(i=0;i<MAX_RST_ELMENT_PER_ALERT;i++)
597        {
598            if(AlertElement->ResetElment[i] == TrafficAlertElement)
599                AlertElement->ResetElment[i] = NULL;
600        }
601        AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
602    }
603}
604
605
606
607/************************************************************************/
608/*          TrafficMonitor_StopNotif                                   */
609/************************************************************************/
610void TrafficMonitor_StopEventNotif(TI_HANDLE hTrafficMonitor,TI_HANDLE EventHandle)
611{
612    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
613    TrafficAlertElement_t *TrafficAlertElement = (TrafficAlertElement_t*)EventHandle;
614
615    if(TrafficMonitor == NULL)
616        return ;
617
618    if(TrafficAlertElement == NULL)
619        return ;
620
621    TrafficAlertElement->Enabled = TI_FALSE;
622    TrafficMonitor_UpdateDownTrafficTimerState (hTrafficMonitor);
623
624}
625
626
627
628/************************************************************************/
629/*          TrafficMonitor_StartNotif                                   */
630/************************************************************************/
631void TrafficMonitor_StartEventNotif(TI_HANDLE hTrafficMonitor, TI_HANDLE EventHandle)
632{
633    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
634    TrafficAlertElement_t *TrafficAlertElement = (TrafficAlertElement_t*)EventHandle;
635
636    if(TrafficMonitor == NULL)
637        return ;
638
639    if(TrafficAlertElement == NULL)
640        return ;
641
642    TrafficAlertElement->Enabled = TI_TRUE;
643    TrafficMonitor_UpdateDownTrafficTimerState (hTrafficMonitor);
644}
645
646
647
648/************************************************************************/
649/*          TrafficMonitor_StartNotif                                   */
650/************************************************************************/
651void TrafficMonitor_ResetEvent(TI_HANDLE hTrafficMonitor, TI_HANDLE EventHandle)
652{
653    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
654    TrafficAlertElement_t *TrafficAlertElement = (TrafficAlertElement_t*)EventHandle;
655
656    if(TrafficMonitor == NULL)
657        return ;
658
659    if(TrafficAlertElement == NULL)
660        return ;
661
662    TrafficAlertElement->CurrentState = ALERT_OFF;
663
664    TrafficMonitor_UpdateDownTrafficTimerState (TrafficMonitor);
665}
666
667
668
669/************************************************************************/
670/*          TrafficMonitor_UnregEvent                                   */
671/************************************************************************/
672void TrafficMonitor_UnregEvent(TI_HANDLE hTrafficMonitor, TI_HANDLE EventHandle)
673{
674    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
675    TrafficAlertElement_t *TrafficAlertElement = (TrafficAlertElement_t*)EventHandle;
676
677    if(TrafficMonitor == NULL)
678        return ;
679
680    /*If it was an edge alert then there can be one more alert element to free.*/
681    /*one is the alert, and the second is the reset element that corresponds to this alert*/
682    /*if it was  Auto Created*/
683    if (TrafficAlertElement->ResetElment[0])
684      if (TrafficAlertElement->ResetElment[0]->AutoCreated)
685       List_FreeElement(TrafficMonitor->NotificationRegList,TrafficAlertElement->ResetElment);
686
687    TrafficMonitor_CleanRelatedRef(TrafficMonitor,TrafficAlertElement);
688
689    List_FreeElement(TrafficMonitor->NotificationRegList,EventHandle);
690
691    TrafficMonitor_UpdateDownTrafficTimerState (TrafficMonitor);
692}
693
694
695
696/***********************************************************************
697 *                        isThresholdUp
698 ***********************************************************************
699DESCRIPTION: Evaluate if alert element as crossed his threshold
700             if yes it operate the callback registered for this alert and take care of the alert state.
701                         For alert with UP direction the following algorithm is preformed
702             If the threshold is passed in the req time interval or less. then
703             For Level
704                The alert mode is changed to ON & the next timeout is set to the next interval.
705             For Edge
706                The alert mode is changed to wait for reset and the reset element is set to off.
707                And his timeout is set
708
709INPUT:
710            EventHandle -         Alert event
711            CurrentTime - the current time Time stamp
712
713OUTPUT:
714
715RETURN:     If  threshold crossed TI_TRUE else False
716
717************************************************************************/
718static TI_BOOL isThresholdUp(TrafficAlertElement_t *AlertElement , TI_UINT32 CurrentTime)
719{
720    int i;
721
722    if (AlertElement->TimeOut < CurrentTime)
723    {
724        AlertElement->EventCounter = AlertElement->LastCounte;
725        AlertElement->TimeOut = CurrentTime + AlertElement->TimeIntervalMs;
726    }
727
728    if (AlertElement->EventCounter > AlertElement->Threshold)
729    {
730        AlertElement->EventCounter = 0;
731        /*Sets the new due time (time out)*/
732        AlertElement->TimeOut = CurrentTime + AlertElement->TimeIntervalMs;
733
734        /*For Edge alert change the alert status to wait for reset and
735        The corresponding reset element from wait for reset To off.
736        That way toggling the two elements*/
737        if(AlertElement->Trigger == TRAFF_EDGE)
738        {
739            AlertElement->CurrentState = ALERT_WAIT_FOR_RESET;
740            for(i=0;i<MAX_RST_ELMENT_PER_ALERT;i++)
741            {
742                TrafficAlertElement_t *rstElmt = AlertElement->ResetElment[i];
743                if(rstElmt != NULL)
744                    if(rstElmt->CurrentState == ALERT_WAIT_FOR_RESET)
745                    {
746                        rstElmt->CurrentState = ALERT_OFF;
747                        rstElmt->EventCounter = 0;
748                        rstElmt->TimeOut = CurrentTime + rstElmt->TimeIntervalMs;
749                    }
750            }
751        }
752        else
753            AlertElement->CurrentState = ALERT_ON;
754
755        /*Call the callback function*/
756        if((AlertElement->CallBack != NULL) && AlertElement->Enabled)
757            AlertElement->CallBack(AlertElement->Context,AlertElement->Cookie);
758        return TI_TRUE;
759    }
760
761    return TI_FALSE;
762}
763
764
765
766/***********************************************************************
767 *                        isThresholdDown
768 ***********************************************************************
769DESCRIPTION: Evaluate if alert element as crossed his threshold
770             if yes it operate the callback registered for this alert and take care of the alert state.
771                         For alert with DOWN direction the following algorithm is preformed
772             If the threshold is passed (EventCounter < Threshold) in the req time only. then
773             For Level
774               The alert mode is changed to ON & the next timeout is set to the next interval.
775               If the alert condition will still be on.then the next alert will be in the next time interval
776            For Edge
777               The alert mode is changed to wait for reset and the reset element is set to off.
778               And his timeout is set.
779
780INPUT:
781            EventHandle -         Alert event
782            CurrentTime - the current time Time stamp
783
784OUTPUT:
785
786RETURN:     If threshold crossed TI_TRUE else False
787
788************************************************************************/
789static TI_BOOL isThresholdDown(TrafficAlertElement_t *AlertElement , TI_UINT32 CurrentTime)
790{
791    int i;
792    TI_BOOL returnVal = TI_FALSE;
793
794    /*
795    if its end of window time.
796    */
797    if (AlertElement->TimeOut <= CurrentTime)
798    {
799        /*
800        if there was a down edge event.
801        */
802        if (AlertElement->EventCounter <= AlertElement->Threshold)
803        {
804            /*For Edge alert change the alert status to wait for reset and
805            The corresponding reset element from wait for reset To off.
806            That way toggling the two elements*/
807            if(AlertElement->Trigger == TRAFF_EDGE)
808            {
809                AlertElement->CurrentState = ALERT_WAIT_FOR_RESET;
810                for(i=0;i<MAX_RST_ELMENT_PER_ALERT;i++)
811                {
812                    TrafficAlertElement_t *rstElmt = AlertElement->ResetElment[i];
813                    if(rstElmt != NULL)
814                        if(rstElmt->CurrentState == ALERT_WAIT_FOR_RESET)
815                        {
816                            rstElmt->CurrentState = ALERT_OFF;
817                            rstElmt->EventCounter = 0;
818                            rstElmt->TimeOut = CurrentTime + rstElmt->TimeIntervalMs;
819                        }
820                }
821            }
822            else
823                AlertElement->CurrentState = ALERT_ON;
824
825            /*Call the callback function*/
826            if((AlertElement->CallBack != NULL) && AlertElement->Enabled)
827                AlertElement->CallBack(AlertElement->Context,AlertElement->Cookie);
828
829            returnVal = TI_TRUE;
830        }
831
832        /* end of time window - clear the event counter for the new window.*/
833        AlertElement->EventCounter = 0;
834        /*Sets the new due time (time out)*/
835        AlertElement->TimeOut = CurrentTime + AlertElement->TimeIntervalMs;
836    }
837    else
838    {
839        /*
840        In case we find out that the alert condition will not Occur for this frame window,
841        therefor start a new alert examine cycle (the next farme window).
842        (Not wait till the timeout of this current frame window)
843        */
844        if(AlertElement->EventCounter > AlertElement->Threshold)
845        {
846            AlertElement->EventCounter = 0;
847            AlertElement->TimeOut = CurrentTime + AlertElement->TimeIntervalMs;
848        }
849    }
850    return returnVal;
851}
852
853
854
855/************************************************************************/
856/*              TimerMonitor_TimeOut                                    */
857/************************************************************************/
858/*
859 *      Timer function that is called for every x time interval
860 *   That will invoke a process if any down limit as occurred.
861 *
862 ************************************************************************/
863static void TimerMonitor_TimeOut (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured)
864{
865
866    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
867    TrafficAlertElement_t *AlertElement;
868    TI_UINT32 CurentTime;
869    TI_UINT32 activeTrafDownEventsNum = 0;
870    TI_UINT32 trafficDownMinTimeout = 0xFFFFFFFF;
871
872    if(TrafficMonitor == NULL)
873        return;
874
875    AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
876    CurentTime = os_timeStampMs(TrafficMonitor->hOs);
877
878
879    /* go over all the Down elements and check for alert */
880    while(AlertElement)
881    {
882        if(AlertElement->CurrentState != ALERT_WAIT_FOR_RESET)
883        {
884            if (AlertElement->Direction == TRAFF_DOWN)
885            {
886               isThresholdDown(AlertElement,CurentTime);
887            }
888        }
889
890         if ((AlertElement->Direction == TRAFF_DOWN) && (AlertElement->Trigger == TRAFF_EDGE) && (AlertElement->CurrentState == ALERT_OFF) && (AlertElement->Enabled == TI_TRUE))
891{
892            /* Increase counter of active traffic down events */
893            activeTrafDownEventsNum++;
894
895            /* Search for the alert with the most short Interval time - will be used to start timer */
896            if ((AlertElement->TimeIntervalMs) < (trafficDownMinTimeout))
897               trafficDownMinTimeout = AlertElement->TimeIntervalMs;
898         }
899
900        AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
901    }
902
903   TrafficMonitor_ChangeDownTimerStatus (TrafficMonitor,activeTrafDownEventsNum,trafficDownMinTimeout);
904
905}
906
907/***********************************************************************
908 *                        TrafficMonitor_IsEventOn
909 ***********************************************************************
910DESCRIPTION: Returns the current status of an event element.
911
912INPUT:      TrafficAlertElement_t
913
914
915OUTPUT:    bool
916
917RETURN:     True = ON  false = OFF
918
919************************************************************************/
920TI_BOOL TrafficMonitor_IsEventOn(TI_HANDLE EventHandle)
921{
922    TrafficAlertElement_t *TrafficAlertElement = (TrafficAlertElement_t*)EventHandle;
923
924    if(TrafficAlertElement == NULL)
925        return TI_FALSE;
926
927
928    if (TrafficAlertElement->CurrentState == ALERT_OFF)
929        return TI_FALSE;
930    else
931        return TI_TRUE;
932
933}
934
935
936
937/***********************************************************************
938 *                        TrafficMonitor_GetFrameBandwidth
939 ***********************************************************************
940DESCRIPTION: Returns the total direct frames in the Rx and Tx per second.
941
942INPUT:          hTrafficMonitor -       Traffic Monitor the object.
943
944
945OUTPUT:
946
947RETURN:     Total BW
948************************************************************************/
949int TrafficMonitor_GetFrameBandwidth(TI_HANDLE hTrafficMonitor)
950{
951	TrafficMonitor_t 	*pTrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
952	TI_UINT32 			uCurentTS;
953
954	if(pTrafficMonitor == NULL)
955        return TI_NOK;
956
957	uCurentTS = os_timeStampMs(pTrafficMonitor->hOs);
958
959	/* Calculate BW for Rx & Tx */
960	return ( TrafficMonitor_calcBW(&pTrafficMonitor->DirectRxFrameBW, uCurentTS) +
961			 TrafficMonitor_calcBW(&pTrafficMonitor->DirectTxFrameBW, uCurentTS) );
962}
963
964/***********************************************************************
965*                        TrafficMonitor_updateBW
966***********************************************************************
967DESCRIPTION: Upon receiving an event of Tx/Rx (a packet was sent or received), This function is
968				called and performs BW calculation.
969
970INPUT:
971				pBandWidth		- BW of Rx or Tx
972				uCurrentTS		- current TS of the recent event
973
974OUTPUT:         pBandWidth		- updated counters and TS
975
976************************************************************************/
977void TrafficMonitor_updateBW(BandWidth_t *pBandWidth, TI_UINT32 uCurrentTS)
978{
979	/* Check if we should move to the next window */
980	if ( (uCurrentTS - pBandWidth->auFirstEventsTS[pBandWidth->uCurrentWindow]) < (SIZE_OF_WINDOW_MS) )
981	{
982		pBandWidth->auWindowCounter[pBandWidth->uCurrentWindow]++;
983	}
984	else	/* next window */
985	{
986		/* increment current window and mark the first event received */
987		pBandWidth->uCurrentWindow = (pBandWidth->uCurrentWindow + 1) & CYCLIC_COUNTER_ELEMENT;
988		pBandWidth->auFirstEventsTS[pBandWidth->uCurrentWindow] = uCurrentTS;
989		pBandWidth->auWindowCounter[pBandWidth->uCurrentWindow] = 1;
990	}
991}
992/***********************************************************************
993*                        TrafficMonitor_calcBW
994***********************************************************************
995DESCRIPTION: Returns the total direct frames in Rx or Tx.
996			 It is called when outside module request the BW.
997			 Calculate band width by summing up the sliding windows.
998
999INPUT:       pBandWidth		- BW of Rx or Tx
1000			 uCurrentTS		- current TS
1001
1002RETURN:     Total BW
1003************************************************************************/
1004TI_UINT32 TrafficMonitor_calcBW(BandWidth_t *pBandWidth, TI_UINT32 uCurrentTS)
1005{
1006	TI_UINT32 uTotalTime = uCurrentTS - pBandWidth->auFirstEventsTS[pBandWidth->uCurrentWindow];
1007	TI_UINT32 uTotalBW = 0;
1008	TI_INT32  iter = (TI_INT32)pBandWidth->uCurrentWindow;
1009	TI_INT32  iNextIter = (iter - 1) & CYCLIC_COUNTER_ELEMENT;	/* Always one less than i */
1010
1011	/* As long as the summed windows are less than BW_WINDOW_MS and we didn't loop the whole array */
1012	while ( (uTotalTime < BW_WINDOW_MS) && (iNextIter != pBandWidth->uCurrentWindow))
1013	{
1014		uTotalBW	+= pBandWidth->auWindowCounter[iter];
1015		/* add next window time - next loop will check if we exceeded the BW window */
1016		uTotalTime   = uCurrentTS - pBandWidth->auFirstEventsTS[iNextIter];
1017
1018		iter = iNextIter;
1019		iNextIter = (iter - 1) & CYCLIC_COUNTER_ELEMENT;
1020	} ;
1021
1022	/*
1023	 * Note that if (iNextIter == pBandWidth->uCurrentWindow) than the calculated BW could be up to
1024	 * SIZE_OF_WINDOW_MS less than BW_WINDOW_MS
1025	 */
1026	return uTotalBW;
1027}
1028
1029
1030/***********************************************************************
1031 *                        TrafficMonitor_Event
1032 ***********************************************************************
1033DESCRIPTION: this function is called for every event that was requested from the Tx or Rx
1034             The function preformes update of the all the relevant Alert in the system
1035             that corresponds to the event. checks the Alert Status due to this event.
1036
1037
1038
1039INPUT:          hTrafficMonitor -       Traffic Monitor the object.
1040
1041            Count - evnet count.
1042            Mask - the event mask that That triggered this function.
1043
1044            MonitorModuleType Will hold the module type from where this function was called.
1045
1046OUTPUT:
1047
1048RETURN:
1049
1050************************************************************************/
1051void TrafficMonitor_Event(TI_HANDLE hTrafficMonitor,int Count,TI_UINT16 Mask,TI_UINT32 MonitorModuleType)
1052{
1053    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
1054    TrafficAlertElement_t *AlertElement;
1055    TI_UINT32 activeTrafDownEventsNum = 0;
1056    TI_UINT32 trafficDownMinTimeout = 0xFFFFFFFF;
1057    TI_UINT32 uCurentTS;
1058
1059    if(TrafficMonitor == NULL)
1060        return;
1061
1062    if(!TrafficMonitor->Active)
1063        return;
1064
1065	uCurentTS = os_timeStampMs(TrafficMonitor->hOs);
1066
1067    /* for BW calculation */
1068    if(MonitorModuleType == RX_TRAFF_MODULE)
1069    {
1070        if(Mask & DIRECTED_FRAMES_RECV)
1071		{
1072            TrafficMonitor_updateBW(&TrafficMonitor->DirectRxFrameBW, uCurentTS);
1073		}
1074    }
1075    else if (MonitorModuleType == TX_TRAFF_MODULE)
1076    {
1077        if(Mask & DIRECTED_FRAMES_XFER)
1078		{
1079            TrafficMonitor_updateBW(&TrafficMonitor->DirectTxFrameBW, uCurentTS);
1080		}
1081    }
1082    else
1083	{
1084        return; /* module type does not exist, error return */
1085	}
1086
1087    AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
1088
1089    /* go over all the elements and check for alert */
1090    while(AlertElement)
1091    {
1092        if(AlertElement->CurrentState != ALERT_WAIT_FOR_RESET)
1093        {
1094            if(AlertElement->MonitorMask[MonitorModuleType] & Mask)
1095            {
1096                AlertElement->ActionFunc(AlertElement,Count);
1097                if (AlertElement->Direction == TRAFF_UP)
1098                {
1099                    isThresholdUp(AlertElement, uCurentTS);
1100                }
1101            }
1102
1103            if ((AlertElement->Direction == TRAFF_DOWN) && (AlertElement->Trigger == TRAFF_EDGE) && (AlertElement->CurrentState == ALERT_OFF) && (AlertElement->Enabled == TI_TRUE))
1104            {
1105               /* Increase counter of active traffic down events */
1106               activeTrafDownEventsNum++;
1107
1108               /* Search for the alert with the most short Interval time - will be used to start timer */
1109               if ((AlertElement->TimeIntervalMs) < (trafficDownMinTimeout))
1110                  trafficDownMinTimeout = AlertElement->TimeIntervalMs;
1111            }
1112
1113        }
1114        AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
1115    }
1116
1117    TrafficMonitor_ChangeDownTimerStatus (TrafficMonitor,activeTrafDownEventsNum,trafficDownMinTimeout);
1118
1119}
1120
1121
1122/*
1123 *      Used as the aggregation function that is used by the alerts for counting the events.
1124 */
1125static void SimpleByteAggregation(TI_HANDLE TraffElem,int Count)
1126{
1127    TrafficAlertElement_t *AlertElement = TraffElem;
1128    AlertElement->EventCounter += Count;
1129    AlertElement->LastCounte = Count;
1130}
1131
1132
1133/*
1134 *      Used as the aggregation function for frame. (count is not used)
1135 */
1136static void SimpleFrameAggregation(TI_HANDLE TraffElem,int Count)
1137{
1138    TrafficAlertElement_t *AlertElement = TraffElem;
1139    AlertElement->EventCounter++;
1140    AlertElement->LastCounte = 1;
1141}
1142
1143/*-----------------------------------------------------------------------------
1144Routine Name: TrafficMonitor_UpdateDownTrafficTimerState
1145Routine Description: called whenever a "down" alert is called, or any other change in the alert list.
1146                     used to either start or stop the "traffic down" timer.
1147                     loops through alert list, searches for active traffic down events.
1148Arguments:
1149Return Value:
1150-----------------------------------------------------------------------------*/
1151static void TrafficMonitor_UpdateDownTrafficTimerState (TI_HANDLE hTrafficMonitor)
1152{
1153	TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
1154    TrafficAlertElement_t *AlertElement;
1155    TI_UINT32 activeTrafDownEventsNum = 0;
1156    TI_UINT32 trafficDownMinTimeout = 0xFFFFFFFF;
1157
1158    AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
1159
1160    while(AlertElement)
1161    {
1162
1163      if ((AlertElement->Direction == TRAFF_DOWN) && (AlertElement->Trigger == TRAFF_EDGE) && (AlertElement->CurrentState == ALERT_OFF) && (AlertElement->Enabled == TI_TRUE))
1164      {
1165         /* Increase counter of active traffic down events */
1166         activeTrafDownEventsNum++;
1167
1168         /* Search for the alert with the most short Interval time - will be used to start timer */
1169         if ((AlertElement->TimeIntervalMs) < (trafficDownMinTimeout))
1170            trafficDownMinTimeout = AlertElement->TimeIntervalMs;
1171      }
1172
1173      AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
1174
1175    }
1176
1177    TrafficMonitor_ChangeDownTimerStatus (TrafficMonitor,activeTrafDownEventsNum,trafficDownMinTimeout);
1178
1179}
1180
1181/*-----------------------------------------------------------------------------
1182Routine Name: TrafficMonitor_ChangeDownTimerStatus
1183Routine Description: Start or stop down traffic timer according to number of down events found and minInterval time.
1184Arguments:
1185Return Value:
1186-----------------------------------------------------------------------------*/
1187static void TrafficMonitor_ChangeDownTimerStatus (TI_HANDLE hTrafficMonitor, TI_UINT32 downEventsFound, TI_UINT32 minIntervalTime)
1188{
1189	TrafficMonitor_t *pTrafficMonitor = (TrafficMonitor_t*)hTrafficMonitor;
1190
1191    if ((downEventsFound == 0) && pTrafficMonitor->DownTimerEnabled)
1192    {
1193        pTrafficMonitor->DownTimerEnabled = TI_FALSE;
1194        tmr_StopTimer (pTrafficMonitor->hTrafficMonTimer);
1195    }
1196    else if ((downEventsFound > 0) && (pTrafficMonitor->DownTimerEnabled == TI_FALSE))
1197    {
1198        pTrafficMonitor->DownTimerEnabled = TI_TRUE;
1199        /* Start the timer with user defined percentage of the the minimum interval discovered earlier */
1200        tmr_StartTimer (pTrafficMonitor->hTrafficMonTimer,
1201                        TimerMonitor_TimeOut,
1202                        (TI_HANDLE)pTrafficMonitor,
1203                        ((minIntervalTime * pTrafficMonitor->trafficDownTestIntervalPercent) / 100),
1204                        TI_TRUE);
1205    }
1206}
1207
1208#ifdef TI_DBG
1209
1210/*-----------------------------------------------------------------------------
1211Routine Name: TrafficMonitor_UpdateActiveEventsCounters
1212Routine Description:
1213Arguments:
1214Return Value:
1215-----------------------------------------------------------------------------*/
1216void TrafficMonitor_UpdateActiveEventsCounters (TI_HANDLE hTrafficMonitor)
1217{
1218	TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
1219    TrafficAlertElement_t *AlertElement;
1220    TI_UINT32 activeTrafDownEventsNum = 0;
1221
1222    AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
1223
1224    while(AlertElement)
1225    {
1226      if ((AlertElement->Direction == TRAFF_DOWN) && (AlertElement->Trigger == TRAFF_EDGE) && (AlertElement->CurrentState == ALERT_OFF) && (AlertElement->Enabled == TI_TRUE))
1227      {
1228         activeTrafDownEventsNum++;
1229      }
1230      AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
1231    }
1232
1233}
1234
1235
1236#endif
1237
1238#ifdef TRAFF_TEST
1239/*
1240 *      TEST Function
1241 */
1242void func1(TI_HANDLE Context,TI_UINT32 Cookie)
1243{
1244    switch(Cookie) {
1245    case 1:
1246                WLAN_OS_REPORT(("TRAFF - ALERT UP limit - 50 ON"));
1247        break;
1248    case 2:
1249                WLAN_OS_REPORT(("TRAFF - ALERT UP limit - 30 ON"));
1250    break;
1251    case 3:
1252                WLAN_OS_REPORT(("TRAFF - ALERT DOWN limit - 25 ON"));
1253    break;
1254    case 4:
1255                WLAN_OS_REPORT(("TRAFF - ALERT DOWN limit - 10 ON"));
1256    break;
1257   }
1258
1259}
1260
1261
1262void PrintElertStus()
1263{
1264    TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)TestTrafficMonitor;
1265    TrafficAlertElement_t *AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
1266
1267    /* go over all the Down elements and check for alert ResetElment that ref to TrafficAlertElement*/
1268    while(AlertElement)
1269    {
1270        if(AlertElement->CurrentState == ALERT_WAIT_FOR_RESET)
1271            WLAN_OS_REPORT(("TRAFF - ALERT ALERT_WAIT_FOR_RESET"));
1272        else
1273            WLAN_OS_REPORT(("TRAFF - ALERT ENABLED"));
1274
1275
1276        AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
1277    }
1278}
1279
1280void TestEventFunc (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured)
1281{
1282
1283    static flag = TI_TRUE;
1284    TrafficAlertRegParm_t TrafficAlertRegParm ;
1285    if(flag)
1286    {
1287
1288        TrafficAlertRegParm.CallBack = func1;
1289        TrafficAlertRegParm.Context = NULL ;
1290        TrafficAlertRegParm.Cookie =  1 ;
1291        TrafficAlertRegParm.Direction = TRAFF_UP ;
1292        TrafficAlertRegParm.Trigger = TRAFF_EDGE;
1293        TrafficAlertRegParm.TimeIntervalMs = 1000;
1294        TrafficAlertRegParm.Threshold = 50;
1295        TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
1296        Alert1 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
1297
1298        TrafficAlertRegParm.CallBack = func1;
1299        TrafficAlertRegParm.Context = NULL ;
1300        TrafficAlertRegParm.Cookie =  2 ;
1301        TrafficAlertRegParm.Direction = TRAFF_UP ;
1302        TrafficAlertRegParm.Trigger = TRAFF_EDGE;
1303        TrafficAlertRegParm.TimeIntervalMs = 1000;
1304        TrafficAlertRegParm.Threshold = 30;
1305        TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
1306        Alert2 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
1307
1308
1309        TrafficAlertRegParm.CallBack = func1;
1310        TrafficAlertRegParm.Context = NULL ;
1311        TrafficAlertRegParm.Cookie =  3 ;
1312        TrafficAlertRegParm.Direction = TRAFF_DOWN ;
1313        TrafficAlertRegParm.Trigger = TRAFF_EDGE;
1314        TrafficAlertRegParm.TimeIntervalMs = 1000;
1315        TrafficAlertRegParm.Threshold = 25;
1316        TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
1317        Alert3 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
1318
1319        TrafficAlertRegParm.CallBack = func1;
1320        TrafficAlertRegParm.Context = NULL ;
1321        TrafficAlertRegParm.Cookie =  4 ;
1322        TrafficAlertRegParm.Direction = TRAFF_DOWN ;
1323        TrafficAlertRegParm.Trigger = TRAFF_LEVEL;
1324        TrafficAlertRegParm.TimeIntervalMs = 1000;
1325        TrafficAlertRegParm.Threshold = 10;
1326        TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
1327        Alert4 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
1328
1329       TrafficMonitor_SetRstCondition(TestTrafficMonitor, Alert1,Alert3,TI_TRUE);
1330       TrafficMonitor_SetRstCondition(TestTrafficMonitor, Alert2,Alert3,TI_FALSE);
1331       flag = TI_FALSE;
1332    }
1333
1334    PrintElertStus();
1335
1336}
1337
1338#endif
1339