/*******************************************************************************
	Workfile:   pmhandler.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.4 $ 
$Date: 2007/01/22 14:49:09 $ 
 
*******************************************************************************/ 
 
#include <string.h>  
#include <stdio.h> 
#include <stdlib.h>
#ifndef USE_VXWORKS /* IXDP425 */
#include <v2pthread.h>
#endif
#include "apitype.h" 
#include "apistruct.h" 
#include "appconfig.h" 
#include "msgbuf.h" 
#include "oamp.h" 
#include "oampdb.h" 
#include "bmeconfig.h" 
#include "ipos.h" 
#include "eventlog.h"
#include "pmhandler.h"

/* Start : For PM Application */

#define timer15mins		3000  //(15(mins)* 60(secs)*1000(millisecs) )/ 300 (millisecs)[IPOS_TMR_RESOLUTION]

//static int ethnetPortNum = 1;
ipos_tmr_info *tmr15mins;
ipos_pm_counters *pPmCntr24Hrs[IPOS_MAX_BME+1][IPOS_MAX_PORT_PER_BME+1];

int iFailStatus[IPOS_MAX_BME+1][IPOS_MAX_PORT_PER_BME+1];
int portStartCopy[IPOS_MAX_BME+1][IPOS_MAX_PORT_PER_BME+1];

char *strAlertNeFailMsg[] 	= 	{	"Loss of Signal (LOS) Failure detected",
								"Loss of Frame (LOF) Failure detected",
								"Loss of Power (LPR) Failure detected",
								"Loss of Margin (LOM) Failure detected",
								"Excessive Severe Error (ESE) Failure detected",
								"",
								"",
								"",
								"NCD - Slow Path Failure Detected",
								"LCD - Slow Path Failure Detected",
								"",
								"",
								"NCD - Fast Path Failure Detected",
								"LCD - Fast Path Failure Detected",
								"",
								""
							};


char *strAlertFeFailMsg[] 	= 	{	"Far-end Loss of Signal (FLOS) Failure detected",
								"Far-end Loss of Frame (FRDI) Failure detected",
								"Far-end Loss of Power (FLPR) Failure detected",
								"Far-end Loss of Margin (FLOM) Failure detected",
								"Far-end Excessive Severe Error (FESE) Failure detected",
								"",
								"",
								"",
								"Far-end NCD - Slow Path Failure Detected",
								"Far-end LCD - Slow Path Failure Detected",
								"",
								"",
								"Far-end NCD - Fast Path Failure Detected",
								"Far-end LCD - Fast Path Failure Detected",
								"",
								""
							};

char *strAlertNeTCA1Msg[] = 	{	"Severly Errored Seconds (SES) TCA detected",
								"Errored Seconds (SES) TCA detected",
								"Loss of Signal Second (LOSS) TCA detected",
								"Forward Error Correction Second(FECS) TCA detected"
							};

char *strAlertFeTCA1Msg[] = 	{	"Far-end Severly Errored Seconds (FSES) TCA detected",
								"Far-end Errored Seconds (FES) TCA detected",
								"Far-end Loss of Signal Second (FLOSS) TCA detected",
								"Far-end Forward Error Correction Second(FFECS) TCA detected"
							};

char *strAlertNeTCA2Msg[] = 	{	"Loss Of Signal (LOS) Failure Count TCA",
								"Loss Of Frame (LOF) Failure Count TCA",
								"Loss Of Power (LPR) Failure Count TCA",
								"Loss of Margin (LOM) Failure Count TCA",
								"Excessive Severe Error (ESE) Failure Count TCA",
								"NCD - Slow Path Failure Count TCA",
								"LCD - Slow Path Failure Count TCA",
								"NCD - Fast Path Failure Count TCA",
								"LCD - Fast Path Failure Count TCA",
								"FEC - Slow Path Anomaly Count TCA",
								"FEC - Fast Path Anomaly Count TCA",
								"CRC - Slow Path Anomaly Count TCA",
								"CRC - Fast Path Anomaly Count TCA",
								"HEC - Slow Path Anomaly Count TCA",
								"HEC - Fast Path Anomaly Count TCA"
							};

