/************************************************************************************************************** 
	Workfile:   perfhandler.c   
*************************************************************************************************************** 
 
 FIRMWARE,	Copyright (C) 2000-2002 Ikanos Communication, Fremont, CA 
			All rights reserved. 
 
			The information and contents of this file are the proprietary information of Ikanos  
			Communication and may not be disclosed or used without the formal written approval of 
			Ikanos Communication. 
*************************************************************************************************************** 
$Revision: 1.1 $ 
$Date: 2006/10/16 04:34:50 $ 
 
**************************************************************************************************************/ 
 
#include<string.h>  
#include<stdio.h> 
 
#ifndef USE_VXWORKS /* IXDP425 */
#include<v2pthread.h>
#endif
#include "perfconfig.h" 
//#include "app.h" 
//#include "mail.h" 

 
#include "apitype.h" 
#include "msgbuf.h" 
#include "bmeconfig.h" 
#include "apistruct.h" 
#include "appconfig.h" 
#include "portmap.h" 
#include "ipos.h" 
#include "dapi.h" 
#include "apilocal.h" 
#include "linecrc.h"
#include "bmetl.h" 
#include "oampdb.h" /* IXDP425 */
#include "oamp.h" 
#include "eventlog.h" 
#ifdef INI_SUPPORT 
#include "HostPtmfApi.h" 
#endif 
#define _TESTING_ 
 
static struct
{
	U32	secondsWithLOS;
	U32	secondsWithLOF;
	U32	secondsWithSEF;
	U32	secondsWithCRC_F;
	U32	secondsWithCRC_S;
} erroredSecondsPerPort[ MAX_NUM_OF_PORTS + 1 ];

extern oamp_bme oampBme [IPOS_MAX_BME];  				/* BME objects for OAMP   */ 
extern ipos_api_bme	apiBme[IPOS_MAX_BME];   
extern void copyCountersToOamp (ipos_port_counters *pReport,ipos_port_id pid); 
 
/* Function Prototypes */ 
extern int sysClkRateGet (void); 
void taskOneSecPerfHdlr(void); 
void InitPerfPara(int BmeNum, int PortNum); 
void UpdatePerfPara(ipos_port_id pid, U8 uid, U32 upar, int status, ipos_port_counters *pREPORT); 
void EvaluateLosFailure(Failures_T *Failure, FailReport_T *FailReport, BYTE current_value); 
void EvaluateLofFailure(Failures_T *Failure, FailReport_T *FailReport, U16 current_value); 
void EvaluateFeLprFailure(Failures_T *NeFailure, Failures_T *FeFailure, FailReport_T *FeFailReport, BYTE current_value); 
void EvaluateAtmPathFailure(FailStatus_T *Failure, BYTE *FailFlag, BYTE *portalarm, BYTE current_value, BYTE FailActiveThreshold, BYTE FailInactiveThreshold); 
void EvaluateSixPtFailure(Failures_T *Failure,  U8 curSixPtFlag, U8 * lineHoldOk);
void UpdateCounts(ParameterStatus_T *PerfPara, UINT32 *CurrentReg24Hour,BYTE current_value, UINT32 overflow_value); 
void EvaluateErrSeconds(PerfParameters_T *PerfParameter, Failures_T *Failure); 
void EvaluateSevErrSeconds(PerfParameters_T *PerfParameter, Failures_T *Failure); 
void EvaluateFecSeconds(PerfParameters_T *PerfParameter, Failures_T *Failure); 
void EvaluateUnavailableSeconds(PerfParameters_T *PerfParameter, Failures_T *Failure, eLINE_STATE *LineState); 
void PrepareThresholdReport(int BmeNum, int PortNum); 
void GenerateTR1(PerfParameters_T *PerfParameter, ThresholdReport15Min_T *TR1, time_t present_time); 
void GenerateTR2(PerfParameters_T *PerfParameter, ThresholdReport24Hour_T *TR2, time_t present_time); 
void CheckTR1_Thresholds(PerfParameters_T *PerfParameter, TRparameters_T *TR1Parameters, ThresholdReport15Min_T *TR1); 
void CheckTR2_Thresholds(PerfParameters_T *PerfParameter, TRparameters_T *TR2Parameters, ThresholdReport24Hour_T *TR2); 
void StackCurrentReg_TR1(HistoryReg15Min_T *TRparameter); 
void StackCurrentReg_TR2(HistoryReg24Hour_T *TRparameter); 
void Reset15MinCounts(PerfParameters_T  *PerfParameter); 
void Reset24HourCounts(PerfParameters_T  *PerfParameter); 
void *GetThresholdReport(int BmeNum, int PortNum, eReportType report_type); 
void DisplayThresholdReport(eReportType report_type, void *TR); 
UINT32 GetPerfParameter (int BmeNum, int PortNum, eReportType report_type, eParaType parameter_type); 
UINT32 GetCurrentValue(PerfParameters_T *PerfParameter, eParaType parameter_type); 
#ifdef INI_SUPPORT
UINT32 GetINICrcThresStatusFlag(uPortStruct *uEPortStatus, int ethnetPortNum, int ptmfPort,  U8 lineHold6ptOk); 

static unsigned int secondTicks = 0; 

static int ethnetPortNum = 1; 
#endif//ifdef INI_SUPPORT

 
 
static void
initErroredSeconds( int lineNum )
{
	erroredSecondsPerPort[ lineNum ].secondsWithLOS = 0;
	erroredSecondsPerPort[ lineNum ].secondsWithLOF = 0;
	erroredSecondsPerPort[ lineNum ].secondsWithSEF = 0;
	erroredSecondsPerPort[ lineNum ].secondsWithCRC_F = 0;
}

void
incrementErroredSeconds( int lineNum, eErroredSecondsType eEST )
{
	switch (eEST) {
	  case eSecondsWithLOS:
		erroredSecondsPerPort[ lineNum ].secondsWithLOS++;
		break;

	  case eSecondsWithLOF:
		erroredSecondsPerPort[ lineNum ].secondsWithLOF++;
		break;

	  case eSecondsWithSEF:
		erroredSecondsPerPort[ lineNum ].secondsWithSEF++;
		break;

	  case eSecondsWithCRC_F:
		erroredSecondsPerPort[ lineNum ].secondsWithCRC_F++;
		break;

	  default:
		break;
	}
}

U32
getErroredSeconds( int lineNum, eErroredSecondsType eEST )
{
	U32	retval = 0;

	switch (eEST) {
	  case eSecondsWithLOS:
		retval = erroredSecondsPerPort[ lineNum ].secondsWithLOS;
		break;

	  case eSecondsWithLOF:
		retval = erroredSecondsPerPort[ lineNum ].secondsWithLOF;
		break;

	  case eSecondsWithSEF:
		retval = erroredSecondsPerPort[ lineNum ].secondsWithSEF;
		break;

	  case eSecondsWithCRC_F:
		retval = erroredSecondsPerPort[ lineNum ].secondsWithCRC_F;
		break;

	  default:
		break;
	}

	return( retval );
}

void
uiShowErroredSeconds( ipos_port_id pid )
{
	int	lineNum;

	getLineNum( pid, &lineNum );
	if (lineNum < 1 || lineNum > MAX_NUM_OF_PORTS)
	{
		printf( "\nInvalid port b%dp%d\n", pid.bmeNum, pid.portNum );
	}
	else
	{
		printf( "\nport b%dp%d (line number %d)\n", pid.bmeNum, pid.portNum, lineNum );
		printf( "Seconds with LOS: %lu\n", erroredSecondsPerPort[ lineNum ].secondsWithLOS );
		printf( "Seconds with LOF: %lu\n", erroredSecondsPerPort[ lineNum ].secondsWithLOF );
		printf( "Seconds with SEF: %lu\n", erroredSecondsPerPort[ lineNum ].secondsWithSEF );
		printf( "Seconds with CRC: %lu\n", erroredSecondsPerPort[ lineNum ].secondsWithCRC_F );
	}
}
 
void resetPerfPara (ipos_port_id pid) 
{ 
  uPortStruct *pPortStatus = &oampBme[pid.bmeNum].oampPort[pid.portNum].portStatus; 
  Failures_T	*NeFailure = &oampBme[pid.bmeNum].oampPort[pid.portNum].Performance.NeFails; 
 
  pPortStatus->iniCrcTCrossCnt[0] = 0; 
  pPortStatus->iniCrcTCrossCnt[1] = 0;
  pPortStatus->startCnt = 0; 
  NeFailure->Los.fail_state=FAIL_INACTIVE; 
  NeFailure->Los.previous_value = 0; 
  NeFailure->Lof.fail_state=FAIL_INACTIVE; 
  NeFailure->Lof.previous_value = 0; 
  NeFailure->Crc.fail_state=FAIL_INACTIVE; 
    
    
    NeFailure->SixPt.previous_value = 0;
    NeFailure->SixPt.fail_state = FAIL_INACTIVE;
 
} 
 
void clearBmeCounters (ipos_port_id pid) 
{
   // Clear BME counters

  memset(&oampBme[pid.bmeNum].oampPort[pid.portNum].Counters, 0, sizeof(ipos_port_counters));
}

/*************************************************************************************************************** 
	Function	:	InitPrefPara() 
	Description	:	Resets the counters and Alarm bits in the structures. Sets the line to Available State. 
					Calls 'PERIODIC_REPORTS_ENABLE' API call for enabling the periodic reports to be  
					sent by the BME for every 500ms (The failures can be declared with +/- 0.5 sec tolerance). 
					 
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value:	eApiRv  
 
***************************************************************************************************************/ 
void InitPerfPara(int BmeNum, int PortNum) 
{ 
	ipos_port_id	pid; 
	int		lineNum;
	 
	/* Initially configure the line to be in Available State */ 
	oampBme[BmeNum].oampPort[PortNum].Performance.NeLineState = AVAILABLE; 
	oampBme[BmeNum].oampPort[PortNum].Performance.FeLineState = AVAILABLE; 
 
	/* Initialise the near and far end failures for the port to zero */ 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.NeFails, 0, sizeof(Failures_T)); 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.NeFails, 0, sizeof(Failures_T)); 
 
	/* Initialise the near and far end failure reports for the port to zero */ 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.NeFailReport, 0, sizeof(FailReport_T)); 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.FeFailReport, 0, sizeof(FailReport_T)); 
 
	/* Initialise the near and far end Performance Parameters for the port to zero */ 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.NePerfPara, 0, sizeof(PerfParameters_T)); 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.FePerfPara, 0, sizeof(PerfParameters_T)); 
 
	/* Initialise the near and far end 15 Minute threshold report paramters to zero */ 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.NeTRpara15Min, 0, sizeof(TRparameters_T)); 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.FeTRpara15Min, 0, sizeof(TRparameters_T)); 
 
	/* Initialise the near and far end 24 hour threshold report paramters to zero */ 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.NeTRpara24Hour, 0, sizeof(TRparameters_T)); 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.FeTRpara24Hour, 0, sizeof(TRparameters_T)); 
 
	/* Initialise the near and far end 15 Minute threshold reports to zero */ 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.Ne15MinTR, 0, sizeof(ThresholdReport15Min_T)); 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.Ne15MinTR, 0, sizeof(ThresholdReport15Min_T)); 
 
	/* Initialise the near and far end 24 Minute threshold reports for the port to zero */ 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.Ne24HourTR, 0, sizeof(ThresholdReport24Hour_T)); 
	memset(&oampBme[BmeNum].oampPort[PortNum].Performance.Fe24HourTR, 0, sizeof(ThresholdReport24Hour_T)); 
 
	pid.bmeNum=BmeNum; 
	pid.portNum=PortNum; 
 
    iposSetCbCntReport(pid, 0, UpdatePerfPara); 
 
	/* Initialise are Counters set by BME */ 
	//memset(&apiBme[BmeNum].pBme->Port[PortNum].PortParms.GetCounterParms, 0, sizeof(struct tGetCounters)); 
 
	/* Enable periodic reports to be sent by BME */ 
 
	//apiBme[BmeNum].pBme->Port[PortNum].PortParms.PerReportParms.ReportsEnable = ( ENABLE_PERIODIC_REPORTS | ENABLE_ALARM_COUNTERS | ENABLE_SYSTEM_STATUS); 
	//apiBme[BmeNum].pBme->Port[PortNum].PortParms.PerReportParms.AlarmCountFreq = 0xf4;  
	//apiBme[BmeNum].pBme->Port[PortNum].PortParms.PerReportParms.SystemStatusFreq = 0xf4;  
 		 
	getLineNum( pid, &lineNum );
	initErroredSeconds( lineNum );

  // Initialize PM Handler
  //InitPMHandler(BmeNum, PortNum);
  
} 
	 
