Home | History | Annotate | Download | only in Data_link
      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*/
     56 TI_HANDLE TestTrafficMonitor;
     57 TI_HANDLE TestEventTimer;
     58 TI_HANDLE Alert1;
     59 TI_HANDLE Alert2;
     60 TI_HANDLE Alert3;
     61 TI_HANDLE Alert4;
     62 void PrintElertStus();
     63 void TestEventFunc (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured);
     64 #endif
     65 
     66 
     67 /************************************************************************/
     68 /*           Function prototype                                         */
     69 /************************************************************************/
     70 static void TimerMonitor_TimeOut (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured);
     71 static void TrafficMonitor_updateBW(BandWidth_t *pBandWidth, TI_UINT32 uCurrentTS);
     72 static TI_UINT32 TrafficMonitor_calcBW(BandWidth_t *pBandWidth, TI_UINT32 uCurrentTS);
     73 static TI_BOOL isThresholdDown(TrafficAlertElement_t *AlertElement,TI_UINT32 CurrentTime);
     74 static TI_BOOL isThresholdUp(TrafficAlertElement_t *AlertElement , TI_UINT32 CurrentTime);
     75 static void SimpleByteAggregation(TI_HANDLE TraffElem,int Count);
     76 static void SimpleFrameAggregation(TI_HANDLE TraffElem,int Count);
     77 static TI_HANDLE TrafficMonitor_ExitFunc(TrafficMonitor_t *TrafficMonitor,TI_HANDLE hOs);
     78 static TI_STATUS FindRstElemEntryIndex (TrafficMonitor_t *TrafficMonitor,TrafficAlertElement_t  *TrafficAlertElement,int *Index);
     79 static TI_STATUS TrafficMonitor_SetMask(TrafficMonitor_t *TrafficMonitor,TrafficAlertElement_t *TrafficAlertElement,TraffEvntOptNum_t MaskType);
     80 
     81 static void TrafficMonitor_UpdateDownTrafficTimerState (TI_HANDLE hTrafficMonitor);
     82 static void TrafficMonitor_ChangeDownTimerStatus (TI_HANDLE hTrafficMonitor, TI_UINT32 downEventsFound, TI_UINT32 minIntervalTime);
     83 
     84 /************************************************************************/
     85 /*                      TrafficMonitor_create                           */
     86 /************************************************************************/
     87 TI_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 /************************************************************************/
    116 static 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 /************************************************************************/
    134 void 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 /************************************************************************/
    181 TI_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 /************************************************************************/
    220 TI_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 /************************************************************************/
    256 TI_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  ***********************************************************************
    295 DESCRIPTION: Reg event processing function, Perform the following:
    296 
    297 
    298 INPUT:          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 
    310 OUTPUT:
    311 
    312 RETURN:     TrafficAlertElement pointer on success, NULL otherwise
    313 
    314 ************************************************************************/
    315 TI_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  ************************************************************************/
    403 static 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  ************************************************************************/
    423 static 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  ***********************************************************************
    494 DESCRIPTION: 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 
    498 INPUT:          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 
    506 NOTE        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 
    510 OUTPUT:
    511 
    512 RETURN:     TI_OK on success, TI_NOK otherwise
    513 
    514 ************************************************************************/
    515 TI_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 /************************************************************************/
    587 void 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 /************************************************************************/
    610 void 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 /************************************************************************/
    631 void 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 /************************************************************************/
    651 void 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 /************************************************************************/
    672 void 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  ***********************************************************************
    699 DESCRIPTION: 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 
    709 INPUT:
    710             EventHandle -         Alert event
    711             CurrentTime - the current time Time stamp
    712 
    713 OUTPUT:
    714 
    715 RETURN:     If  threshold crossed TI_TRUE else False
    716 
    717 ************************************************************************/
    718 static 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  ***********************************************************************
    769 DESCRIPTION: 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 
    780 INPUT:
    781             EventHandle -         Alert event
    782             CurrentTime - the current time Time stamp
    783 
    784 OUTPUT:
    785 
    786 RETURN:     If threshold crossed TI_TRUE else False
    787 
    788 ************************************************************************/
    789 static 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  ************************************************************************/
    863 static 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  ***********************************************************************
    910 DESCRIPTION: Returns the current status of an event element.
    911 
    912 INPUT:      TrafficAlertElement_t
    913 
    914 
    915 OUTPUT:    bool
    916 
    917 RETURN:     True = ON  false = OFF
    918 
    919 ************************************************************************/
    920 TI_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  ***********************************************************************
    940 DESCRIPTION: Returns the total direct frames in the Rx and Tx per second.
    941 
    942 INPUT:          hTrafficMonitor -       Traffic Monitor the object.
    943 
    944 
    945 OUTPUT:
    946 
    947 RETURN:     Total BW
    948 ************************************************************************/
    949 int 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 ***********************************************************************
    967 DESCRIPTION: Upon receiving an event of Tx/Rx (a packet was sent or received), This function is
    968 				called and performs BW calculation.
    969 
    970 INPUT:
    971 				pBandWidth		- BW of Rx or Tx
    972 				uCurrentTS		- current TS of the recent event
    973 
    974 OUTPUT:         pBandWidth		- updated counters and TS
    975 
    976 ************************************************************************/
    977 void 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 ***********************************************************************
    995 DESCRIPTION: 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 
    999 INPUT:       pBandWidth		- BW of Rx or Tx
   1000 			 uCurrentTS		- current TS
   1001 
   1002 RETURN:     Total BW
   1003 ************************************************************************/
   1004 TI_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  ***********************************************************************
   1033 DESCRIPTION: 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 
   1039 INPUT:          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 
   1046 OUTPUT:
   1047 
   1048 RETURN:
   1049 
   1050 ************************************************************************/
   1051 void 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  */
   1125 static 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  */
   1136 static void SimpleFrameAggregation(TI_HANDLE TraffElem,int Count)
   1137 {
   1138     TrafficAlertElement_t *AlertElement = TraffElem;
   1139     AlertElement->EventCounter++;
   1140     AlertElement->LastCounte = 1;
   1141 }
   1142 
   1143 /*-----------------------------------------------------------------------------
   1144 Routine Name: TrafficMonitor_UpdateDownTrafficTimerState
   1145 Routine 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.
   1148 Arguments:
   1149 Return Value:
   1150 -----------------------------------------------------------------------------*/
   1151 static 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 /*-----------------------------------------------------------------------------
   1182 Routine Name: TrafficMonitor_ChangeDownTimerStatus
   1183 Routine Description: Start or stop down traffic timer according to number of down events found and minInterval time.
   1184 Arguments:
   1185 Return Value:
   1186 -----------------------------------------------------------------------------*/
   1187 static 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         os_wake_unlock(pTrafficMonitor->hOs);
   1196     }
   1197     else if ((downEventsFound > 0) && (pTrafficMonitor->DownTimerEnabled == TI_FALSE))
   1198     {
   1199         os_wake_lock(pTrafficMonitor->hOs);
   1200         pTrafficMonitor->DownTimerEnabled = TI_TRUE;
   1201         /* Start the timer with user defined percentage of the the minimum interval discovered earlier */
   1202         tmr_StartTimer (pTrafficMonitor->hTrafficMonTimer,
   1203                         TimerMonitor_TimeOut,
   1204                         (TI_HANDLE)pTrafficMonitor,
   1205                         ((minIntervalTime * pTrafficMonitor->trafficDownTestIntervalPercent) / 100),
   1206                         TI_TRUE);
   1207     }
   1208 }
   1209 
   1210 #ifdef TI_DBG
   1211 
   1212 /*-----------------------------------------------------------------------------
   1213 Routine Name: TrafficMonitor_UpdateActiveEventsCounters
   1214 Routine Description:
   1215 Arguments:
   1216 Return Value:
   1217 -----------------------------------------------------------------------------*/
   1218 void TrafficMonitor_UpdateActiveEventsCounters (TI_HANDLE hTrafficMonitor)
   1219 {
   1220 	TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)hTrafficMonitor;
   1221     TrafficAlertElement_t *AlertElement;
   1222     TI_UINT32 activeTrafDownEventsNum = 0;
   1223 
   1224     AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
   1225 
   1226     while(AlertElement)
   1227     {
   1228       if ((AlertElement->Direction == TRAFF_DOWN) && (AlertElement->Trigger == TRAFF_EDGE) && (AlertElement->CurrentState == ALERT_OFF) && (AlertElement->Enabled == TI_TRUE))
   1229       {
   1230          activeTrafDownEventsNum++;
   1231       }
   1232       AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
   1233     }
   1234 
   1235 }
   1236 
   1237 
   1238 #endif
   1239 
   1240 #ifdef TRAFF_TEST
   1241 /*
   1242  *      TEST Function
   1243  */
   1244 void func1(TI_HANDLE Context,TI_UINT32 Cookie)
   1245 {
   1246     switch(Cookie) {
   1247     case 1:
   1248                 WLAN_OS_REPORT(("TRAFF - ALERT UP limit - 50 ON"));
   1249         break;
   1250     case 2:
   1251                 WLAN_OS_REPORT(("TRAFF - ALERT UP limit - 30 ON"));
   1252     break;
   1253     case 3:
   1254                 WLAN_OS_REPORT(("TRAFF - ALERT DOWN limit - 25 ON"));
   1255     break;
   1256     case 4:
   1257                 WLAN_OS_REPORT(("TRAFF - ALERT DOWN limit - 10 ON"));
   1258     break;
   1259    }
   1260 
   1261 }
   1262 
   1263 
   1264 void PrintElertStus()
   1265 {
   1266     TrafficMonitor_t *TrafficMonitor =(TrafficMonitor_t*)TestTrafficMonitor;
   1267     TrafficAlertElement_t *AlertElement  = (TrafficAlertElement_t*)List_GetFirst(TrafficMonitor->NotificationRegList);
   1268 
   1269     /* go over all the Down elements and check for alert ResetElment that ref to TrafficAlertElement*/
   1270     while(AlertElement)
   1271     {
   1272         if(AlertElement->CurrentState == ALERT_WAIT_FOR_RESET)
   1273             WLAN_OS_REPORT(("TRAFF - ALERT ALERT_WAIT_FOR_RESET"));
   1274         else
   1275             WLAN_OS_REPORT(("TRAFF - ALERT ENABLED"));
   1276 
   1277 
   1278         AlertElement = (TrafficAlertElement_t*)List_GetNext(TrafficMonitor->NotificationRegList);
   1279     }
   1280 }
   1281 
   1282 void TestEventFunc (TI_HANDLE hTrafficMonitor, TI_BOOL bTwdInitOccured)
   1283 {
   1284 
   1285     static flag = TI_TRUE;
   1286     TrafficAlertRegParm_t TrafficAlertRegParm ;
   1287     if(flag)
   1288     {
   1289 
   1290         TrafficAlertRegParm.CallBack = func1;
   1291         TrafficAlertRegParm.Context = NULL ;
   1292         TrafficAlertRegParm.Cookie =  1 ;
   1293         TrafficAlertRegParm.Direction = TRAFF_UP ;
   1294         TrafficAlertRegParm.Trigger = TRAFF_EDGE;
   1295         TrafficAlertRegParm.TimeIntervalMs = 1000;
   1296         TrafficAlertRegParm.Threshold = 50;
   1297         TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
   1298         Alert1 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
   1299 
   1300         TrafficAlertRegParm.CallBack = func1;
   1301         TrafficAlertRegParm.Context = NULL ;
   1302         TrafficAlertRegParm.Cookie =  2 ;
   1303         TrafficAlertRegParm.Direction = TRAFF_UP ;
   1304         TrafficAlertRegParm.Trigger = TRAFF_EDGE;
   1305         TrafficAlertRegParm.TimeIntervalMs = 1000;
   1306         TrafficAlertRegParm.Threshold = 30;
   1307         TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
   1308         Alert2 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
   1309 
   1310 
   1311         TrafficAlertRegParm.CallBack = func1;
   1312         TrafficAlertRegParm.Context = NULL ;
   1313         TrafficAlertRegParm.Cookie =  3 ;
   1314         TrafficAlertRegParm.Direction = TRAFF_DOWN ;
   1315         TrafficAlertRegParm.Trigger = TRAFF_EDGE;
   1316         TrafficAlertRegParm.TimeIntervalMs = 1000;
   1317         TrafficAlertRegParm.Threshold = 25;
   1318         TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
   1319         Alert3 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
   1320 
   1321         TrafficAlertRegParm.CallBack = func1;
   1322         TrafficAlertRegParm.Context = NULL ;
   1323         TrafficAlertRegParm.Cookie =  4 ;
   1324         TrafficAlertRegParm.Direction = TRAFF_DOWN ;
   1325         TrafficAlertRegParm.Trigger = TRAFF_LEVEL;
   1326         TrafficAlertRegParm.TimeIntervalMs = 1000;
   1327         TrafficAlertRegParm.Threshold = 10;
   1328         TrafficAlertRegParm.MonitorType = TX_RX_DIRECTED_FRAMES;
   1329         Alert4 = TrafficMonitor_RegEvent(TestTrafficMonitor,&TrafficAlertRegParm,TI_FALSE);
   1330 
   1331        TrafficMonitor_SetRstCondition(TestTrafficMonitor, Alert1,Alert3,TI_TRUE);
   1332        TrafficMonitor_SetRstCondition(TestTrafficMonitor, Alert2,Alert3,TI_FALSE);
   1333        flag = TI_FALSE;
   1334     }
   1335 
   1336     PrintElertStus();
   1337 
   1338 }
   1339 
   1340 #endif
   1341