char *strAlertFeTCA2Msg[] = 	{	"Far-end Loss Of Signal (FLOS) Failure Count TCA",
								"Far-end Loss Of Frame (FRDI) Failure Status",
								"Far-end Loss Of Power (FLPR) Failure Count TCA",
								"Far-end Loss of Margin (FLOM) Failure Count TCA",
								"Far-end Excessive Severe Error (FESE) Failure Count TCA",
								"Far-end NCD - Slow Path Failure Count TCA",
								"Far-end LCD - Slow Path Failure Count TCA",
								"Far-end NCD - Fast Path Failure Count TCA",
								"Far-end LCD - Fast Path Failure Count TCA",
								"Far-end FEC - Slow Path Anomaly Count TCA",
								"Far-end FEC - Fast Path Anomaly Count TCA",
								"Far-end CRC - Slow Path Anomaly Count TCA",
								"Far-end CRC - Fast Path Anomaly Count TCA",
								"Far-end HEC - Slow Path Anomaly Count TCA",
								"Far-end HEC - Fast Path Anomaly Count TCA"
							};

/* End : For PM Application */
extern oamp_bme oampBme [IPOS_MAX_BME+1];  				/* BME objects for OAMP   */ 

void ReceivePmAlert(ipos_port_id pid, U8 uid, U32 upar, int status,
                    ipos_pm_alert *pAlert); 

void ReceivePmCounters(ipos_port_id pid, U8 uid, U32 upar, int status,
                       ipos_pm_counters *pPmCntr); 
void ResetPMCounters (ipos_pm_counters *pPmCntr);
void accumulatePMCounters(ipos_pm_counters *pPmAccCntr, ipos_pm_counters *pPmCntr);

/*******************************************************************************
	Function	:	InitPMHandler() 
	Description	:	Resets the PM Counters structures. Also sets the callback
                functions for the messages associated with performance
                monitoring viz PM Alert and PM Counters Messages.
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value:	eApiRv  
 
*******************************************************************************/
void InitPMHandler(int BmeNum, int PortNum) 
{ 
  ipos_port_id	pid; 

  memset(&oampBme[BmeNum].oampPort[PortNum].PmCounters, 0,
         sizeof(ipos_pm_counters));
  memset(&oampBme[BmeNum].oampPort[PortNum].PmCountersAtPortStart,0,
         sizeof(ipos_pm_counters));

  /* Start : For PM Application */
  pPmCntr24Hrs[BmeNum][PortNum]=&(oampBme[BmeNum].oampPort[PortNum].PmCounters24Hrs);
  memset(pPmCntr24Hrs[BmeNum][PortNum], 0,sizeof(ipos_pm_counters));
  /* End : For PM Application */
  pid.bmeNum=BmeNum; 
  pid.portNum=PortNum; 
 
  iposSetCbPmCounters(pid, 0, ReceivePmCounters); 

  iposSetCbPmAlert(pid, 0, ReceivePmAlert);

} 
	 
 
/******************************************************************************** 
	Function	:	ReceivePmAlert
	Description	:	
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value:	 
 
********************************************************************************/ 
 