void ResetCrcThresCnt(ipos_port_id pid) 
{ 
  uPortStruct *pPortStatus; 
 
  pPortStatus = &oampBme[pid.bmeNum].oampPort[pid.portNum].portStatus; 
 
  pPortStatus->iniCrcTCrossCnt[0] = 0; 
  pPortStatus->iniCrcTCrossCnt[1] = 0;
  pPortStatus->iniCrcCnt[0] = 0; 
  pPortStatus->iniCrcCnt[1] = 0;
 
} 
 
 
/*************************************************************************************************************** 
	Function	:	UpdatePerfPara() 
	Description	:	1.	Evaluates 'Alarms' based on the presence of 'defects or anomalies' given by BME, over a period  
						of time, both at near end and far end for the port. The failures which are evaluated are 
							1. Loss of Signal 
							2. Loss of Frame 
							3. Loss of Power at the Far End. 
							4. And ATM Path Related Failures viz NCD, LCD,  
						 
						A 'PortAlarm' flag is set upon recognisation of an Alarm.  
 
					2.	Updates the current register contents for the performance  parameters if the parameter  
						is not inhibited. Accumulation of some of the parameters are inhibited during Unavailable 
						seconds. 
				 
				  This is called periodically from the Port task whenever it gets data(counters) form BME.	 
 
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value:	 
 
***************************************************************************************************************/ 
 
void UpdatePerfPara(ipos_port_id pid, U8 uid, U32 upar, int status, ipos_port_counters *pREPORT)  
{ 
 
  uPortStruct *pPortStatus; 

 
	BYTE current_value; 
	PerfParameters_T *NePerfParameter, *FePerfParameter; 
	Failures_T	*NeFailure, *FeFailure; 
	FailReport_T *NeFailureReport, *FeFailureReport; 
	BYTE PortState;				/* Gives the present Port Staus */ 
	//int crcTCrossFlag = 0;
        int lineNum/*, ptmfPort, i*/;
        //int IniIndex, IniFast, IniSlow; 
    S32 deltaSEF;
#ifdef INI_SUPPORT
  int IniIndex, IniFast, IniSlow; 
  int ptmfPort, i;
  int crcTCrossFlag = 0;
#endif
    U8  okLineHold6Pt = FALSE;  
 
  /* update CRC errored seconds BEFORE calling copyCountersToOamp */

	getLineNum (pid, &lineNum);

	if ((pREPORT->NeCRC_F != oampBme[pid.bmeNum].oampPort[pid.portNum].Counters.NeCRC_F) ||
        (pREPORT->NeCRC_S != oampBme[pid.bmeNum].oampPort[pid.portNum].Counters.NeCRC_S)) 
	    incrementErroredSeconds( lineNum, eSecondsWithCRC_F );

	copyCountersToOamp (pREPORT,pid); 
 
 
	/* Read the present Port status */ 
	PortState = oampBme[pid.bmeNum].oampPort[pid.portNum].portState; 
	 
	if( !(PortState & uSHOWTIME) ) 
	{ 
//		 printf("\n Port is not in ShowTime"); 
		return; 
	} 
	 
	//EventLog ("b%ip%i UpdatePerfPara LOS defect %i",pid.bmeNum,pid.portNum,pREPORT->NeLOS); 
	 
	NePerfParameter = &oampBme[pid.bmeNum].oampPort[pid.portNum].Performance.NePerfPara; 
	FePerfParameter = &oampBme[pid.bmeNum].oampPort[pid.portNum].Performance.FePerfPara; 
	 
	NeFailure = &oampBme[pid.bmeNum].oampPort[pid.portNum].Performance.NeFails; 
	FeFailure = &oampBme[pid.bmeNum].oampPort[pid.portNum].Performance.FeFails; 
 
	NeFailureReport = &oampBme[pid.bmeNum].oampPort[pid.portNum].Performance.NeFailReport; 
	FeFailureReport = &oampBme[pid.bmeNum].oampPort[pid.portNum].Performance.FeFailReport; 
 
/* -------------------------FAILURE DETECTION FOR LINE RELATED PARAMETERS ---------------------------------- */ 

	/* update errored seconds BEFORE calling EvaluateLofFailure or EvaluateLosFailure */

	if (pREPORT->NeLOS != NeFailure->Los.previous_value)
	  incrementErroredSeconds( lineNum, eSecondsWithLOS );

	/* mimic EvaluateLofFailure */

	deltaSEF = (S32) (pREPORT->NeSEF) - (S32) (NeFailure->Lof.previous_value);
	if (deltaSEF < 0)
	  deltaSEF += 0x10000;
	if (deltaSEF != 0)
	  incrementErroredSeconds( lineNum, eSecondsWithSEF );
	if (deltaSEF >= LOF_DELTA_THRESHOLD)
	  incrementErroredSeconds( lineNum, eSecondsWithLOF );
 
	/* Get the present counter value for near end LOS defects */ 
	current_value = pREPORT->NeLOS; 
 
    EvaluateSixPtFailure(NeFailure, (U8) pREPORT->sixPtLineHold, &okLineHold6Pt);  //Do this before everything cos it may enable/disable drop the line
  EvaluateLofFailure(NeFailure, NeFailureReport, pREPORT->NeSEF); 
 
	/* Evaluate the Near End LOS failure */ 
	EvaluateLosFailure( NeFailure, NeFailureReport, current_value); 
   
	/* Evaluate the Far End LPR failure */ 
	EvaluateFeLprFailure( NeFailure, FeFailure, FeFailureReport, pREPORT->FeLPR); 
   
//    printf("\n >P%d,lineHoldFlag:%d okLineHold6Pt:%d",pid.portNum, pREPORT->sixPtLineHold, okLineHold6Pt ); 
  /* Evaluate CRC threshold */ 
	if ( (evalLineCrc (pid, pREPORT->NeCRC_F, pREPORT->NeCRC_S)) &&
         (evalSixPtLineHold(okLineHold6Pt) == 0) )
    {
	  NeFailure->Crc.fail_state = FAIL_ACTIVE;
    }

  /* Evaluate INI CRC threshold */ 
  pPortStatus = &oampBme[pid.bmeNum].oampPort[pid.portNum].portStatus; 
 
  getLineNum (pid, &lineNum); 
 
#ifdef INI_SUPPORT 
  //getIniPhy (lineNum, &ptmfPort); 
  getIniMap(pid, &IniIndex, &IniSlow, &IniFast);  
 
  if (IniFast != IniSlow) 
      ethnetPortNum = 2; 
  
  for (i = 0; i<ethnetPortNum; i++) 
  { 
     ptmfPort = IniIndex + i;	
     crcTCrossFlag = GetINICrcThresStatusFlag(pPortStatus, i, ptmfPort,okLineHold6Pt);    
  } 
 
   
#endif 
 
  if (((NeFailure->Los.fail_state == FAIL_ACTIVE) 
       || (NeFailure->Lof.fail_state == FAIL_ACTIVE) 
			 || (NeFailure->Crc.fail_state == FAIL_ACTIVE)
			 || (NeFailure->LPR.fail_state == FAIL_ACTIVE)
#ifdef INI_SUPPORT 
       || (crcTCrossFlag !=0)/*(pPortStatus->iniCrcTCrossCnt >= 5)*/ 
#endif 
      ) && (PortState == uSHOWTIME)) 
  { 
    if (FeFailure->LPR.fail_state == FAIL_ACTIVE) 
    {
      UserLog ("Bme %i Port %i LPR failure detected.",pid.bmeNum,pid.portNum); 
      printf ("\nb%dp%d LPR failure detected\n",pid.bmeNum,pid.portNum); 
    } 
    else if (NeFailure->Los.fail_state == FAIL_ACTIVE) 
    { 
      UserLog ("Bme %i Port %i LOS failure detected.",pid.bmeNum,pid.portNum); 
      printf ("\nb%dp%d LOS failure detected\n",pid.bmeNum,pid.portNum); 
    } 
    else  if (NeFailure->Lof.fail_state == FAIL_ACTIVE) 
      { 
        UserLog ("Bme %i Port %i LOF failure detected.",pid.bmeNum,pid.portNum); 
        printf ("\nb%dp%d LOF failure detected\n",pid.bmeNum,pid.portNum); 
      }
    else if (NeFailure->Crc.fail_state == FAIL_ACTIVE) 
				{ 
					UserLog ("Bme %i Port %i CRC failure detected.",pid.bmeNum,pid.portNum); 
					printf ("\nb%dp%d CRC failure detected\n",pid.bmeNum,pid.portNum); 
				}
#ifdef INI_SUPPORT 
      else 
      { 
        UserLog ("Bme %i Port %i INI CRC threshold crossing detected.", 
                 pid.bmeNum, pid.portNum); 
        printf ("\nb%dp%d INI CRC threshold crossing detected\n", 
                pid.bmeNum, pid.portNum); 
      } 
#endif 
     
    resetPerfPara(pid); 
    pPortStatus->status |= uDOWN; 
 
    // Notify OAMP to re-start line 
	  oampBme[pid.bmeNum].oampPort[pid.portNum].portState=uSTOP; 
  } 
} 
 
/****************************************************************************************************************** 
	Function	:	EvaluateLosFailure() 
	Description	:	This function analyses the successive LOS( Loss Of Signal) defects or anomalies. If the defect  
					is present contiguously for TS1 seconds, or if LOS defect is present when the criteria for LOF  
					Failure declaration have been met, it will be considered as a failure. If there is no change  
					between the previous count and present count for about TS2 seconds after the failure has been  
					noticed, the failure will be cleared.  
				 
					This is called for both Near End and Far End 'LOS' defect Analysis. 
 
	Parameters	:	Pointer to the Failures structure, a pointer to Failure Report and present value of the counter.  
	Return Value:	-- 
 
******************************************************************************************************************/ 
 
