/*
Copyright (c) 2000, 2001                      RIPE NCC


All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the author not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.

THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/*
-------------------------------------------------------------------------------
Module Header
Filename          : Delay.h
Author            : Rene Wilhelm
Date              : 07-JUL-2000
Revised		  : 02-JUL-2001, added symbolic names for clock status bits
Revised		  : 12-JUL-2001, define DelaySummary class
Description       : TTM Delay class definition
Language Version  : C++
OSs Tested        : Solaris 2.6

The Delay class groups all information for a single TestTraffic
Delay measurement. Usually, Delay objects are created from
"packet" structs (defined in packet.h) by a one to one copy
of struct fields to the private data members.

$Id: Delay.h,v 1.9 2003/06/19 13:58:57 ttraffic Exp $
-------------------------------------------------------------------------------
*/

#ifndef ROOT_Delay
#define ROOT_Delay


#include "TObject.h"

#include <iostream.h>
#include <time.h>
#include "packet.h"

// define macros for clock status
// STA_* symbolic names copied from  <sys/timex.h>
// (at least on Solaris CINT runs into problems when its inlcuded)

/*
 * Status codes (timex.status)
 */
#define STA_PLL         0x0001  /* enable PLL updates (rw) */
#define STA_PPSFREQ     0x0002  /* enable PPS freq discipline (rw) */
#define STA_PPSTIME     0x0004  /* enable PPS time discipline (rw) */
#define STA_FLL         0x0008  /* select frequency-lock mode (rw) */

#define STA_INS         0x0010  /* insert leap (rw) */
#define STA_DEL         0x0020  /* delete leap (rw) */
#define STA_UNSYNC      0x0040  /* clock unsynchronized (rw) */
#define STA_FREQHOLD    0x0080  /* hold frequency (rw) */

#define STA_PPSSIGNAL   0x0100  /* PPS signal present (ro) */
#define STA_PPSJITTER   0x0200  /* PPS signal jitter exceeded (ro) */
#define STA_PPSWANDER   0x0400  /* PPS signal wander exceeded (ro) */
#define STA_PPSERROR    0x0800  /* PPS signal calibration error (ro) */

#define STA_CLOCKERR    0x1000  /* clock hardware fault (ro) */
#define STA_NANO        0x2000  /* resolution (0 = us, 1 = ns) (ro) */

// LEAPBITMASK: bitwise AND with NTP status masks the leap second insertion bits
// GOODCLOCK  : required value of status word after the AND with LEAPBITMASK

#define LEAPBITMASK   ~(STA_INS | STA_DEL)

#define GPSGOODCLOCK1  (STA_PLL | STA_PPSFREQ | STA_PPSTIME | STA_PPSSIGNAL)
#define GPSGOODCLOCK2  (STA_NANO | GPSGOODCLOCK1 )

#define CDMAGOODCLOCK1 (STA_PLL)
#define CDMAGOODCLOCK2 (STA_NANO | CDMAGOODCLOCK1 )


class TDirectory;


enum PacketStatus {
	ClockValid,		// Clock valid at both ends
	ClockSrcValid,		// Clock valid at source only
	ClockTrgValid,		// Clock valid at target only
	ClockInvalid,		// Clock invalid at both ends
	PacketLost		// Packet Lost
};  

class Delay : public TObject {
	// result of one delay measurement

private:

	UInt_t     PacketId;        // Identifier of the packet 
	Int_t      SourceId;        // ID# of the sending testbox
	Int_t      SourcePort;      // Port from which the packet was sent
	Int_t      TargetId;        // ID# of the receiving testbox 
	Int_t      TargetPort;      // Port to which the packet was sent 
	Int_t      PacketSize;      // Packet size in bytes 
	Double_t   ArrivalTime;     // -1.0 if undefined 
	Double_t   PacketDelay;     // Delay in ms, -1.0 if undefined 
	UInt_t     SourceClock;     // Sending clock NTP status    
	UInt_t     TargetClock;     // Receiving clock NTP status 
	Int_t      Nhops;           // Number of hops, -1 if unknown
	Int_t      RouteId;         // Routing vector number, -1 if unknown 
	Float_t    SourceNtp;       // Sending clock NTP estimated error
	Float_t    TargetNtp;       // Receiving clock NTP estimated error

public:
	Delay();
	Delay (struct packet *);
	virtual ~Delay();