void ReceivePmAlert (ipos_port_id pid, U8 uid, U32 upar, int status,
                     ipos_pm_alert *pAlert)  
{ 
/* Start : For PM Application */
    ipos_pm_counters *pCnt;

	//int ibitcount=0, crcTCrossFlag = 0;
	//int lineNum, ptmfPort;
	//int IniIndex, IniFast, IniSlow; 
	uPortStruct *pPortStatus; 
	//int errCode=IPOS_SUCCESS;

    if (iFailStatus[pid.bmeNum][pid.portNum])
        return;

	/* Evaluate INI CRC threshold */ 
	pPortStatus = &oampBme[pid.bmeNum].oampPort[pid.portNum].portStatus; 
    pCnt = &oampBme[pid.bmeNum].oampPort[pid.portNum].PmCounters;
 
#if 0
	// For Near-end and Far-end Failures
	if (pAlert->NeFailures || pAlert->FeFailures)
	{
#endif
		// Change Port Status if LOS (bit 0) or LOF (1) or ESE (4) occur
        if (pAlert->FeFailures & 0x4)
        {
            printf ("Bme %i Port %i %s\n", pid.bmeNum, pid.portNum,
                    strAlertFeFailMsg[2]);
            iFailStatus[pid.bmeNum][pid.portNum]=TRUE;
        }
        else if (pAlert->NeFailures & 0x13)
		{
			iFailStatus[pid.bmeNum][pid.portNum]=TRUE;
                        if (pAlert->NeFailures & 0x1)
           		       printf ("Bme %i Port %i %s\n",pid.bmeNum, pid.portNum, strAlertNeFailMsg[0]);
                        else if (pAlert->NeFailures & 0x2)
           		       printf ("Bme %i Port %i %s\n",pid.bmeNum, pid.portNum, strAlertNeFailMsg[1]);
                        else if (pAlert->NeFailures & 0x10)
           		       printf ("Bme %i Port %i %s\n",pid.bmeNum, pid.portNum, strAlertNeFailMsg[4]);

		}
#if 0
		if(pAlert->NeFailures)
		{
			// SRD: For Debugging
			//printf("\nb%dp%d : NeFailure 0x%.4x",pid.bmeNum, pid.portNum, pAlert->NeFailures);
		
			for (ibitcount=0;ibitcount<=15;ibitcount++)
			{
				// Check bit and display message
				// donot evaluate Bits 5-7, 10-11,14-15 as they are reserved
				
				if(
					(ibitcount!=5 || ibitcount!=6 || ibitcount!=7 || ibitcount!=10 
					|| ibitcount!=11 || ibitcount!=14 || ibitcount!=15)
					&& ((pAlert->NeFailures) & (0x01<<ibitcount))
				   )
					{
						UserLog ("Bme %i Port %i %s",pid.bmeNum, pid.portNum, strAlertNeFailMsg[ibitcount]);
						//printf("\nb%dp%d : %s", pid.bmeNum, pid.portNum, strAlertNeFailMsg[ibitcount]);
					}
			}
		}

		if(pAlert->FeFailures)
		{
			// SRD: For Debugging
			//printf("\nb%dp%d : FeFailure 0x%.4x",pid.bmeNum, pid.portNum, pAlert->FeFailures);
			
			for (ibitcount=0;ibitcount<=15;ibitcount++)
			{
				// Check bit and display message
				// donot evaluate Bits 5-7, 10-11,14-15 as they are reserved
				
				if(
					(ibitcount!=5 || ibitcount!=6 || ibitcount!=7 || ibitcount!=10 
					|| ibitcount!=11 || ibitcount!=14 || ibitcount!=15 )
					&& ((pAlert->FeFailures) & (0x01<<ibitcount))
				   )
					{
						UserLog ("Bme %i Port %i %s",pid.bmeNum, pid.portNum,strAlertFeFailMsg[ibitcount]);
						//printf("\nb%dp%d : %s ", pid.bmeNum, pid.portNum, strAlertFeFailMsg[ibitcount]);
					}
			}
		}
	}

	// For TCAs

	// The respective TCAs are displayed. 
	// Further decision based on these values can be taken here
	if (pAlert->NeTCA1)
	{
#endif
		// Change Port Status if TCA1 occurs for SES (bit 0) or LOSS (bit 2)
#if 0
		for (ibitcount=0;ibitcount<=3;ibitcount++)
		{
			// Check bit and display message
			if((pAlert->NeTCA1) & (0x01<<ibitcount))
			{
				UserLog ("Bme %i Port %i %s",pid.bmeNum, pid.portNum, strAlertNeTCA1Msg[ibitcount]);
				//printf("\nb%dp%d : %s ", pid.bmeNum, pid.portNum, strAlertNeTCA1Msg[ibitcount]);
			}
		}
	}

	if (pAlert->FeTCA1)
	{
		for (ibitcount=0;ibitcount<=3;ibitcount++)
		{
			// Check bit and display message
			if((pAlert->FeTCA1) & (0x01<<ibitcount))
			{
				UserLog ("Bme %i Port %i %s",pid.bmeNum, pid.portNum,strAlertFeTCA1Msg[ibitcount]);
				//printf("\nb%dp%d : %s ", pid.bmeNum, pid.portNum, strAlertFeTCA1Msg[ibitcount]);
			}
		}
	}

	if (pAlert->NeTCA2)
	{
		for (ibitcount=0;ibitcount<=14;ibitcount++)
		{
			// Check bit and display message
			if((pAlert->NeTCA2) & (0x01<<ibitcount))
			{
				UserLog ("Bme %i Port %i %s",pid.bmeNum, pid.portNum,strAlertFeTCA2Msg[ibitcount]);
				//printf("\nb%dp%d : %s ", pid.bmeNum, pid.portNum, strAlertNeTCA2Msg[ibitcount]);
			}
		}
	}

	if (pAlert->FeTCA2)
	{
		for (ibitcount=0;ibitcount<=14;ibitcount++)
		{
			// Check bit and display message
			if((pAlert->FeTCA2) & (0x01<<ibitcount))
			{
				UserLog ("Bme %i Port %i %s",pid.bmeNum, pid.portNum,strAlertFeTCA2Msg[ibitcount]);
				//printf("\nb%dp%d : %s ", pid.bmeNum, pid.portNum, strAlertFeTCA2Msg[ibitcount]);
			}
		}
	}
#endif

	if(iFailStatus[pid.bmeNum][pid.portNum] == TRUE)
	{
		pPortStatus->status |=uDOWN;
		oampBme[pid.bmeNum].oampPort[pid.portNum].portState=uSTOP;
	}


/* End : For PM Application */

#if 0
UserLog ("PM Alert:Failures = 0x%x; TCA1 = 0x%x; TCA2 = 0x%x",
           ((U32)pAlert->NeFailures) | ((U32)pAlert->FeFailures << 16),
           ((U32)pAlert->NeTCA1) | ((U32)pAlert->FeTCA1 << 16),
           ((U32)pAlert->NeTCA2) | ((U32)pAlert->FeTCA2 << 16));
printf ("\nb%dp%d PM Alert Received",pid.bmeNum,pid.portNum); 
#endif

}

 
/*******************************************************************************
	Function	:	ReceivePmCounters
	Description	:	
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value:	 
 
*******************************************************************************/
 