void EvaluateLosFailure(Failures_T *Failure, FailReport_T *FailReport, BYTE current_value) 
{ 
 
 
	short delta_value=0; 
	 
	time_t present_time;		/* Time in seconds */ 
	 
 
	delta_value = (short)current_value-(short)Failure->Los.previous_value; 
 
	if (delta_value<0) delta_value+=256; 
	 
	switch( Failure->Los.fail_state) 
	{ 
		case FAIL_INACTIVE	:		 
							/* If there is any defect in the parameter being monitored */ 
							if(delta_value >= LOS_DELTA_THRESHOLD) 
							{ 
								 
								Failure->Los.fail_state = DEFECT_START; 
								Failure->Los.defect_start_time= time(&present_time); 
							} 
							break; 
 
		case DEFECT_START	:	 
 
							/*	If the line started coming to normal condition before reaching the 'Failure' state,  
								reset the counter  */ 
							if(delta_value < LOS_DELTA_THRESHOLD) 
							{ 
								Failure->Los.fail_state = FAIL_INACTIVE; 
							}		 
							else 
							{ 
                /*	Check whether LOF (Loss of frame) failure is present, while there is LOS defect. 
                  If so declare LOS.  */  
								/* Failure Evaluation */ 
								if ((Failure->Lof.fail_state == FAIL_ACTIVE) || 
                    (difftime( time(&present_time), Failure->Los.defect_start_time) >= TS1 )) 
								{ 
									/* Declare the Alarm/failure */ 
									Failure->Los.fail_state = FAIL_ACTIVE; 
									/* Declare the alarm */ 
									FailReport->LossOfSignal = TRUE; 
 
									/*	Set the Port Alarm, if not set,to indicate that the presence of a Failure on the port  
										This is reset after declaring the alarms to Management Unit */ 
									if(!FailReport->PortAlarm) 
										FailReport->PortAlarm = TRUE; 
								} 
							}			 
							break; 
 
		case FAIL_ACTIVE	: 
							//printf("\n Error Count = %d",delta_value); 
							if(delta_value < LOS_DELTA_THRESHOLD) 
							{ 
								Failure->Los.fail_state = DEFECT_STOP; 
								Failure->Los.defect_stop_time= time(&present_time);	 
 							} 
							break; 
 
		case DEFECT_STOP	: 
							if(delta_value >= LOS_DELTA_THRESHOLD) 
								Failure->Los.fail_state = FAIL_ACTIVE; 
 
							else if( difftime( time(&present_time), Failure->Los.defect_stop_time) >= TS2 ) 
							{ 
								Failure->Los.fail_state = FAIL_INACTIVE; 
 
								/* Clear the alarm */ 
								FailReport->LossOfSignal = FALSE; 
 
								/*	Set the Port Alarm, if not set,to indicate that an alarm has been cleared  
									on the port.This is reset after declaring the alarms to Management Unit */ 
 
								if(!FailReport->PortAlarm) 
									FailReport->PortAlarm = TRUE; 
							} 
							break; 
 
		default			: 
							break; 
	} 
 
	/* Update the previous value */ 
	Failure->Los.previous_value = current_value; 
} 
	 
 
/**************************************************************************************************************** 
	Function	:	EvaluateLofFailure() 
	Description	:	This function analyses the successive SEF( Severely Errored Frames) defects or anomalies.If  
					the defect is present contiguously for TF1 seconds, it will be considered as a failure, except  
					when LOS defect or Failure is present. If there is no  change between the previous count and  
					present count for about TF2 seconds after the failure is noticed, or when LOS failure is  
					declared, the LOF failure will be cleared.  
				 
					This is called for both Near End and Far End 'LOF' defect Analysis. 
 
	Parameters	:	Pointer to the Failures structure, a pointer to Failure Report and present value of the counter.  
	Return Value:	-- 
 
****************************************************************************************************************/ 
 
 
void EvaluateLofFailure(Failures_T *Failure, FailReport_T *FailReport, U16 current_value) 
{ 
	S32 delta_value=0; 
	time_t present_time;		/* Time in seconds */ 
 
	delta_value = (S32)current_value-(S32)Failure->Lof.previous_value; 
	//printf("\nCur %d Prev %d",current_value,Failure->Los.previous_value); 
 
	if (delta_value<0) delta_value+=0x10000; 
	 
	switch( Failure->Lof.fail_state) 
	{ 
		case FAIL_INACTIVE	:	 
							/* If there is any defect in the parameter being monitored */ 
							if(delta_value >= LOF_DELTA_THRESHOLD) 
							{ 
								Failure->Lof.fail_state = DEFECT_START; 
								Failure->Lof.defect_start_time= time(&present_time); 
							} 
							break; 
 
		case DEFECT_START	:	 
 
							/*	If the line started coming to normal condition before reaching the 'Failure' state,  
								reset the counter  */ 
							if( delta_value  < LOF_DELTA_THRESHOLD) 
							{ 
								Failure->Lof.fail_state = FAIL_INACTIVE; 
							} 
							 
							else	/* Failure Evaluation */ 
							{ 
								/*	Check whether the defect has been present contiguously for TS1 Seconds,  
									to be declared as failure. TS1 : Threshold value in seconds */  
								if( difftime( time(&present_time), Failure->Lof.defect_start_time) >= TF1 ) 
								{ 
									/* If LOS (Loss of Signal) defect or failure is present, don't declare LOF */  
									if( (Failure->Los.fail_state == DEFECT_START)  || (Failure->Los.fail_state == FAIL_ACTIVE) ) 
									{		 
										Failure->Lof.fail_state = FAIL_INACTIVE; 
									} 
 
									else 
									{ 
										/* Declare the Alarm/failure */ 
										Failure->Lof.fail_state = FAIL_ACTIVE; 
 
										/* Declare the alarm */ 
										FailReport->LossOfFrame = TRUE; 
 
										/*	Set the Port Alarm, if not set,to indicate the presence of an alarm on the  
											port.This is reset after declaring the alarms to Management Unit */ 
 
										if(!FailReport->PortAlarm) 
											FailReport->PortAlarm = TRUE; 
									} 
								} 
								 
							} 
							break; 
 
		case FAIL_ACTIVE	: 
							/* If LOS (Loss of Signal) failure is declared, Clear LOF failure */  
							if(Failure->Los.fail_state == FAIL_ACTIVE) 
							{ 
								Failure->Lof.fail_state = FAIL_INACTIVE; 
 
								/* Clear the alarm */ 
								FailReport->LossOfFrame=0; 
								/*	Set the Port Alarm, if not set,to indicate that an alarm has been cleared  
									on the port.This is reset after declaring the alarms to Management Unit */ 
 
								if(!FailReport->PortAlarm) 
									FailReport->PortAlarm = TRUE; 
							} 
 
							else if(delta_value < LOF_DELTA_THRESHOLD) 
							{ 
								Failure->Lof.fail_state = DEFECT_STOP; 
								Failure->Lof.defect_stop_time= time(&present_time);	 
							} 
 
							break; 
 
		case DEFECT_STOP	:	 
							if(delta_value >= LOF_DELTA_THRESHOLD) 
							{ 
								Failure->Lof.fail_state = FAIL_ACTIVE; 
							}	 
 
							else if( difftime( time(&present_time), Failure->Lof.defect_stop_time) >= TF2 ) 
							{ 
								Failure->Lof.fail_state = FAIL_INACTIVE; 
								 
								/* Clear the alarm */ 
								FailReport->LossOfFrame = FALSE; 
 
								/*	Set the Port Alarm, if not set,to indicate that an alarm has been cleared  
									on the port.This is reset after declaring the alarms to Management Unit */ 
								if(!FailReport->PortAlarm) 
									FailReport->PortAlarm = TRUE; 
							} 
							break; 
 
		default				: 
							break; 
	} 
 
	/* Update the previous value */ 
	Failure->Lof.previous_value = current_value; 
} 
	 
 
//
//Use this mechanism to do a higher layer sixpt override  monitor timer
//

#define SIXPT_OVERRIDE_TMO      (100)//in seconds

void EvaluateSixPtFailure(Failures_T *Failure,  U8 curSixPtFlag, U8 * lineHoldOk)  
{
    time_t present_time;        /* Time in seconds */ 


    U8 sixPtOverride = 0;  //local Output of the FSM

    switch (Failure->SixPt.fail_state)
    {
        case FAIL_INACTIVE :
            if(curSixPtFlag == 1)
            {
                Failure->SixPt.fail_state = DEFECT_START; 
                Failure->SixPt.defect_start_time= time(&present_time); 
            }

            break;

        case DEFECT_START :    
            if(curSixPtFlag == 0)
            {
                Failure->SixPt.fail_state = FAIL_INACTIVE; 
            }
            else
            {
                if (difftime( time(&present_time), Failure->SixPt.defect_start_time) >= SIXPT_OVERRIDE_TMO)
                {
                    Failure->SixPt.fail_state = DEFECT_STOP;  //override state
                    sixPtOverride = 1;
                }
            }

            break;

        case DEFECT_STOP :  //Override sixPT state..

            if(curSixPtFlag == 0)
            {
                Failure->SixPt.fail_state = FAIL_INACTIVE;

            }
            else
            {
                sixPtOverride = 1;
            }
            break;

        default     :
            break;
    }

   if ( (curSixPtFlag == 1) && (sixPtOverride == 0) )
        *lineHoldOk = TRUE;
   else
        *lineHoldOk = FALSE;

}

/****************************************************************************** 
	Function	:	EvaluateFeLprFailure() 
	Description	:	This function analyses the occurence of Far End LPR
                    (Loss Of Power) primitive followed by successive near end
                    LOS( Loss Of Signal) defect or anomalies for TS1 Seconds.
                    If the LOS failure has been declared afer this, Fe LPR will
                    be considered as a failure. If LOS failure is cleared, then  
					Far end LPR will also be cleared.						 
 
					This is called only for Far End 'LPR' defect Analysis. There
                    is no near end LPR. 
 
	Parameters	:	Pointer to the Near End Failures structure, a pointer to Near
                    End Failures structure,  
					a pointer to Failure Report and present value of the counter. 
	Return Value:	-- 
 
******************************************************************************/ 
void EvaluateFeLprFailure(Failures_T *NeFailure, Failures_T *FeFailure, FailReport_T *FeFailReport, BYTE current_value) 
{ 
    time_t present_time;		/* Time in seconds */ 
 
	switch( FeFailure->LPR.fail_state)	/* Far End failure only */ 
	{ 
		case FAIL_INACTIVE	:	 
							/* If Far End LPR defect hasn't been reported yet */ 
							if(current_value  != FeFailure->LPR.previous_value) 
        {
            if (NeFailure->Los.fail_state == FAIL_ACTIVE
                /* || NeFailure->Lof.fail_state == FAIL_ACTIVE */ )
                FeFailure->LPR.fail_state = FAIL_ACTIVE;
            else
								FeFailure->LPR.fail_state = DEFECT_START; 
            FeFailure->LPR.defect_start_time = time(&present_time);
        }
							break; 
 
		case DEFECT_START	:	 
        /* If NeLOS failure has been declared, declare FeLPR */
        if (NeFailure->Los.fail_state == FAIL_ACTIVE
               /*  || NeFailure->Lof.fail_state == FAIL_ACTIVE */ )
							{ 
								FeFailure->LPR.fail_state = FAIL_ACTIVE; 
 
								/* Clear the alarm */ 
								FeFailReport->LossOfPower = TRUE; 
 
            /* Set the Port Alarm, if not set,to indicate the
             * presence of an alarm on the port. This is reset
             * after declaring the alarms to Management Unit
             */
								if(!FeFailReport->PortAlarm) 
									FeFailReport->PortAlarm = TRUE; 
							}	 
        else if(current_value == FeFailure->LPR.previous_value)
        {
            /* We still haven't seen LOS.
             * Reset the LPR state to FAIL_INACTIVE */
            if (difftime( time(&present_time), FeFailure->LPR.defect_start_time) >= 8*TS1 )
            {
                FeFailure->LPR.fail_state = FAIL_INACTIVE;
                FeFailReport->LossOfPower = FALSE;
            }
        }
							break; 
 
		case FAIL_ACTIVE	:	 
							/* If Near End LOS is clearned clear Far end Loss of power */	 
							if(NeFailure->Los.fail_state == FAIL_INACTIVE) 
							{ 
								FeFailure->LPR.fail_state = FAIL_INACTIVE; 
 
								/* Clear the alarm */ 
								FeFailReport->LossOfPower = FALSE; 
 
            /* 
             * Set the Port Alarm, if not set,to indicate that an alarm has
             * been cleared on the port. This is reset after declaring the
             * alarms to Management Unit.
             */
 
								if(!FeFailReport->PortAlarm) 
									FeFailReport->PortAlarm = TRUE; 
							} 
							break; 
 
		case DEFECT_STOP	:	 
							break; 
 
		default			: 
							break; 
	} 
 
	/* Update the counter */ 
	FeFailure->LPR.previous_value = current_value; 
} 
 
/************************************************************************************************************************ 
	Function	:	EvaluateAtmPathFailure() 
	Description	:	This function analyses the successive NCD( No Cell dilineation) or LCD (Loss of Cell dilineation)  
					defects or anomalies.  If the defect is present contiguously for first Threshold 
					(in seconds), it will be considered as a failure. If there is no change between the previous count  
					and present count for Second Threshold (in seconds) contiguously after the failure is noticed, the  
					failure will be cleared.  
				 
					This is called for both Near End and Far End ATM path related defect Analysis for slow and fast data. 
 
	Parameters	:	Pointer to the FailStatus structure, a pointer to Failure Report, current counter value,  
					threshold values for declaring alarms. 
 
	Return Value:	-- 
 
************************************************************************************************************************/ 
 
void EvaluateAtmPathFailure(FailStatus_T *Failure, BYTE *FailFlag, BYTE *portalarm, BYTE current_value, BYTE FailActiveThreshold, BYTE FailInactiveThreshold) 
{ 
	time_t present_time;		/* Time in seconds */ 
 
	switch( Failure->fail_state) 
	{ 
		case FAIL_INACTIVE	:	 
							/* If there is any defect in the parameter being monitored */ 
							if(current_value  != Failure->previous_value) 
							{ 
								Failure->fail_state = DEFECT_START; 
								Failure->defect_start_time= time(&present_time); 
							} 
							break; 
 
		case DEFECT_START	:	 
 
							/*	If the line started coming to normal condition before reaching the 'Failure' state,  
								reset the counter  */ 
							if( current_value  == Failure->previous_value) 
								Failure->fail_state = FAIL_INACTIVE; 
							else 
							{ 
								/* Failure Evaluation */ 
								/*	Check whether the defect has been present contiguously for TS1 Seconds,  
									to be declared as failure. TS1 : Threshold value in seconds */  
								if( difftime( time(&present_time), Failure->defect_start_time) >= FailActiveThreshold) 
								{ 
									/* Declare the Alarm/failure */ 
									Failure->fail_state = FAIL_ACTIVE; 
 
									/* Declare the alarm */ 
									*FailFlag = TRUE; 
 
									/*	Set the Port Alarm, if not set,to indicate the presence of an alarm  
										on the port.This is reset after declaring the alarms to Management Unit */ 
									if(!*portalarm) 
										*portalarm= TRUE; 
								} 
							}	 
							break; 
 
		case FAIL_ACTIVE	:	 
							 
							if(current_value  ==  Failure->previous_value) 
							{ 
								Failure->fail_state = DEFECT_STOP; 
								Failure->defect_stop_time= time(&present_time);	 
							} 
 
							break; 
 
		case DEFECT_STOP	:	 
							if(current_value  !=  Failure->previous_value) 
								Failure->fail_state = FAIL_ACTIVE; 
 
							else if( difftime( time(&present_time), Failure->defect_stop_time) >= FailInactiveThreshold)  
							{ 
								Failure->fail_state = FAIL_INACTIVE; 
								 
								/* Clear the alarm */ 
								*FailFlag = FALSE; 
 
								/*	Set the Port Alarm, if not set,to indicate that an alarm has been cleared 
									on the port.This is reset after declaring the alarms to Management Unit */ 
								if(!*portalarm) 
									*portalarm = TRUE; 
							} 
							break; 
 
		default				: 
							break; 
	} 
 
	/* Update the previous value */ 
	Failure->previous_value = current_value; 
} 
 