	void   SetPacketId    (UInt_t    n) {PacketId = n; }
	void   SetSourceId    (Int_t     n) {SourceId = n; }
	void   SetSourcePort  (Int_t     n) {SourcePort = n; }
	void   SetTargetId    (Int_t     n) {TargetId = n; }
	void   SetTargetPort  (Int_t     n) {TargetPort = n; }
	void   SetPacketSize  (Int_t     n) {PacketSize = n; }
	void   SetArrivalTime (Double_t  d) {ArrivalTime = d; }
	void   SetPacketDelay (Double_t  d) {PacketDelay = d; }
	void   SetSourceClock (UInt_t    n) {SourceClock = n; }
	void   SetTargetClock (UInt_t    n) {TargetClock = n; }
	void   SetNhops       (Int_t     n) {Nhops = n; }
	void   SetRouteId     (Int_t     n) {RouteId = n; }
	void   SetSourceNtp   (Float_t   f) {SourceNtp = f; }
	void   SetTargetNtp   (Float_t   f) {TargetNtp = f; }

	UInt_t     GetPacketId ()	{return PacketId;}
	Int_t      GetSourceId ()	{return SourceId;}
	Int_t      GetSourcePort ()	{return SourcePort;}
	Int_t      GetTargetId ()	{return TargetId;}
	Int_t      GetTargetPort ()	{return TargetPort;}
	Int_t      GetPacketSize ()	{return PacketSize;}
	Double_t   GetArrivalTime ()	{return ArrivalTime;}
	Double_t   GetPacketDelay ()	{return PacketDelay;}
	UInt_t     GetSourceClock ()	{return SourceClock;}
	UInt_t     GetTargetClock ()	{return TargetClock;}
	Int_t      GetNhops ()		{return Nhops;}
	Int_t      GetRouteId ()	{return RouteId;}
	Float_t    GetSourceNtp ()	{return SourceNtp;}
	Float_t    GetTargetNtp ()	{return TargetNtp;}

	Double_t   GetPacketTime (time_t starttime);
	Int_t      ClocksOK();
	PacketStatus	Status();

	ClassDef(Delay,1)  //Delay structure
};

//
//

class DelaySummary : public TObject {
	// summarizes delay measurement in a particular period
	
	// Days are divided in equal intervals of BinSize seconds
	// For each bin 2.5, 97.5 percentile and median are stored
	// If the period covered more than one day, results
        // of all days are accumulated. For instance, with 6 hour
	// intervals, bin 1 summarizes the results between 0000 and 0600
	// for the _entire_ NumDays period 

	// NOTE: the Bin with No 0 summarizes results over the entire
	// timeperiod, it is not a subdivision.
        

private:

	Int_t TargetId;		// target (receiving side) of measurement
	Int_t SourceId;		// source (sending side) of measurement
	Int_t BinNo;            // Interval No  (1..4)
	Int_t NumEntries;	// number of entries in the bin
	Double_t TimeLow;       // Lower bound of time interval
	Double_t BinSize;       // Size of time interval (seconds)
	Int_t    NumDays;	// Number of days 
	Double_t Level025;      // value of 2.5 percentile level
	Double_t Median;	// Median (50 percentile) value
	Double_t Level975;      // value of 97.5 percentile level
	Double_t Loss;          // Percentage of packets lost in this interval

public:
	DelaySummary();
	~DelaySummary();
	void   SetTargetId    (Int_t n)    {TargetId = n; }
	void   SetSourceId    (Int_t n)    {SourceId = n; }
	void   SetBinNo       (Int_t n)    {BinNo = n; }
	void   SetTimeLow     (Double_t t) {TimeLow = t; }
	void   SetBinSize     (Double_t t) {BinSize = t; }
	void   SetNumEntries  (Int_t n)    {NumEntries = n; }
	void   SetNumDays     (Int_t n)    {NumDays = n; }
	void   SetLevel025    (Double_t t) {Level025 = t; }
	void   SetMedian      (Double_t t) {Median = t; }
	void   SetLevel975    (Double_t t) {Level975 = t; }
	void   SetLoss        (Double_t t) {Loss = t; }

	Int_t     GetTargetId    () {return TargetId; }
	Int_t     GetSourceId    () {return SourceId; }
	Int_t     GetBinNo   	 () {return BinNo; }
	Int_t     GetNumEntries  () {return NumEntries; }
	Int_t     GetNumDays     () {return NumDays; }
	Double_t  GetTimeLow     () {return TimeLow; }
	Double_t  GetBinSize   	 () {return BinSize; }
	Double_t  GetLevel025    () {return Level025; }
	Double_t  GetMedian      () {return Median; }
	Double_t  GetLevel975    () {return Level975; }
	Double_t  GetLoss        () {return Loss; }
	
	ClassDef(DelaySummary,1)  // needed for ROOT & CINT
};


#endif