void ReceivePmCounters (ipos_port_id pid, U8 uid, U32 upar, int status,
                        ipos_pm_counters *pPmCntr)  
{ 
  int bmeNum, portNum;
  
  /* Start : For PM Application */
  //int lineNum;
  ipos_pm_counters *pPmCntrCurrent;
  /* End : For PM Application */
  bmeNum = pid.bmeNum;
  portNum = pid.portNum;

  if (! (oampBme[pid.bmeNum].oampPort[pid.portNum].portState & SHOWTIME))
  {
	printf("\nb%dp%d Port not in Show Time",pid.bmeNum,pid.portNum);
	return;
  }

  pPmCntrCurrent = &(oampBme[pid.bmeNum].oampPort[pid.portNum].PmCounters);

  if (pPmCntr->PmPeriodId -pPmCntrCurrent->PmPeriodId)
  {
	updatePMCounters24Hrs(pPmCntr24Hrs[pid.bmeNum][pid.portNum], pPmCntr, pid);
    // printf("24 hour PM counter update: %d %d\n",pPmCntr24Hrs[pid.bmeNum][pid.portNum]->NeCRC_S, pPmCntr->NeCRC_S);
    // printf("24 hour PM counter update: %d %d\n",pPmCntr24Hrs[pid.bmeNum][pid.portNum]->NeFEC_S, pPmCntr->NeFEC_S);
  }

  copyPMCountersToOamp(pPmCntr,pid);
  //IK_PRINTF("\n >sixPtstat:%d", pPmCntr->sixPtLineHold );
}

 
/******************************************************************************
	Function	:	copyPMCountersToOamp
	Description	:	
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value:	 
 
******************************************************************************/

void copyPMCountersToOamp (ipos_pm_counters *pPmCntr,ipos_port_id pid)
{

  memcpy (&oampBme[pid.bmeNum].oampPort[pid.portNum].PmCounters,
          pPmCntr, sizeof(ipos_pm_counters));

  if (oampBme[pid.bmeNum].oampPort[pid.portNum].PmCounters.PortStartFlag || portStartCopy[pid.bmeNum][pid.portNum]) 
  {
        oampBme[pid.bmeNum].oampPort[pid.portNum].PmCountersAtPortStart.PmPeriodId = 0;

       memcpy(&oampBme[pid.bmeNum].oampPort[pid.portNum].PmCountersAtPortStart,
         pPmCntr24Hrs[pid.bmeNum][pid.portNum], sizeof(ipos_pm_counters));

	accumulatePMCounters(&oampBme[pid.bmeNum].oampPort[pid.portNum].PmCountersAtPortStart,
		&oampBme[pid.bmeNum].oampPort[pid.portNum].PmCounters);

        portStartCopy[pid.bmeNum][pid.portNum] = 0;
  }
}