/***************************************************************************************************************** 
	Function	:	UpdateCounts() 
	Description	:	Updates (stores the value in the current registers of 15 Min and 24 hour) counts(anamolies)for  
					the port, provided particular parameter accumulation is not inhibited. Certain Parameter counts 
					are inhibited when the line is declared as unavailable. 
										 
					This is called for both Near End and Far End Counts updation.  
 
	Parameters	:	Pointer to the Performance perameter status structure, corresponding 24 hour current register, 
					and present value of the counter got from BME. 
	Return Value:	-- 
 
 ******************************************************************************************************************/ 
 
void UpdateCounts(ParameterStatus_T *PerfPara, UINT32 *CurrentReg24Hour, BYTE current_value, UINT32 overflow_value) 
{ 
	/*  If FEC count is NOT inhibited for this port */ 
	if(!PerfPara->inhibited) 
	{ 
		/* If there is any change in the current value w.r.t previous value */ 
		if (current_value  != PerfPara->previous_value) 
		{ 
			if( current_value  > PerfPara->previous_value) 
			{ 
				PerfPara->current_reg += (UINT32) (current_value - PerfPara->previous_value); 
				*CurrentReg24Hour += (UINT32) (current_value - PerfPara->previous_value); 
			} 
			else 
			{ 
				/* BME counter (byte counter) over flows after reaching maximum value */ 
				PerfPara->current_reg += (UINT32) ((overflow_value- PerfPara->previous_value) + current_value); 
				*CurrentReg24Hour += (UINT32) ((overflow_value- PerfPara->previous_value) + current_value); 
			} 
			 
			/* Update the counter */ 
			PerfPara->previous_value = current_value; 
#ifdef _DEBUG_ 
			printf("\n Curren Value : %d", PerfPara->current_reg); 
#endif 
		} 
	} 
	else 
	{ 
		PerfPara->previous_value = current_value; 
#ifdef _DEBUG_ 
		printf("\n Counts are INHIBITED "); 
#endif 
	} 
} 
 
 
/*************************************************************************************************************** 
	Function	:	EvaluateErrSeconds() 
	Description	:	It evaluates the 1-second intervals with one or more CRC-8 anomalies, or one or more LOS  
					defects, or one or more LPR defects.   
	Parameters	:	A pointer to the Performance Parameter structure and a pointer to Failures structure for the 
					port selected.	 
	Return Value:	 
 
***************************************************************************************************************/ 
	 
 
void EvaluateErrSeconds(PerfParameters_T *PerfParameter, Failures_T *Failure) 
{ 
	UINT32 new_value; 
	if( (Failure->Los.fail_state == DEFECT_START) || (Failure->Los.fail_state == FAIL_ACTIVE)  
		|| ( (PerfParameter->CvSlow15Min.current_reg - PerfParameter->CvSlow15Min.old_count) >= MAX_CRC_ERRORS_FOR_ES) 
		|| ( (PerfParameter->CvFast15Min.current_reg - PerfParameter->CvFast15Min.old_count) >= MAX_CRC_ERRORS_FOR_ES)) 
	{ 
		if(!PerfParameter->ErrSecond15Min.fail_onesecond_flag) 
		{ 
			PerfParameter->ErrSecond15Min.fail_onesecond_flag = TRUE; 
#ifdef _DEBUG_	 
			printf("\n Errored Seconds Had Started");			 
#endif 
		} 
 
		else 
		{ 
			new_value = PerfParameter->ErrSecond15Min.current_reg+1; 
#ifndef _DEBUG_	 
			printf("\n Errored Seconds 15 Min= %ld", PerfParameter->ErrSecond15Min.current_reg+1);			 
#endif 
			 
			/* Check for overflow of the counter */ 
			if(new_value < PerfParameter->ErrSecond15Min.current_reg++) 
				PerfParameter->ErrSecond15Min.overflow_flag = TRUE; 
 
			new_value = PerfParameter->ErrSecond24Hour.current_reg+1; 
#ifndef _DEBUG_	 
			printf("\n Errored Seconds 24 Hour= %ld", PerfParameter->ErrSecond24Hour.current_reg+1);			 
#endif 
			 
			/* Check for overflow of the counter */ 
			if(new_value < PerfParameter->ErrSecond24Hour.current_reg++) 
				PerfParameter->ErrSecond24Hour.overflow_flag = TRUE; 
		}	 
		 
	} 
	else 
		PerfParameter->ErrSecond15Min.fail_onesecond_flag = FALSE; 
} 
	 
/*************************************************************************************************************** 
	Function	:	EvaluateSevereErrSeconds() 
	Description	:	It evaluates the 1-second intervals with 18 or more CRC-8 anomalies, or one or more LOS  
					defects, or one or more LPR defects.   
	Parameters	:	A pointer to the Performance Parameter structure and a pointer to Failures structure for the 
					port selected.	 
	Return Value:	 
 
***************************************************************************************************************/ 
	 
void EvaluateSevereErrSeconds( PerfParameters_T *PerfParameter, Failures_T *Failure) 
{ 
	UINT32 new_value; 
	if( (Failure->Los.fail_state == DEFECT_START) || (Failure->Los.fail_state == FAIL_ACTIVE)  
		|| ( (PerfParameter->CvSlow15Min.current_reg - PerfParameter->CvSlow15Min.old_count) >= MAX_CRC_ERRORS_FOR_SES)  
		|| ( (PerfParameter->CvFast15Min.current_reg - PerfParameter->CvFast15Min.old_count) >= MAX_CRC_ERRORS_FOR_SES) )  
	{ 
		if(!PerfParameter->SevErrSecond15Min.fail_onesecond_flag) 
			PerfParameter->SevErrSecond15Min.fail_onesecond_flag = TRUE; 
		else 
		{ 
			new_value = PerfParameter->SevErrSecond15Min.current_reg+1; 
			 
			/* Check for overflow of the counter */ 
			if(new_value < PerfParameter->SevErrSecond15Min.current_reg++ ) 
				PerfParameter->SevErrSecond15Min.overflow_flag = TRUE; 
			 
			new_value = PerfParameter->SevErrSecond24Hour.current_reg+1; 
			 
			/* Check for overflow of the counter */ 
			if(new_value < PerfParameter->SevErrSecond24Hour.current_reg++ ) 
				PerfParameter->SevErrSecond24Hour.overflow_flag = TRUE; 
		} 
		 
	} 
	else 
		PerfParameter->SevErrSecond15Min.fail_onesecond_flag = FALSE; 
} 
	 
/*************************************************************************************************************** 
	Function	:	EvaluateFecSeconds() 
	Description	:	It counts the 1-second intervals with one or more FEC-8 anomalies. 
	Parameters	:	A pointer to the Performance Parameter structure and a pointer to Failures structure for the 
					port selected.	 
	Return Value:	 
***************************************************************************************************************/ 
	 
void EvaluateFecSeconds(PerfParameters_T *PerfParameter, Failures_T *Failure) 
{ 
	UINT32 new_value; 
	if( (PerfParameter->FecSlow15Min.current_reg - PerfParameter->FecSlow15Min.old_count) >= 1)  
	{ 
		if(	!PerfParameter->FecSecond15Min.fail_onesecond_flag) 
			PerfParameter->FecSecond15Min.fail_onesecond_flag = TRUE; 
		else 
		{ 
			new_value = PerfParameter->FecSecond15Min.current_reg+1; 
			 
			/* Check for overflow of the counter */ 
			if(new_value < PerfParameter->FecSecond15Min.current_reg++) 
				PerfParameter->FecSecond15Min.overflow_flag = TRUE; 
 
			new_value = PerfParameter->FecSecond24Hour.current_reg+1; 
			 
			/* Check for overflow of the counter */ 
			if(new_value < PerfParameter->FecSecond24Hour.current_reg++ ) 
				PerfParameter->FecSecond24Hour.overflow_flag = TRUE; 
		} 
	}  
	else 
		PerfParameter->FecSecond15Min.fail_onesecond_flag = FALSE; 
} 
 
/*************************************************************************************************************** 
	Function	:	EvaluateUnavailableSeconds() 
	Description	:	This is a count of 1-second intervals for which the ADSL line is unavailable. The ADSL line  
					becomes unavailable at the onset of 10 contiguous SES-Ls. The VDSL line becomes 'Available' 
					at the onset of 10 contiguous seonds with no SES_Ls. 10 Seconds with no SES_Ls are excluded 
					from unavailable time. 
	Parameters	:	A pointer to the Performance Parameter structure, a pointer to Failures structure for the 
					port selected and a pointer to present Line State. 
	Return Value:	 
 
***************************************************************************************************************/ 
	 
void EvaluateUnavailableSeconds(PerfParameters_T *PerfParameter, Failures_T *Failure, eLINE_STATE *LineState) 
{ 
	UINT32 new_value; 
	switch(*LineState) 
	{ 
		case AVAILABLE	: 
							if(PerfParameter->SevErrSecond15Min.fail_onesecond_flag) 
							{ 
								if(!PerfParameter->UASecond15Min.fail_onesecond_flag) 
								{ 
									PerfParameter->UASecond15Min.fail_onesecond_flag = TRUE; 
									PerfParameter->UASecond15Min.old_count = 1;		/* Here the old counts refers the Unavailable seconds occured so far. Pl don't go by name */ 
								} 
								else 
								{ 
									if (++PerfParameter->UASecond15Min.old_count >= 10) 
									{ 
										/* Line should now be declared as Unavailable */ 
										*LineState = UNAVAILABLE; 
#ifdef _DEBUG_ 
										printf("\n Line is UNAVAILABLE now"); 
#endif 
											 
										/* Following Parameters are Inhibited During this time.*/ 
										PerfParameter->CvSlow15Min.inhibited = TRUE; 
										PerfParameter->CvFast15Min.inhibited = TRUE; 
										PerfParameter->FecSlow15Min.inhibited = TRUE; 
										PerfParameter->FecFast15Min.inhibited = TRUE; 
										PerfParameter->HecvSlow15Min.inhibited = TRUE; 
										PerfParameter->HecvFast15Min.inhibited = TRUE; 
										 
										PerfParameter->UASecond15Min.previous_value = MAX_SES_FOR_UAS; 
 
										/* Count the 1-second intervals of Unavailable seconds */ 
 
										new_value = PerfParameter->UASecond15Min.current_reg+1; 
										 
										/* Check for overflow of the counter */ 
										if(new_value < PerfParameter->UASecond15Min.current_reg++) 
											PerfParameter->UASecond15Min.overflow_flag = TRUE; 
 
										new_value = PerfParameter->UASecond24Hour.current_reg+1; 
										 
										/* Check for overflow of the counter */ 
										if(new_value < PerfParameter->UASecond24Hour.current_reg++ ) 
											PerfParameter->UASecond24Hour.overflow_flag = TRUE; 
									} 
								} 
							} 
							else 
								PerfParameter->UASecond15Min.fail_onesecond_flag = 0; 
							 
							break; 
 
		case UNAVAILABLE: 
							/* If there is no SES error after the line is declared unavailable */ 
							if(!PerfParameter->SevErrSecond15Min.fail_onesecond_flag) 
								PerfParameter->UASecond15Min.fail_onesecond_flag = FALSE; 
														 
							/* These are counted only when there is a SES error and Line is unavailable */ 
							if(PerfParameter->UASecond15Min.fail_onesecond_flag) 
							{ 
								new_value = PerfParameter->UASecond15Min.current_reg+1; 
							 
								/* Check for overflow of the counter */ 
								if(new_value < PerfParameter->UASecond15Min.current_reg++) 
									PerfParameter->UASecond15Min.overflow_flag = TRUE; 
 
								new_value = PerfParameter->UASecond24Hour.current_reg+1; 
								 
								/* Check for overflow of the counter */ 
								if(new_value < PerfParameter->UASecond24Hour.current_reg++ ) 
									PerfParameter->UASecond24Hour.overflow_flag = TRUE; 
 
								PerfParameter->UASecond15Min.previous_value = MAX_SES_FOR_UAS;	/* Here the previous value refers to the Total Unavailable seconds Counted. Pl don't go by name */ 
							} 
 
							/* Line may be coming to normal 'available' state */ 
							else	 
							{ 
								if(--PerfParameter->UASecond15Min.previous_value == 0)	/* Here the previous value is used for evaluating the Line availability again */ 
								{	 
									/* Line should now be declared as Available */ 
									*LineState = AVAILABLE; 
 
									/* Following Parameters are Inhibited During this time */ 
									PerfParameter->CvSlow15Min.inhibited = FALSE; 
									PerfParameter->CvFast15Min.inhibited = FALSE; 
									PerfParameter->FecSlow15Min.inhibited = FALSE; 
									PerfParameter->FecFast15Min.inhibited = FALSE; 
									PerfParameter->HecvSlow15Min.inhibited = FALSE; 
									PerfParameter->HecvFast15Min.inhibited = FALSE; 
									 
									/* Reset the counter */ 
									PerfParameter->UASecond15Min.old_count = 0; 
								} 
							} 
							break; 
 
		default			: 
							break;	 
				 
	} 
}			 
 
/*************************************************************************************************************** 
	Function	:	PrepareThresholdReport() 
	Description	:	This is called Every one second. The activities performed by the this function include, 
					 
						1.	Transfers the contents from 15Min current register to 24 hour current register for  
							all the parameters.  
						2.	Evaluates Errored Seconds, SES and UAS according to the definitions and updates 
							the current register value.  
						3.	Generating Threshold Reports whenever a parameter crosses its threshold value( User  
							configurable) or at the end of 15 Min and 24 hour accumulation period.  
					 
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value:	 
 
***************************************************************************************************************/ 
 
void PrepareThresholdReport(int BmeNum, int PortNum) 
{ 
	time_t present_time; 
	eLINE_STATE *NeLineState, *FeLineState; 
	PerfParameters_T *NePerfParameter, *FePerfParameter; 
	Failures_T	*NeFailure, *FeFailure; 
	FailReport_T *NeFailureReport, *FeFailureReport; 
	TRparameters_T *NeTR1Parameters, *FeTR1Parameters, *NeTR2Parameters, *FeTR2Parameters; 
	int i; 
	ThresholdReport15Min_T  *NeTR1, *FeTR1; 
	ThresholdReport24Hour_T  *NeTR2, *FeTR2; 
	BYTE PortStatus;				/* Gives the present Port Status */ 
 
	/* Get Port status. Parameters are accumulated only when the port is in SHOWTIME */ 
	PortStatus = apiBme[BmeNum].pBme->Port[PortNum].PortParms.PortStatusBriefParms.Actual; 
 
	if( !(PortStatus & PORT_IN_SHOWTIME) ) 
	{ 
		/* printf("\n Port is not in ShowTime"); */ 
		return; 
	} 
 
	NeTR1Parameters = &oampBme[BmeNum].oampPort[PortNum].Performance.NeTRpara15Min; 
	NeTR2Parameters = &oampBme[BmeNum].oampPort[PortNum].Performance.NeTRpara24Hour; 
	 
	FeTR1Parameters = &oampBme[BmeNum].oampPort[PortNum].Performance.FeTRpara15Min; 
	FeTR2Parameters = &oampBme[BmeNum].oampPort[PortNum].Performance.FeTRpara24Hour; 
 
	NeFailureReport = &oampBme[BmeNum].oampPort[PortNum].Performance.NeFailReport; 
	FeFailureReport = &oampBme[BmeNum].oampPort[PortNum].Performance.FeFailReport; 
 
	/* 15 Minute Threshold Reports */ 
	NeTR1 = &oampBme[BmeNum].oampPort[PortNum].Performance.Ne15MinTR; 
	FeTR1 = &oampBme[BmeNum].oampPort[PortNum].Performance.Fe15MinTR; 
 
	/* 24 Hour Threshold Reports */ 
	NeTR2 = &oampBme[BmeNum].oampPort[PortNum].Performance.Ne24HourTR; 
	FeTR2 = &oampBme[BmeNum].oampPort[PortNum].Performance.Fe24HourTR; 
 
	/* Performance Parameters */ 
	NePerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.NePerfPara; 
	FePerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.FePerfPara; 
	 
	/* Failures / Alarms */ 
	NeFailure = &oampBme[BmeNum].oampPort[PortNum].Performance.NeFails; 
	FeFailure = &oampBme[BmeNum].oampPort[PortNum].Performance.FeFails; 
	 
	/* Present Line condition. Available or Unavailable state */ 
	NeLineState = &oampBme[BmeNum].oampPort[PortNum].Performance.NeLineState; 
	FeLineState = &oampBme[BmeNum].oampPort[PortNum].Performance.FeLineState; 
 
	/* Get the present calendar time */ 
	if( (present_time = time(&present_time)) == TIME_ERROR ) 
	{ 
		printf("\n Timer Error"); 
		return; 
	} 
 
 
	/*-------------S-E-N-D-I-N-G----------R-E-P-0-R-T-----------F-O-R------F-A-I-L-U-R-E-S----------*/ 
	 
	/* Near End Failure  declaration to the Management */ 
	if( NeFailureReport->PortAlarm && (!NeFailureReport->SendReport) ) 
	{ 
		/* Covert the present calender time into broken down time and set that as report time */ 
		NeFailureReport->report_time =*(localtime(&present_time)); 
 
		/* Send the report to Management Unit. Port Alarm and SendReport flags should be reset  
		   afer sending the report in this function. Sending the report is done in a separate task */ 
		NeFailureReport->SendReport = TRUE; 
 
		printf(" \n Alarms Change of Status:\n "); 
 
		printf("\n  NeLOS = %d....  NeLOF = %d... ", NeFailureReport->LossOfSignal,NeFailureReport->LossOfFrame); 
		printf("\n  NeNCDSlow = %d....  NeNCDFast = %d... ", NeFailureReport->NCDSlow,NeFailureReport->NCDFast); 
		printf("\n  NeLCDSlow = %d....  NeLCDFast = %d... ", NeFailureReport->LCDSlow,NeFailureReport->LCDFast); 
	 
		NeFailureReport->PortAlarm =FALSE; 
		NeFailureReport->SendReport = FALSE; 
 
	}	 
 
	/* Near End Failure  declaration to the Management */ 
	if(FeFailureReport->PortAlarm && ( !FeFailureReport->SendReport) ) 
	{ 
		/* Covert the present calender time into broken down time and set that as report time */ 
		FeFailureReport->report_time = *(localtime( &present_time)); 
 
		/*	Send the report to Management Unit. Port Alarm and SendReport flags should be reset  
			in this function afer sending the report . Sending the report is done in a separate task */ 
		FeFailureReport->SendReport = TRUE; 
		printf("\n  FeLOS = %d....  FeLOF = %d... ", FeFailureReport->LossOfSignal,FeFailureReport->LossOfFrame); 
		printf("\n  FeNCDSlow = %d....  FeNCDFast = %d... ", FeFailureReport->NCDSlow,FeFailureReport->NCDFast); 
		printf("\n  FeLCDSlow = %d....  FeLCDFast = %d... ", FeFailureReport->LCDSlow,FeFailureReport->LCDFast); 
		printf("\n  FeLPR = %d....  ", FeFailureReport->LossOfPower); 
		FeFailureReport->PortAlarm =FALSE; 
	}	 
 
	/* This 'First time' is used for waiting till PORT_STABILITY_TIME gets over. All the parameter accumulation 
	   is delayed by this time  */  
	if(NePerfParameter->FirstTime) 
	{ 
		NePerfParameter->StartTime=present_time; 
		NePerfParameter->FirstTime = FALSE; 
	} 
 
	/* All reports are delayed by 10 sec */ 
	if(difftime(present_time, NePerfParameter->StartTime) < PORT_STABILITY_TIME) 
	{ 
		printf("\n Initial Stability Time hasn't been crossed yet"); 
		return; 
	} 
 
 
	/*	The Threshold Reports for 24 Hour and 15 Mintues accumulation Peroid occur at the end of 15, 30, 45  
		or 60 Minute window bourdary */ 
		 
	if( !(present_time % BOUNDARY_15MINUTE) ) 
	{ 
		printf("\n 15 Minute BOUNDARY HAS CROSSED at time : %ld", present_time); 
		/* If Parameters are accumulated for 15 Minutes, the data is valid */ 
		if(difftime(present_time, NeTR1Parameters->StartTime) == BOUNDARY_15MINUTE) 
		{ 
			NeTR1->InvalidFlag = FALSE; 
			FeTR1->InvalidFlag = FALSE; 
			printf("\n TR1 DATA IS VALID"); 
		} 
		else		/* Data is Invalid */ 
		{ 
			NeTR1->InvalidFlag = TRUE; 
			FeTR1->InvalidFlag = TRUE; 
			printf("\n TR1 DATA IS INVALID"); 
		} 
 
		/* Generate the report */ 
		GenerateTR1(NePerfParameter, NeTR1, present_time); 
		GenerateTR1(FePerfParameter, FeTR1, present_time); 
 
		/* Only this paramaeter needs to be set for both the ends */ 
		NeTR1Parameters->SendReport = TRUE;			/* Set for sending the Threshold report for Near End */ 
		FeTR1Parameters->SendReport = TRUE;			/* Set for sending the Threshold report for Far End */ 
		NeTR1Parameters->StackReg   = TRUE;			/* Set for transferring the current register contents into Stack */ 
#ifndef _DEBUG_ 
		printf("\n 15 Min Threshold REPORT "); 
		printf("\n -----------------------"); 
		printf("\n Errored Seconds 	: Current Register   : %ld",NeTR1->ErrSeconds.current_reg); 
		printf("\n                 	: Over Flow Flag     : %d",NeTR1->ErrSeconds.overflow_flag); 
		for(i = 0; i < MAX_15MIN_HISTORY_REGISTERS; i++) 
			printf("\n 	 		: History Register[%d]: %ld",i, NeTR1->ErrSeconds.history_reg[i]); 
		printf("\n -----------------------"); 
		printf("\n SevErrored Seconds 	: Current Register   : %ld",NeTR1->SevErrSeconds.current_reg); 
		printf("\n                 	: Over Flow Flag     : %d",NeTR1->SevErrSeconds.overflow_flag); 
		for(i = 0; i < MAX_15MIN_HISTORY_REGISTERS; i++) 
			printf("\n			: History Register[%d]: %ld",i, NeTR1->SevErrSeconds.history_reg[i]); 
 
		printf("\n -----------------------"); 
		printf("\n Unavailable Seconds 	: Current Register   : %ld",NeTR1->UASeconds.current_reg); 
		printf("\n                 	: Over Flow Flag     : %d",NeTR1->UASeconds.overflow_flag); 
		for(i = 0; i < MAX_15MIN_HISTORY_REGISTERS; i++) 
			printf("\n 	 	   	: History Register[%d]: %ld",i,NeTR1->UASeconds.history_reg[i]); 
		printf("\n 		   	: Invalid Flag	: %d",NeTR1->InvalidFlag); 
		NeTR1Parameters->SendReport = FALSE;		/* This is set for sending the Threshold report to Management Unit */ 
		FeTR1Parameters->SendReport = FALSE;		/* This is set for sending the Threshold report to Management Unit */ 
#endif 
 
		/* For start accumulating for the next threshold report */ 
		NeTR1Parameters->ReportStart = FALSE;			/* Both Near end and Far End reports start at the same time */ 
 
	 
		/* If the Parameters accumulation for TR2 gets started on a Odd boundary, sychronise it  
		   by sending the report for the first time after setting the invalid flag */ 
 
		if( difftime(present_time, NeTR2Parameters->StartTime) < BOUNDARY_15MINUTE)  
		{ 
			NeTR2->InvalidFlag = TRUE; 
			FeTR2->InvalidFlag = TRUE; 
		 
			GenerateTR2(NePerfParameter, NeTR2, present_time); 
			GenerateTR2(FePerfParameter, FeTR2, present_time); 
 
			/* Only this paramaeter needs to be set for both the ends */ 
			NeTR2Parameters->SendReport = TRUE;		/* This is set for sending the Threshold report to Management Unit */ 
			FeTR2Parameters->SendReport = TRUE;		/* This is set for sending the Threshold report to Management Unit */ 
			NeTR2Parameters->StackReg   = TRUE;		/* Set for transferring the current register contents into Stack */ 
 
			/* Both Far and Near End reports will start at the same time..no need to set both end flags */ 
			NeTR2Parameters->ReportStart = FALSE;		/* For the next report */ 
					 
		} 
 
		/* If the 24 Hour Accumulation period had reached, check for data validity */ 
		else if(difftime(present_time, NeTR2Parameters->StartTime) == BOUNDARY_24HOUR ) 
		{ 
			NeTR2->InvalidFlag = FALSE; 
			FeTR2->InvalidFlag = FALSE; 
		 
			GenerateTR2(NePerfParameter, NeTR2, present_time); 
			GenerateTR2(FePerfParameter, FeTR2, present_time); 
 
			/* Only this paramaeter needs to be set for both the ends */ 
			NeTR2Parameters->SendReport = TRUE;		/* This is set for sending the Threshold report to Management Unit */ 
			FeTR2Parameters->SendReport = TRUE;		/* This is set for sending the Threshold report to Management Unit */ 
			NeTR2Parameters->StackReg   = TRUE;		/* Set for transferring the current register contents into Stack */ 
 
			/* Both Far and Near End reports will start at the same time..no need to set both end flags */ 
			NeTR2Parameters->ReportStart = FALSE;		/* Start accumulating for the next report */ 
		} 
	} 
 
	/* Check whether to stack the current register contents */ 
	if(NeTR1Parameters->StackReg) 
	{ 
		/* If the report has already been sent, stack the current register to history register */ 
		if( !NeTR1Parameters->SendReport) 
		{ 
			StackCurrentReg_TR1(&NeTR1->ErrSeconds); 
			StackCurrentReg_TR1(&NeTR1->SevErrSeconds); 
			StackCurrentReg_TR1(&NeTR1->UASeconds); 
			 
			StackCurrentReg_TR1(&FeTR1->ErrSeconds); 
			StackCurrentReg_TR1(&FeTR1->SevErrSeconds); 
			StackCurrentReg_TR1(&FeTR1->UASeconds); 
			 
			/* Reset the flag */ 
			NeTR1Parameters->StackReg = FALSE; 
		} 
	} 
 
	/* Check whether to stack the current register contents */ 
	if(NeTR2Parameters->StackReg)					 
	{ 
		/* If the report has already been sent, stack the current register to history register */ 
		if( !NeTR2Parameters->SendReport) 
		{ 
			StackCurrentReg_TR2(&NeTR2->ErrSeconds); 
			StackCurrentReg_TR2(&NeTR2->SevErrSeconds); 
			StackCurrentReg_TR2(&NeTR2->UASeconds); 
			 
			StackCurrentReg_TR2(&FeTR2->ErrSeconds); 
			StackCurrentReg_TR2(&FeTR2->SevErrSeconds); 
			StackCurrentReg_TR2(&FeTR2->UASeconds); 
 
			/* Reset the flag */ 
			NeTR2Parameters->StackReg = FALSE; 
		} 
	} 
		 
	/* If the Parameters accumulation for the 15 Min accumulation peroid hasn't been started yet */ 
	if(!NeTR1Parameters->ReportStart) 
	{ 
		NeTR1Parameters->ReportStart = TRUE; 
		 
		/* Get the calendar time in seconds */ 
		NeTR1Parameters->StartTime = present_time; 
#ifdef _DEBUG_ 
		printf("\n Report Start Time : %ld", present_time); 
#endif 
		/* Reset All 15 Minute Counts */ 
		Reset15MinCounts(NePerfParameter); 
		Reset15MinCounts(FePerfParameter); 
	} 
 
	/* If the Parameters accumulation for the 24 Hour accumulation peroid hasn't been started yet */ 
	if(!NeTR2Parameters->ReportStart) 
	{ 
		NeTR2Parameters->ReportStart = TRUE; 
		 
		/* Get the calendar time in seconds */ 
		NeTR2Parameters->StartTime = present_time; 
 
		/* Reset All 15 Minute Counts */ 
		Reset24HourCounts(NePerfParameter); 
		Reset24HourCounts(FePerfParameter); 
	} 
	/*----------T-H-R-E-S-H-O-L-D------R-E-P-O-R-T------P-A-R-A-M-E-T-E-R--------E-V-A-L-U-A-T-I-O-N-----*/ 
 
	/* Evaluate Errored Seconds for the near end */ 
	EvaluateErrSeconds(NePerfParameter, NeFailure); 
 
	/* Evaluate Errored Seconds for the near end */ 
	EvaluateErrSeconds(FePerfParameter, FeFailure); 
 
	/* Evaluate Severe Errored Seconds for the near end */ 
	EvaluateSevereErrSeconds(NePerfParameter, NeFailure); 
 
	/* Evaluate Severe Errored Seconds for the near end */ 
	EvaluateSevereErrSeconds(FePerfParameter, FeFailure); 
	 
	/* Evaluate Unavailable seconds and check the status (available or unavailable) of the line for near end */ 
	EvaluateUnavailableSeconds(NePerfParameter, NeFailure, NeLineState); 
 
	/* Evaluate Unavailable seconds and check the status (available or unavailable) of the line for far end */ 
	EvaluateUnavailableSeconds(FePerfParameter, FeFailure, FeLineState); 
 
	/* Check for Threshold Crossing for the all TR1 or TR2 parameters */ 
	CheckTR1_Thresholds(NePerfParameter, NeTR1Parameters, NeTR1); 
	CheckTR1_Thresholds(FePerfParameter, FeTR1Parameters, FeTR1); 
 
	CheckTR2_Thresholds(NePerfParameter, NeTR2Parameters, NeTR2); 
	CheckTR2_Thresholds(FePerfParameter, FeTR2Parameters, FeTR2); 
 
 
	/* Update old counts. These are used for evaluating Errored Seconds, Severe Errror Seconds and FEC seconds */ 
	NePerfParameter->CvSlow15Min.old_count  = NePerfParameter->CvSlow15Min.current_reg; 
	NePerfParameter->CvFast15Min.old_count  = NePerfParameter->CvFast15Min.current_reg; 
	NePerfParameter->FecSlow15Min.old_count = NePerfParameter->FecSlow15Min.current_reg; 
	NePerfParameter->FecFast15Min.old_count = NePerfParameter->FecFast15Min.current_reg; 
 
	FePerfParameter->CvSlow15Min.old_count  = FePerfParameter->CvSlow15Min.current_reg; 
	FePerfParameter->CvFast15Min.old_count  = FePerfParameter->CvFast15Min.current_reg; 
	FePerfParameter->FecSlow15Min.old_count = FePerfParameter->FecSlow15Min.current_reg; 
	FePerfParameter->FecFast15Min.old_count = FePerfParameter->FecFast15Min.current_reg; 
} 
 
 
/*************************************************************************************************************** 
	Function	:	Reset15MinCounts() 
	Description	:	It resets all 15 minute current registers and old counts contents to zero. 
	Parameters	:	A pointer to the Performance Parameter structure.  
	Return Value:	 
 
 **************************************************************************************************************/ 
 