/* Start : For PM Application */
/******************************************************************************
	Function		:	CreateTimer15Mins
	Description	:	Creates a 15 minutes timer and defines the timer handler
	Parameters	:	void
	Return Value	:	TRUE for Success, FALSE for Failure
 
******************************************************************************/
int CreateTimer15Mins()
{
	if (IPOS_ERROR == iposTmrInit())
	{
		printf("\nTimer Initialization for 15mins Timer : Failed");
		return FALSE;
	}
	
	if (IPOS_ERROR == iposCreateTmr(&tmr15mins))
	{
		printf("\nCreate 15mins Timer : Failed");
		return FALSE;
	}
	else
	{
		//For initial testing - use timecount=20 for 0.1 minutes or 6 secs
		//(i.e. simulate by sending PM timer 96 times before 24 Hrs timer reset) 
		//if (IPOS_ERROR == iposSetTmr(tmr15mins, (U16) (U16) 20, tmr15minsExp,(U32) 0, (U32)0))
			
		//set timer count 
		if (IPOS_ERROR == iposSetTmr(tmr15mins, (U16) timer15mins, (tmrExp)tmr15minsExp,(U32) 0, (U32)0))
		{
			printf("\niposSetTmr for 15mins Timer : Failed");
			return FALSE;
		}
	}
        printf("CreateTimer15Mins(): success \n");

	return TRUE;
}

/******************************************************************************
	Function		:	tmr15minsExp
	Description	:	Timer Expiry handler for 15 minutes timer	
	Parameters	:	U32 arg1, U32 arg2
	Return Value	:	TRUE for Success, FALSE for Failure 
 
******************************************************************************/

int tmr15minsExp(U32 arg1, U32 arg2)
{
	int bmeNum=1;
	ipos_port_id pid15mins;

	//Reset the timer
	if (IPOS_ERROR == iposResetTmr(tmr15mins))
	{
		printf("\n15MinsTimer Reset : Failed");
		return FALSE;
	}


	// Set the timer again

	//For initial testing - use timecount=20 for 0.1 minutes or 6 secs
	//(i.e. simulate by sending PM timer 96 times before 24 Hrs timer reset) 
	// if (IPOS_ERROR == iposSetTmr(tmr15mins, (U16) 20, tmr15minsExp,(U32) 0, (U32)0))

	if (IPOS_ERROR == iposSetTmr(tmr15mins, (U16) timer15mins, (tmrExp)tmr15minsExp,(U32) 0, (U32)0))
	{
		printf("\niposSetTmr for 15mins Timer : Failed");
		return FALSE;
	}

	if(oampGetOamOptionMask & 0x1)
	{
		for(bmeNum=1;bmeNum<=IPOS_MAX_BME;bmeNum++)
		{
			if(uRUN == oampBme[bmeNum].bmeState)
			{
				pid15mins.bmeNum=bmeNum;
				pid15mins.portNum=0;

				//Send PM Timer to BME
				if (IPOS_ERROR == iposPmTimer(pid15mins, (U8)0, (U32)0, (iposCbCtl)sendPmTimer15minsComplete))
				{
					printf("\nSendPMTimer on 15 minutes for BME%d : Failed", pid15mins.bmeNum);
					return FALSE;
				}
				// printf("\nSendPMTimer on 15 minutes for BME%d : Success", pid15mins.bmeNum);
			}
		}
	}
	
	return TRUE;
}

/******************************************************************************
	Function		:	tmr15minsExp
	Description	:	Display COMPLETE message for SendPMTimer message
	Parameters	:	U8 UID, U32 uPar
	Return Value	:	void
 
******************************************************************************/

void sendPmTimer15minsComplete(U8 UID, U32 uPar)
{
    return;
}


/******************************************************************************
	Function	:	KillTimer15Mins
	Description	:	Kill Respective Timer on BME Crash
	Parameters	:	 
	Return Value	:	 
 
******************************************************************************/

int KillTimer15Mins(int bmenum)
{
	if (IPOS_ERROR == iposFreeTmr(tmr15mins))
	{
		printf("\nKill 15MinsTimer for BME %d : Failed ", bmenum);
		return FALSE;
	}

	return TRUE;
}