void Reset15MinCounts(PerfParameters_T  *PerfParameter) 
{ 
 
#ifdef _DEBUG_ 
	printf("\n COUNTE ARE RESET"); 
#endif 
	PerfParameter->ErrSecond15Min.current_reg = 0; 
	PerfParameter->SevErrSecond15Min.current_reg = 0; 
	PerfParameter->UASecond15Min.current_reg = 0; 
	PerfParameter->FecSecond15Min.current_reg = 0; 
	PerfParameter->CvSlow15Min.current_reg = 0; 
	PerfParameter->CvFast15Min.current_reg = 0; 
	PerfParameter->FecSlow15Min.current_reg = 0; 
	PerfParameter->FecFast15Min.current_reg = 0; 
 
	PerfParameter->ErrSecond15Min.old_count = 0; 
	PerfParameter->SevErrSecond15Min.old_count = 0; 
	PerfParameter->UASecond15Min.old_count = 0; 
	PerfParameter->FecSecond15Min.old_count = 0; 
	PerfParameter->CvSlow15Min.old_count = 0; 
	PerfParameter->CvFast15Min.old_count = 0; 
	PerfParameter->FecSlow15Min.old_count = 0; 
	PerfParameter->FecFast15Min.old_count = 0; 
 
	PerfParameter->ErrSecond15Min.overflow_flag = FALSE; 
	PerfParameter->SevErrSecond15Min.overflow_flag = FALSE; 
	PerfParameter->UASecond15Min.overflow_flag = FALSE; 
} 
 
/*************************************************************************************************************** 
	Function	:	Reset24hourCounts() 
	Description	:	It resets all 15 minute current registers and old counts contents to zero. 
	Parameters	:	A pointer to the Performance Parameter structure.  
	Return Value:	 
 ***************************************************************************************************************/ 
 
void Reset24HourCounts(PerfParameters_T  *PerfParameter) 
{ 
	PerfParameter->ErrSecond24Hour.current_reg = 0; 
	PerfParameter->SevErrSecond24Hour.current_reg = 0; 
	PerfParameter->UASecond24Hour.current_reg = 0; 
	PerfParameter->FecSecond24Hour.current_reg = 0; 
	PerfParameter->CvSlow24Hour.current_reg = 0; 
	PerfParameter->CvFast24Hour.current_reg = 0; 
	PerfParameter->FecSlow24Hour.current_reg = 0; 
	PerfParameter->FecFast24Hour.current_reg = 0; 
 
	PerfParameter->ErrSecond24Hour.old_count = 0; 
	PerfParameter->SevErrSecond24Hour.old_count = 0; 
	PerfParameter->UASecond24Hour.old_count = 0; 
	PerfParameter->FecSecond24Hour.old_count = 0; 
	PerfParameter->CvSlow24Hour.old_count = 0; 
	PerfParameter->CvFast24Hour.old_count = 0; 
	PerfParameter->FecSlow24Hour.old_count = 0; 
	PerfParameter->FecFast24Hour.old_count = 0; 
 
	PerfParameter->ErrSecond24Hour.overflow_flag = FALSE; 
	PerfParameter->SevErrSecond24Hour.overflow_flag = FALSE; 
	PerfParameter->UASecond24Hour.overflow_flag = FALSE; 
} 
 
/******************************************************************************************************************* 
	Function	:	StackCurrentReg_TR1() 
	Description	:	Transfers the current register contents to History registers. After reaching the last history 
					register, it writes back at the first location, discarding the oldest value available. 
	Parameters	:	A pointer to 15 Minute threshold report parameter 
	Return Value:	 
 
 ******************************************************************************************************************/ 
 
void StackCurrentReg_TR1(HistoryReg15Min_T *TRparameter) 
{ 
	TRparameter->history_reg[TRparameter->write_index++]= TRparameter->current_reg; 
 
	if(TRparameter->write_index == TRparameter->read_index) 
	{ 
		if(++TRparameter->read_index >= LAST_TR1_HISTORY_REGISTER) 
			TRparameter->read_index = 0; 
	}	 
 
	if(TRparameter->write_index >= LAST_TR1_HISTORY_REGISTER) 
		TRparameter->write_index = 0; 
} 
 
 
/******************************************************************************************************************* 
	Function	:	StackCurrentReg_TR2() 
	Description	:	Transfers the current register contents to History registers. After reaching the last history 
					register, it writes back at the first location, discarding the oldest value available. 
	Parameters	:	A pointer to 24 hour threshold report parameter. 
	Return Value:	 
 
 *******************************************************************************************************************/ 
 
void StackCurrentReg_TR2(HistoryReg24Hour_T *TRparameter) 
{ 
	TRparameter->history_reg[TRparameter->write_index++] = TRparameter->current_reg; 
 
	if(TRparameter->write_index == TRparameter->read_index) 
	{ 
		if(++TRparameter->read_index >= LAST_TR2_HISTORY_REGISTER) 
			TRparameter->read_index = 0; 
	}	 
 
	if(TRparameter->write_index >= LAST_TR2_HISTORY_REGISTER) 
		TRparameter->write_index = 0; 
} 
 
 
/******************************************************************************************************************* 
	Function	:	CheckTR1_Thresholds() 
	Description	:	If any one of the parameters being accumulated crosses its 15 Min threshold value, it prepares 
					to send the report to Mamagement Unit. 
 
	Parameters	:	A pointer to performance parameter structure,  a pointer to  threshold report parameters, 
					and a pointer to 15 minute threshold report structure. 
	Return Value:	 
 
 ******************************************************************************************************************/ 
 
void CheckTR1_Thresholds(PerfParameters_T *PerfParameter, TRparameters_T *TR1Parameters, ThresholdReport15Min_T *TR1) 
{ 
	time_t present_time; 
 
	/* Get the present calendar time */ 
	if( (present_time = time(&present_time)) ==  TIME_ERROR ) 
		printf("\n Timer Error"); 
 
	/* if any of these parameters cross corresponding thresholds, prepare for sending the report */ 
	if(	(PerfParameter->ErrSecond15Min.current_reg >= MAX_ERR_SECONDS)  
		|| (PerfParameter->SevErrSecond15Min.current_reg >= MAX_SEV_ERR_SECONDS) 
		|| (PerfParameter->UASecond15Min.current_reg >= MAX_UNAVAILABLE_SECONDS) ) 
	{ 
		TR1->InvalidFlag = FALSE; 
		 
		TR1Parameters->SendReport = TRUE;						/* Set for sending the Threshold report by another task */ 
		 
		TR1->report_time = *(localtime(&present_time));		/* Time of occurence of the report */ 
 
		/* Transfer the current register counts to Threshold report for the near end */ 
		TR1->ErrSeconds.current_reg    = PerfParameter->ErrSecond15Min.current_reg; 
		TR1->SevErrSeconds.current_reg = PerfParameter->SevErrSecond15Min.current_reg; 
		TR1->UASeconds.current_reg     = PerfParameter->UASecond15Min.current_reg;	 
	} 
} 
 