/******************************************************************************
    Function        :   accumulatePMCounters
    Description :   accumulates the 1st argument cntrs with 2nd argument cntrs
    Parameters  :   Pointer to the PM structure
    Return Value    :   void
 
******************************************************************************/
void accumulatePMCounters(ipos_pm_counters *pPmAccCntr, ipos_pm_counters *pPmCntr)
{
        pPmAccCntr->FeCRC_S +=pPmCntr->FeCRC_S;
        pPmAccCntr->FeCRC_F +=pPmCntr->FeCRC_F;
        pPmAccCntr->FeES += pPmCntr->FeES;
        pPmAccCntr->FeESE += pPmCntr->FeESE;
        pPmAccCntr->FeUnavl += pPmCntr->FeUnavl;
        pPmAccCntr->FeFailures += pPmCntr->FeFailures;
        pPmAccCntr->FeFECS += pPmCntr->FeFECS;
        pPmAccCntr->FeFEC_S += pPmCntr->FeFEC_S;
        pPmAccCntr->FeFEC_F += pPmCntr->FeFEC_F;
        pPmAccCntr->FeHEC_S += pPmCntr->FeHEC_S;
        pPmAccCntr->FeHEC_F += pPmCntr->FeHEC_F;
        pPmAccCntr->FeLCD_S += pPmCntr->FeLCD_S;
        pPmAccCntr->FeLCD_F += pPmCntr->FeLCD_F;
        pPmAccCntr->FePO += pPmCntr->FePO;
        pPmAccCntr->FeLOM += pPmCntr->FeLOM;
        pPmAccCntr->FeLOS += pPmCntr->FeLOS;
        pPmAccCntr->FeLOSS += pPmCntr->FeLOSS;
        pPmAccCntr->FeLPR += pPmCntr->FeLPR;
        pPmAccCntr->FeNCD_S += pPmCntr->FeNCD_S;
        pPmAccCntr->FeNCD_F += pPmCntr->FeNCD_F;
        pPmAccCntr->FeRDI += pPmCntr->FeRDI;
        pPmAccCntr->FeSES += pPmCntr->FeSES;
        pPmAccCntr->FeTCA1 += pPmCntr->FeTCA1;
        pPmAccCntr->FeTCA2 += pPmCntr->FeTCA2;
        pPmAccCntr->NeCRC_S += pPmCntr->NeCRC_S;
        pPmAccCntr->NeCRC_F += pPmCntr->NeCRC_F;
        pPmAccCntr->NeES += pPmCntr->NeES;
        pPmAccCntr->NeESE += pPmCntr->NeESE;
        pPmAccCntr->NeUnavl += pPmCntr->NeUnavl;
        pPmAccCntr->NeFailures += pPmCntr->NeFailures;
        pPmAccCntr->NeFECS += pPmCntr->NeFECS;
        pPmAccCntr->NeFEC_S += pPmCntr->NeFEC_S;
        pPmAccCntr->NeFEC_F += pPmCntr->NeFEC_F;
        pPmAccCntr->NeHEC_S += pPmCntr->NeHEC_S;
        pPmAccCntr->NeHEC_F += pPmCntr->NeHEC_F;
        pPmAccCntr->NeLCD_S += pPmCntr->NeLCD_S;
        pPmAccCntr->NeLCD_F += pPmCntr->NeLCD_F;
        pPmAccCntr->NeLOF += pPmCntr->NeLOF;
        pPmAccCntr->NeLOM += pPmCntr->NeLOM;
        pPmAccCntr->NeLOS += pPmCntr->NeLOS;
        pPmAccCntr->NeLOSS += pPmCntr->NeLOSS;
        pPmAccCntr->NeNCD_S += pPmCntr->NeNCD_S;
        pPmAccCntr->NeNCD_F += pPmCntr->NeNCD_F;
        pPmAccCntr->NeSES += pPmCntr->NeSES;
        pPmAccCntr->NeTCA1 += pPmCntr->NeTCA1;
        pPmAccCntr->NeTCA2 += pPmCntr->NeTCA2;
        pPmAccCntr->numIDLEcell_S += pPmCntr->numIDLEcell_S;
        pPmAccCntr->numIDLEcell_F += pPmCntr->numIDLEcell_F;
        pPmAccCntr->numUSRcell_S += pPmCntr->numUSRcell_S;
        pPmAccCntr->numUSRcell_F += pPmCntr->numUSRcell_F;
        pPmAccCntr->numRxBlk_F += pPmCntr->numRxBlk_F;
        pPmAccCntr->numRxBlk_S += pPmCntr->numRxBlk_S;
        pPmAccCntr->numTxBlk_F += pPmCntr->numTxBlk_F;
        pPmAccCntr->numTxBlk_S += pPmCntr->numTxBlk_S;
        pPmAccCntr->NeFECUnCrr_F += pPmCntr->NeFECUnCrr_F;
        pPmAccCntr->NeFECUnCrr_S += pPmCntr->NeFECUnCrr_S;
        pPmAccCntr->numInitFailure += pPmCntr->numInitFailure;
        pPmAccCntr->numReInit += pPmCntr->numReInit;
}


/******************************************************************************
	Function		:	updatePMCounters24Hrs
	Description	:	Increments the 24Hrs counter values every 15 minutes
	Parameters	:	Pointer to the BME structure, Port Number. 
	Return Value	:	void
 
******************************************************************************/