/******************************************************************************************************************* 
	Function	:	CheckTR2_Thresholds() 
	Description	:	If any one of the parameters being accumulated crosses its 24 Hour threshold value, it prepares 
					to send the report to Mamagement Unit. 
 
	Parameters	:	A pointer to performance parameter structure,  a pointer to  threshold report parameters, 
					and a pointer to 24 Hour threshold report structure. 
	Return Value:	 
 
 ******************************************************************************************************************/ 
 
void CheckTR2_Thresholds(PerfParameters_T *PerfParameter, TRparameters_T *TR2Parameters, ThresholdReport24Hour_T *TR2) 
{ 
	time_t present_time; 
 
	/* Get the present calendar time */ 
	if( (present_time = time(&present_time)) == TIME_ERROR ) 
		printf("\n Timer Error"); 
 
	/* if any of these parameters crosses corresponding thresholds, prepare for sending the report */ 
	if(	(PerfParameter->ErrSecond15Min.current_reg >= MAX_ERR_SECONDS)  
		|| (PerfParameter->SevErrSecond15Min.current_reg >= MAX_SEV_ERR_SECONDS) 
		|| (PerfParameter->UASecond15Min.current_reg >= MAX_UNAVAILABLE_SECONDS) ) 
	{ 
		TR2->InvalidFlag = FALSE; 
			 
		TR2Parameters->SendReport = TRUE;						/* Set for sending the Threshold report by another task */ 
		TR2->report_time = *(localtime(&present_time));	/* Time of occurence of the report */ 
 
		/* Transfer the current register counts to Threshold report for the far end */ 
		TR2->ErrSeconds.current_reg    = PerfParameter->ErrSecond15Min.current_reg; 
		TR2->SevErrSeconds.current_reg = PerfParameter->SevErrSecond15Min.current_reg; 
		TR2->UASeconds.current_reg     = PerfParameter->UASecond15Min.current_reg;	 
	} 
} 
 
/*************************************************************************************************************** 
	Function	:	GenerateTR1() 
	Description	:	Fills the data into the current registers. Sets the overflow flag based on the Performance 
					parameter flag.	Sets the the report time. 
	Parameters	:	A pointer to the Performance Parameters structure, a poiner to Threshold report structure 
					and present time(in seconds) 
	Return Value:	 
 ***************************************************************************************************************/ 
 
void GenerateTR1(PerfParameters_T *PerfParameter, ThresholdReport15Min_T *TR1, time_t present_time) 
{ 
	/* Transfer the current register counts to Threshold report, if there is no over flow */ 
	if(PerfParameter->ErrSecond15Min.overflow_flag) 
	{ 
		TR1->ErrSeconds.current_reg = MAX_COUNT; 
		TR1->ErrSeconds.overflow_flag = TRUE; 
	} 
	else 
	{ 
		TR1->ErrSeconds.current_reg = PerfParameter->ErrSecond15Min.current_reg; 
		TR1->ErrSeconds.overflow_flag = FALSE; 
	} 
 
	/*  Set the current register counts to Maximum value, if there is an over flow */ 
	if(PerfParameter->SevErrSecond15Min.overflow_flag) 
	{ 
		TR1->SevErrSeconds.current_reg = MAX_COUNT; 
		TR1->SevErrSeconds.overflow_flag = TRUE; 
	} 
	else 
	{ 
		TR1->SevErrSeconds.current_reg = PerfParameter->SevErrSecond15Min.current_reg; 
		TR1->SevErrSeconds.overflow_flag = FALSE; 
	} 
 
 
	/*  Set the current register counts to Maximum value, if there is an over flow */ 
	if(PerfParameter->UASecond15Min.overflow_flag) 
	{ 
		TR1->UASeconds.current_reg = MAX_COUNT; 
		TR1->UASeconds.overflow_flag = TRUE; 
	} 
	else 
	{ 
		TR1->UASeconds.current_reg = PerfParameter->UASecond15Min.current_reg; 
		TR1->UASeconds.overflow_flag = FALSE; 
	} 
 
	/* Time of occurence of the report */ 
	TR1->report_time = *(localtime(&present_time));	 
} 
 
 
/*************************************************************************************************************** 
	Function	:	GenerateTR2() 
	Description	:	Fills the data into the current registers of 24 Hour Threshold report. Sets the overflow flag  
					based on the Performance parameter flag. Sets the the report time. 
	Parameters	:	A pointer to the Performance Parameters structure, a poiner to Threshold report structure 
					and present time(in seconds) 
	Return Value:	 
 ***************************************************************************************************************/ 
 
void GenerateTR2(PerfParameters_T *PerfParameter, ThresholdReport24Hour_T *TR2, time_t present_time) 
{ 
	/* Transfer the current register counts to Threshold report, if there is no over flow */ 
	if(PerfParameter->ErrSecond24Hour.overflow_flag) 
	{ 
		TR2->ErrSeconds.current_reg = MAX_COUNT; 
		TR2->ErrSeconds.overflow_flag = TRUE; 
	} 
	else 
	{ 
		TR2->ErrSeconds.current_reg = PerfParameter->ErrSecond24Hour.current_reg; 
		TR2->ErrSeconds.overflow_flag = FALSE; 
	} 
 
	/*  Set the current register counts to Maximum value, if there is an over flow */ 
	if(PerfParameter->SevErrSecond24Hour.overflow_flag) 
	{ 
		TR2->SevErrSeconds.current_reg = MAX_COUNT; 
		TR2->SevErrSeconds.overflow_flag = TRUE; 
	} 
	else 
	{ 
		TR2->SevErrSeconds.current_reg = PerfParameter->SevErrSecond24Hour.current_reg; 
		TR2->SevErrSeconds.overflow_flag = FALSE; 
	} 
 
	/*  Set the current register counts to Maximum value, if there is an over flow */ 
	if(PerfParameter->UASecond24Hour.overflow_flag) 
	{ 
		TR2->UASeconds.current_reg = MAX_COUNT; 
		TR2->UASeconds.overflow_flag = TRUE; 
	} 
	else 
	{ 
		TR2->UASeconds.current_reg = PerfParameter->UASecond24Hour.current_reg; 
		TR2->UASeconds.overflow_flag = FALSE; 
	} 
 
	/* Time of occurence of the report */ 
	TR2->report_time = *(localtime( &present_time)); 
} 
#if 0 
/*************************************************************************************************************** 
	Function	:	taskOneSecPerfHdlr( ) 
	Description	:	This is 'Performance hanlder One Second taks's Entry fuction. The task is created 
				by the 'start()' in app.c. This calls every one second the 'PrepareThresholdReport' 
				function for hanlding the Failures and Threshold Reports 
			 
	Parameters	:	None. 
	Return Value:	 
 ***************************************************************************************************************/ 
#define AUTO_REPT 
void taskOneSecPerfHdlr(void) 
{ 
#ifdef AUTO_REPT 
  BYTE pTlStr[32]; 
	BYTE PortNum = 0;	 
#ifdef AUTO_REPT 
	BYTE bmeNum; 
#endif 
 
	while(1) 
	{ 
#ifdef AUTO_REPT 
#ifdef PRODUCTION_CODE 
		for (bmeNum = 0; bmeNum < numBme; bmeNum++) 
		{ 
			if ((bmeStatus[bmeNum].status & uRUN) && 
          (bmeStatus[bmeNum].cmdStatus == uCMD_IDLE) && 
					(bmeStatus[bmeNum].reptCmdStatus == uRPT_IDLE)) 
			{ 
//				sprintf(pTlStr,"perrep:99:%i:0:3:20:0;", bmeNum + 1);	 
				sprintf(pTlStr,"perrep:99:%i:0:7:20:30;", bmeNum + 1);	 
        if (ReceiveTLCommand (pTlStr) == 0) 
        { 
          bmeStatus[bmeNum].cmdStatus = uCMD_SND; 
					bmeStatus[bmeNum].reptCmdStatus = uRPT_CMD_SND; 
        } 
			} 
		} 
#endif 
#else 
    if (pmEnable) 
    { 
 
//		for(PortNum =0; PortNum< MAX_VDSL_PORTS; PortNum++) 
		  /* PrepareThresholdReport(&Bme[1], PortNum); */ 
 
    for(PortNum =0; PortNum< MAX_VDSL_PORTS; PortNum++) 
     { 
      if (portStatus[PortNum].status == uSHOWTIME) 
      { 
        if (portStatus[PortNum].startCnt < 5) 
          portStatus[PortNum].startCnt++; 
        else 
        { 
          if (portStatus[PortNum].pollCmdSnd == 0) 
          { 
            if (portStatus[PortNum].losFailure == 0) 
            { 
              if (portStatus[PortNum].startCnt == 5)  
              { 
 
		sprintf(pTlStr,"getcntr:99:%i:%i;",portStatus[PortNum].bmeNum,portStatus[PortNum].portNum);	 
                if (ReceiveTLCommand (pTlStr) == 0) 
               		{ 
                  	portStatus[PortNum].startCnt = 6; 
                  	portStatus[PortNum].pollCmdSnd = 1; 
             		} 
 
              } 
              else 
                portStatus[PortNum].startCnt = 5; 
            } 
 
          } 
        } 
       } //for loop 
      } // pmEnable 
    } 
#endif 
		iposTaskDelay(TICKS_PER_SECOND); 
    secondTicks++; 
	}		 
#endif 
} 
#endif 
/*************************************************************************************************************** 
	Function	:	GetThresholdReport( ) 
	Description	:	This is the utility funciton for user to get the Threshold report. 
			 
	Parameters	:	Pointer to the BME structure, Port Number and the type of the report, TR1 or TR2. 
	Return Value	:	Pointer to the corresponding threshold report. 
 ***************************************************************************************************************/ 
 
void *GetThresholdReport(int BmeNum, int PortNum, eReportType report_type) 
{ 
	PerfParameters_T *PerfParameter; 
	ThresholdReport15Min_T  *TR1; 
	ThresholdReport24Hour_T *TR2; 
	void *TR; 
 
	time_t present_time; 
 
	/* Get the present calendar time */ 
	if( (present_time = time(&present_time)) == TIME_ERROR ) 
		printf("\n Timer Error"); 
	 
	switch(report_type) 
	{ 
		case NE_15MIN:	/* 15 Minute Near End Threshold Report */ 
				PerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.NePerfPara; 
				TR1 = &oampBme[BmeNum].oampPort[PortNum].Performance.Ne15MinTR; 
				GenerateTR1(PerfParameter, TR1, present_time); 
				TR = (void *) TR1; 
				break; 
 
		case FE_15MIN:	/* 15 Minute Far End Threshold Report */ 
				PerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.FePerfPara; 
				TR1 = &oampBme[BmeNum].oampPort[PortNum].Performance.Fe15MinTR;	 
				GenerateTR1(PerfParameter, TR1, present_time); 
				TR = (void *) TR1; 
				break; 
 
		case NE_24HOUR:	/* 24 hour End Threshold Report */ 
				PerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.NePerfPara;	 
				TR2 = &oampBme[BmeNum].oampPort[PortNum].Performance.Ne24HourTR; 
				GenerateTR2(PerfParameter, TR2, present_time); 
				TR = (void *) TR2; 
				break; 
 
		case FE_24HOUR:	/* 24 Hour far End Threshold Report */ 
		default: 
				PerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.FePerfPara; 
				TR2 = &oampBme[BmeNum].oampPort[PortNum].Performance.Fe24HourTR; 
				GenerateTR2(PerfParameter, TR2, present_time); 
				TR = (void *) TR2; 
				break; 
	} 
	return TR; 
}
#ifdef INI_SUPPORT  
/************************************************************************************************************ 
  
GetINICrcThresStatusFlag   -  CRC Threshold Crossing Detection 
 
 Input : Ethernet Port Number
         uPortStruct
		 ptmfPort Number

 Output: Returns CRC Threshold Flag 
 
  **********************************************************************************************************/ 
 UINT32 GetINICrcThresStatusFlag(uPortStruct *uEPortStatus, int ethnetPortNum, int ptmfPort, U8 lineHold6ptOk) 
{ 
 
  UINT16 cRxFrame; 
  UINT16 cCrcCnt; 
  UINT16 cDropByteCnt; 
  float crcThreshold = 30.0; 
  unsigned int iniRxFrameCnt; 
  unsigned int iniMinRxFrameCnt;
  int crcThresCrsFlag = 0;

 
 if (uEPortStatus->pRxFrame[ethnetPortNum] == 0xFFFF) 
  { 
    uEPortStatus->pRxFrame[ethnetPortNum] = iposPtmfEnetTxFrames(ptmfPort); 
    uEPortStatus->pCrcCnt[ethnetPortNum] = iposPtmfHdlcGeneralErrors(ptmfPort); 
    uEPortStatus->pDropByteCnt[ethnetPortNum] = iposPtmfHdlcDroppedFrames (ptmfPort); 
   
     
	uEPortStatus->iniCrcCnt[ethnetPortNum] = 0; 
    uEPortStatus->iniRxFrameCnt[ethnetPortNum] = 0; 
    uEPortStatus->iniCrcTCrossCnt[ethnetPortNum] = 0; 
 
    uEPortStatus->tickCount[ethnetPortNum] = secondTicks; 
  } 
  else 
  { 
      cRxFrame = iposPtmfEnetTxFrames(ptmfPort); 
      cCrcCnt = iposPtmfHdlcGeneralErrors(ptmfPort); 
      cDropByteCnt = iposPtmfHdlcDroppedFrames(ptmfPort); 
 
 
    if (cRxFrame < uEPortStatus->pRxFrame[ethnetPortNum]) 
      iniRxFrameCnt = 0x10000 - uEPortStatus->pRxFrame[ethnetPortNum] + cRxFrame; 
    else 
      iniRxFrameCnt = cRxFrame - uEPortStatus->pRxFrame[ethnetPortNum]; 
 
    uEPortStatus->pRxFrame[ethnetPortNum] = cRxFrame; 
     
    iniMinRxFrameCnt = secondTicks; 
     
    if (iniMinRxFrameCnt < uEPortStatus->tickCount[ethnetPortNum]) 
      iniMinRxFrameCnt += (0xFFFFFFFF - uEPortStatus->tickCount[ethnetPortNum]) + 1; 
    else 
      iniMinRxFrameCnt -= uEPortStatus->tickCount[ethnetPortNum]; 
 
    uEPortStatus->tickCount[ethnetPortNum] = secondTicks; 
     
    iniMinRxFrameCnt *= uEPortStatus->expIniRxFramePerSec[ethnetPortNum]; 
    if (iniMinRxFrameCnt > iniRxFrameCnt) 
      iniRxFrameCnt = iniMinRxFrameCnt; 
 
    uEPortStatus->iniRxFrameCnt[ethnetPortNum] += iniRxFrameCnt; 
    if (cDropByteCnt == uEPortStatus->pDropByteCnt[ethnetPortNum]) 
    { 
      if (cCrcCnt < uEPortStatus->pCrcCnt[ethnetPortNum]) 
        uEPortStatus->iniCrcCnt[ethnetPortNum] += 0x10000 - uEPortStatus->pCrcCnt[ethnetPortNum] + cCrcCnt; 
      else 
        uEPortStatus->iniCrcCnt[ethnetPortNum] += cCrcCnt - uEPortStatus->pCrcCnt[ethnetPortNum]; 
    } 
     
    uEPortStatus->pCrcCnt[ethnetPortNum] = cCrcCnt; 
    uEPortStatus->pDropByteCnt[ethnetPortNum] = cDropByteCnt; 
    if (uEPortStatus->iniRxFrameCnt[ethnetPortNum] > numCrcCheckFrames) 
    { 
      crcThreshold = 30 * ((float)uEPortStatus->iniRxFrameCnt[ethnetPortNum] / (float)numCrcCheckFrames); 
//	  printf("\n CrcCheckFrames = %d \n",numCrcCheckFrames); 
      uEPortStatus->iniRxFrameCnt[ethnetPortNum] = 0; 
      uEPortStatus->tickCount[ethnetPortNum] = secondTicks; 
      if (uEPortStatus->iniCrcCnt[ethnetPortNum] < crcThreshold) 
      { 
        uEPortStatus->iniCrcTCrossCnt[ethnetPortNum] = 0; 
        uEPortStatus->iniCrcCnt[ethnetPortNum] = 0; 
      } 
    } 
    if (uEPortStatus->iniCrcCnt[ethnetPortNum] >= crcThreshold) 
    { 
            if(evalSixPtLineHold(lineHold6ptOk) == 1) 
            {
                uEPortStatus->iniCrcTCrossCnt[ethnetPortNum]=0;             
            }
            else
            {
	      	uEPortStatus->iniCrcTCrossCnt[ethnetPortNum]++; 
		}
      uEPortStatus->iniCrcCnt[ethnetPortNum] = 0; 
      uEPortStatus->iniRxFrameCnt[ethnetPortNum] = 0; 
      uEPortStatus->tickCount[ethnetPortNum] = secondTicks; 
    } 
  }
  if (uEPortStatus->iniCrcTCrossCnt[ethnetPortNum] >= 5)
    crcThresCrsFlag = 1;
  return(crcThresCrsFlag); 
} 
#endif //ifdef INI_SUPPORT  
/*************************************************************************************************************** 
	Function	:	GetPerfParameter( ) 
	Description	:	This is the utility funciton for user to get the current value of a performance 
				parameter for during 15 minute or 24 hour accumulation period. 
			 
	Parameters	:	Near End or Far End Performance Parameter and Paramete type. 
	Return Value	:	Current Register count. 
 ***************************************************************************************************************/ 
 
UINT32 GetPerfParameter (int BmeNum, int PortNum, eReportType report_type, eParaType parameter_type) 
{ 
	PerfParameters_T *PerfParameter; 
	 
	switch(report_type) 
	{ 
		case NE_15MIN:	/* 15 Minute accumulation period */ 
		case NE_24HOUR:	/* 24Hour accumulation period */ 
				PerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.NePerfPara; 
				break; 
		case FE_15MIN:	/* 15 Minute accumulation period */ 
		case FE_24HOUR:	/* 24Hour accumulation period */ 
		default: 
				PerfParameter = &oampBme[BmeNum].oampPort[PortNum].Performance.FePerfPara; 
				break; 
	} 
	return (GetCurrentValue(PerfParameter, parameter_type)); 
} 
 
/*************************************************************************************************************** 
	Function	:	GetCurrentValue( ) 
	Description	:	Returns the Current Register contents for the accumulation period requested. 
			 
	Parameters	:	Pointer to the BME structure, Port Number  
				Near End or Far End Performance Parameter and Paramete type. 
	Return Value	:	Current Register count. 
 ***************************************************************************************************************/ 
 
UINT32 GetCurrentValue(PerfParameters_T *PerfParameter, eParaType parameter_type) 
{ 
	switch(parameter_type) 
	{ 
 
/* Code Violation Count  */ 
		case CV_SLOW_15MIN: 
				return PerfParameter->CvSlow15Min.current_reg; 
			  
		case CV_FAST_15MIN: 
				return PerfParameter->CvFast15Min.current_reg; 
 
		case CV_SLOW_24HOUR: 
				return PerfParameter->CvSlow24Hour.current_reg; 
			  
		case CV_FAST_24HOUR: 
				return PerfParameter->CvFast24Hour.current_reg; 
 
/* FEC Count */ 
		case FEC_SLOW_15MIN: 
				return PerfParameter->FecSlow15Min.current_reg; 
			  
		case FEC_FAST_15MIN: 
				return PerfParameter->FecFast15Min.current_reg; 
 
		case FEC_SLOW_24HOUR: 
				return PerfParameter->FecSlow24Hour.current_reg; 
			  
		case FEC_FAST_24HOUR: 
				return PerfParameter->FecFast24Hour.current_reg; 
 
/* HEC violation Count */ 
 
		case HECV_SLOW_5MIN: 
				return PerfParameter->HecvSlow15Min.current_reg; 
			  
		case HECV_FAST_15MIN: 
				return PerfParameter->HecvFast15Min.current_reg; 
 
		case HECV_SLOW_24HOUR: 
				return PerfParameter->HecvSlow24Hour.current_reg; 
			  
		case HECV_FAST_24HOUR: 
				return PerfParameter->HecvFast24Hour.current_reg; 
 
/* Errored Seconds Count */ 
		case ERR_SEC_15MIN: 
				return PerfParameter->ErrSecond15Min.current_reg; 
 
		case ERR_SEC_24HOUR: 
				return PerfParameter->ErrSecond24Hour.current_reg; 
 
/* Severe Errored Seconds Count */ 
		case SEV_ERR_SEC_15MIN: 
				return PerfParameter->SevErrSecond15Min.current_reg; 
 
		case SEV_ERR_SEC_24HOUR: 
				return PerfParameter->SevErrSecond24Hour.current_reg; 
 
/* Unavailable Seconds Count */ 
		case UASEC_15MIN: 
				return PerfParameter->UASecond15Min.current_reg; 
 
		case UASEC_24HOUR: 
				return PerfParameter->UASecond24Hour.current_reg; 
		default		:	 
				return NULL; 
	} 
} 
 
void DisplayThresholdReport(eReportType report_type, void *TR) 
{ 
	int i; 
	ThresholdReport15Min_T  *TR1; 
	ThresholdReport24Hour_T *TR2; 
 
	switch(report_type) 
	{ 
		case NE_15MIN:	/* 15 Minute Near End Threshold Report */ 
		case FE_15MIN: 	/* 15 Minute Far End Threshold Report */ 
				TR1 = (ThresholdReport15Min_T  *)TR; 
				printf("\n 15 Minute Threshold Report (TR1)"); 
				printf("\n----------------------------------"); 
				printf("\n Data InValid Flag: %d",TR1->InvalidFlag); 
				printf("\n Errored Seconds 	: Current Register   : %ld",TR1->ErrSeconds.current_reg); 
				printf("\n                 	: Over Flow Flag     : %d",TR1->ErrSeconds.overflow_flag); 
				for(i = 0; i < MAX_15MIN_HISTORY_REGISTERS; i++) 
					printf("\n 	 		: History Register[%d]: %ld",i, TR1->ErrSeconds.history_reg[i]); 
				 
				printf("\n -----------------------"); 
				printf("\n SevErrored Seconds 	: Current Register   : %ld",TR1->SevErrSeconds.current_reg); 
				printf("\n                 	: Over Flow Flag     : %d",TR1->SevErrSeconds.overflow_flag); 
				for(i = 0; i < MAX_15MIN_HISTORY_REGISTERS; i++) 
					printf("\n			: History Register[%d]: %ld",i, TR1->SevErrSeconds.history_reg[i]); 
	 
				printf("\n -----------------------"); 
				printf("\n Unavailable Seconds 	: Current Register   : %ld",TR1->UASeconds.current_reg); 
				printf("\n                 	: Over Flow Flag     : %d",TR1->UASeconds.overflow_flag); 
				for(i = 0; i < MAX_15MIN_HISTORY_REGISTERS; i++) 
					printf("\n 	 	   	: History Register[%d]: %ld",i,TR1->UASeconds.history_reg[i]); 
				break; 
 
		case NE_24HOUR:	/* 24 hour End Threshold Report */ 
		case FE_24HOUR:	/* 24 Hour far End Threshold Report */ 
				TR2 = (ThresholdReport24Hour_T  *)TR; 
				printf("\n 24 Hour Threshold Report (TR2)"); 
				printf("\n----------------------------------"); 
				printf("\n Data InValid Flag: %d",TR2->InvalidFlag); 
				printf("\n Errored Seconds 	: Current Register   : %ld",TR2->ErrSeconds.current_reg); 
				printf("\n                 	: Over Flow Flag     : %d",TR2->ErrSeconds.overflow_flag); 
				for(i = 0; i < MAX_24HOUR_HISTORY_REGISTERS; i++) 
					printf("\n 	 		: History Register[%d]: %ld",i, TR2->ErrSeconds.history_reg[i]); 
				 
				printf("\n -----------------------"); 
				printf("\n SevErrored Seconds 	: Current Register   : %ld",TR2->SevErrSeconds.current_reg); 
				printf("\n                 	: Over Flow Flag     : %d",TR2->SevErrSeconds.overflow_flag); 
				for(i = 0; i < MAX_24HOUR_HISTORY_REGISTERS; i++) 
					printf("\n			: History Register[%d]: %ld",i, TR2->SevErrSeconds.history_reg[i]); 
	 
				printf("\n -----------------------"); 
				printf("\n Unavailable Seconds 	: Current Register   : %ld",TR2->UASeconds.current_reg); 
				printf("\n                 	: Over Flow Flag     : %d",TR2->UASeconds.overflow_flag); 
				for(i = 0; i < MAX_24HOUR_HISTORY_REGISTERS; i++) 
					printf("\n 	 	   	: History Register[%d]: %ld",i,TR2->UASeconds.history_reg[i]); 
				break; 
 
				break; 
	} 
	 
} 
 
 
 