void updatePMCounters24Hrs (ipos_pm_counters *pPm24hrs, ipos_pm_counters *pPmCntr, ipos_port_id pid)
{
	// Clear all values if 24 Hrs timer has expired
    if (pPm24hrs->PmPeriodId > 95)  /* 96 = ((24*60)/15) */
    {
        //printf("\nb%dp%d 24HrsCounters Reset", pid.bmeNum, pid.portNum);
        memcpy ((ipos_pm_counters*)pPm24hrs,(ipos_pm_counters*)pPmCntr, sizeof(ipos_pm_counters));
        memcpy (&oampBme[pid.bmeNum].oampPort[pid.portNum].PmCountersAtPortStart,(ipos_pm_counters*)pPmCntr, sizeof(ipos_pm_counters));
        pPm24hrs->PmPeriodId = 0;
    }
	// Update 24 Hrs timer values
	else
	{
        accumulatePMCounters(pPm24hrs, pPmCntr);
        ResetPMCounters (pPmCntr);
        pPm24hrs->PmPeriodId++;
    }
}


/******************************************************************************
    Function        :   ResetPMCounters 
    Description :   resets PM counters
    Parameters  :   Pointer to the PM structure
    Return Value    :   void
 
******************************************************************************/
void ResetPMCounters (ipos_pm_counters *pPmCntr)
{
      pPmCntr->FeCRC_S = 0;
      pPmCntr->FeCRC_F = 0;
      pPmCntr->FeES = 0;
      pPmCntr->FeESE = 0;
      pPmCntr->FeUnavl = 0;
      pPmCntr->FeFailures = 0;
      pPmCntr->FeFECS = 0;
      pPmCntr->FeFEC_S = 0;
      pPmCntr->FeFEC_F = 0;
      pPmCntr->FeHEC_S = 0;
      pPmCntr->FeHEC_F = 0;
      pPmCntr->FeLCD_S = 0;
      pPmCntr->FeLCD_F = 0;
      pPmCntr->FePO = 0;
      pPmCntr->FeLOM = 0;
      pPmCntr->FeLOS = 0;
      pPmCntr->FeLOSS = 0;
      pPmCntr->FeLPR = 0;
      pPmCntr->FeNCD_S = 0;
      pPmCntr->FeNCD_F = 0;
      pPmCntr->FeRDI = 0;
      pPmCntr->FeSES = 0;
      pPmCntr->FeTCA1 = 0;
      pPmCntr->FeTCA2 = 0;
      pPmCntr->NeCRC_S = 0;
      pPmCntr->NeCRC_F = 0;
      pPmCntr->NeES = 0;
      pPmCntr->NeESE = 0;
      pPmCntr->NeUnavl = 0;
      pPmCntr->NeFailures = 0;
      pPmCntr->NeFECS = 0;
      pPmCntr->NeFEC_S = 0;
      pPmCntr->NeFEC_F = 0;
      pPmCntr->NeHEC_S = 0;
      pPmCntr->NeHEC_F = 0;
      pPmCntr->NeLCD_S = 0;
      pPmCntr->NeLCD_F = 0;
      pPmCntr->NeLOF = 0;
      pPmCntr->NeLOM = 0;
      pPmCntr->NeLOS = 0;
      pPmCntr->NeLOSS = 0;
      pPmCntr->NeNCD_S = 0;
      pPmCntr->NeNCD_F = 0;
      pPmCntr->NeSES = 0;
      pPmCntr->NeTCA1 = 0;
      pPmCntr->NeTCA2 = 0;
      pPmCntr->numIDLEcell_S = 0;
      pPmCntr->numIDLEcell_F = 0;
      pPmCntr->numUSRcell_S = 0;
      pPmCntr->numUSRcell_F = 0;
      pPmCntr->numRxBlk_F = 0;
      pPmCntr->numRxBlk_S = 0;
      pPmCntr->numTxBlk_F = 0;
      pPmCntr->numTxBlk_S = 0;
      pPmCntr->NeFECUnCrr_F = 0;
      pPmCntr->NeFECUnCrr_S = 0;
      pPmCntr->numInitFailure = 0;
      pPmCntr->numReInit = 0;
    
}


/******************************************************************************** 
	Function		:	displayPMCounters24Hrs
	Description	:	
	Parameters	:	ipos_port_id pid 
	Return Value:	 
 
********************************************************************************/ 
void displayPMCounters24Hrs (ipos_port_id pid)
{
        ipos_pm_counters *pPm24hrs = pPmCntr24Hrs[pid.bmeNum][pid.portNum];
		int itime=0;
		itime = pPm24hrs->PmPeriodId * 15;
					
		printf ("\n\t PERFORMANCE MANAGEMENT DATA FOR 24 HOURS\n");
		printf ("\n=================================");
		printf ("\n Period Interval");
		if(pPm24hrs->PmPeriodId<4)
		{
			printf (": %d minutes", itime);
		}
		else
		{
			printf (": %.2f Hours ",(float)((float)itime/(float)60) );
		}
		printf ("\n=================================\n");
		printf ("\nALERTS");
		printf ("\n======");
		printf ("\nNear-End Failures: 0x%04X; Far-end Failures: 0x%04X",
		       pPm24hrs->NeFailures, pPm24hrs->FeFailures); 
		printf ("\nNear-End TCA1    : 0x%04X; Far-end TCA1    : 0x%04X",
		       pPm24hrs->NeTCA1, pPm24hrs->FeTCA1); 
		printf ("\nNear-End TCA2    : 0x%04X; Far-end TCA2    : 0x%04X",
		       pPm24hrs->NeTCA2, pPm24hrs->FeTCA2); 

		printf ("\n\nFAILURE COUNTS");
		printf ("\n==============");
		printf ("\nNeLOS=%u; NeLOF=%u; NeLOM=%u; NeESE=%u", pPm24hrs->NeLOS,
		      pPm24hrs->NeLOF, pPm24hrs->NeLOM, 
		      pPm24hrs->NeESE); 
		printf ("\nFeLOS=%u; FeLOF=%u; FeLPR=%u; FeLOM=%u; FeESE=%u", pPm24hrs->FeLOS,
		      pPm24hrs->FeRDI, pPm24hrs->FeLPR, 
		      pPm24hrs->FeLOM, pPm24hrs->FeESE); 
		printf ("\nNeNCD_S=%u; NeLCD_S=%u; NeNCD_F=%u; NeLCD_F=%u;", pPm24hrs->NeNCD_S,
		      pPm24hrs->NeLCD_S, pPm24hrs->NeNCD_F, 
		      pPm24hrs->NeLCD_F); 
		printf ("\nFeNCD_S=%u; FeLCD_S=%u; FeNCD_F=%u; FeLCD_F=%u;", pPm24hrs->FeNCD_S,
		      pPm24hrs->FeLCD_S, pPm24hrs->FeNCD_F, 
		      pPm24hrs->FeLCD_F); 

		printf ("\n\nCOUNT OF SECONDS WITH ANOMALY");
		printf ("\n=============================");
		printf ("\nNeFECS=%u; NeES=%u; NeSES=%u; NeLOSS=%u",
		      pPm24hrs->NeFECS, pPm24hrs->NeES, 
		      pPm24hrs->NeSES, pPm24hrs->NeLOSS);
		printf ("\nFeFECS=%u; FeES=%u; FeSES=%u; FeLOSS=%u",
		      pPm24hrs->FeFECS, pPm24hrs->FeES, 
		      pPm24hrs->FeSES, pPm24hrs->FeLOSS);

		printf ("\n\nANOMALY COUNTERS");
		printf ("\n================");
		printf ("\nNeFEC_S=%lu; NeFEC_F=%lu;", pPm24hrs->NeFEC_S, pPm24hrs->NeFEC_F);
		printf ("\nNeCRC_S=%lu; NeCRC_F=%lu;", pPm24hrs->NeCRC_S, pPm24hrs->NeCRC_F);
		printf ("\nNeHEC_S=%lu; NeHEC_F=%lu;", pPm24hrs->NeHEC_S, pPm24hrs->NeHEC_F);
		printf ("\nFeFEC_S=%lu; FeFEC_F=%lu;", pPm24hrs->FeFEC_S, pPm24hrs->FeFEC_F);
		printf ("\nFeCRC_S=%lu; FeCRC_F=%lu;", pPm24hrs->FeCRC_S, pPm24hrs->FeCRC_F);
		printf ("\nFeHEC_S=%lu; FeHEC_F=%lu;", pPm24hrs->FeHEC_S, pPm24hrs->FeHEC_F);

		printf ("\n\nCELL COUNTERS");
		printf ("\n=============");
		printf ("\nUser Cells(slow)=%lu; User Cells(fast)=%lu",
		       pPm24hrs->numUSRcell_S, pPm24hrs->numUSRcell_F);
		printf ("\nIdle Cells(slow)=%lu; Idle Cells(fast)=%lu",
		       pPm24hrs->numIDLEcell_S, pPm24hrs->numIDLEcell_F); 

}

/* End : For PM Application */

