Files
m241Neelima/components/ip_net2-6.9/ipptp/src/ptpd.h
T
2026-07-30 11:19:44 +05:30

530 lines
16 KiB
C

/**
* @file ptpd.h
* @mainpage Ptpd v2 Documentation
* @authors Martin Burnicki, Alexandre van Kempen, Steven Kreuzer,
* George Neville-Neil
* @version 2.0
* @date Fri Aug 27 10:22:19 2010
*
* @section implementation Implementation
* PTTdV2 is not a full implementation of 1588 - 2008 standard.
* It is implemented only with use of Transparent Clock and Peer delay
* mechanism, according to 802.1AS requierements.
*
* This header file includes all others headers.
* It defines functions which are not dependant of the operating system.
*/
/*
modification history
--------------------
17oct23,rjq Fix Y2038 issue.
15aug16,xxy Add PTP features.(F6696)
06jun16,xxy Fix unstable error.(VXW7-3677)
02feb16,h_l Init version.
*/
#ifndef PTPD_H_
#define PTPD_H_
#define VXWORKS_OS
#ifdef VXWORKS_OS
#define HAVE_SYS_TIMEX_H
#define _POSIX_TIMERS 200112L
#define PACKAGE_VERSION "2.3.1"
#define usleep(x) taskDelay(sysClkRateGet() * x / 1000000)
#endif /*endif VXWORKS_OS*/
#ifdef HAVE_CONFIG_H
# include <ipptp_config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <unistd.h>
#include <math.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <limits.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/resource.h>
#ifdef HAVE_SYS_TIMEX_H
#ifndef VXWORKS_OS
#include <sys/timex.h>
#else
/*below parts copied from include/uapi/linux/timx.h*/
struct timex {
int modes; /* mode selector */
long offset; /* time offset (usec) */
int freq; /* frequency offset (scaled ppm) */
long maxerror;/* maximum error (usec) */
long esterror;/* estimated error (usec) */
int status; /* clock command/status */
long constant;/* pll time constant */
long precision;/* clock precision (usec) (read only) */
long tolerance;/* clock frequency tolerance (ppm)
* (read only)
*/
struct timeval time; /* (read only, except for ADJ_SETOFFSET) */
unsigned int tick; /* (modified) usecs between clock ticks */
int tai; /* TAI offset (ro) */
};
/*
* Mode codes (timex.mode)
*/
#define ADJ_OFFSET 0x0001 /* time offset */
#define ADJ_FREQUENCY 0x0002 /* frequency offset */
#define ADJ_MAXERROR 0x0004 /* maximum time error */
#define ADJ_ESTERROR 0x0008 /* estimated time error */
#define ADJ_STATUS 0x0010 /* clock status */
#define ADJ_TIMECONST 0x0020 /* pll time constant */
#define ADJ_TAI 0x0080 /* set TAI offset */
#define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
#define ADJ_MICRO 0x1000 /* select microsecond resolution */
#define ADJ_NANO 0x2000 /* select nanosecond resolution */
#define ADJ_TICK 0x4000 /* tick value */
/* NTP userland likes the MOD_ prefix better */
#define MOD_OFFSET ADJ_OFFSET
#define MOD_FREQUENCY ADJ_FREQUENCY
#define MOD_MAXERROR ADJ_MAXERROR
#define MOD_ESTERROR ADJ_ESTERROR
#define MOD_STATUS ADJ_STATUS
#define MOD_TIMECONST ADJ_TIMECONST
#define MOD_TAI ADJ_TAI
#define MOD_MICRO ADJ_MICRO
#define MOD_NANO ADJ_NANO
/*
* 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) */
#define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */
#define STA_CLK 0x8000 /* clock source (0 = A, 1 = B) (ro) */
/* read-only bits */
#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)
/*
* Clock states (time_state)
*/
#define TIME_OK 0 /* clock synchronized, no leap second */
#define TIME_INS 1 /* insert leap second */
#define TIME_DEL 2 /* delete leap second */
#define TIME_OOP 3 /* leap second in progress */
#define TIME_WAIT 4 /* leap second has occurred */
#define TIME_ERROR 5 /* clock not synchronized */
#define TIME_BAD TIME_ERROR /* bw compat */
#endif
#endif
#include <sys/socket.h>
#include <ipcom_netif.h>
#ifdef VXWORKS_OS
#include <selectLib.h>
#else
#include <sys/select.h>
#endif
#include <sys/ioctl.h>
#ifndef VXWORKS_OS
#include <sys/param.h>
#endif
#include <arpa/inet.h>
#include <stdarg.h>
#include <syslog.h>
#include <limits.h>
#ifdef VXWORKS_OS
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#else
#include <getopt.h>
#endif
#include <ctype.h>
#ifndef VXWORKS_OS
#include <glob.h>
#endif
#include <stddef.h>
#include <stdint.h>
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#else
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif /* HAVE_UTMP_H */
#endif /* HAVE_UTMPX_H */
#ifdef HAVE_NET_ETHERNET_H
#include <net/ethernet.h>
#endif /* HAVE_NET_ETHERNET_H */
#include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#ifdef HAVE_NETINET_ETHER_H
#include <netinet/ether.h>
#endif /* HAVE_NETINET_ETHER_H */
#ifdef HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#endif /* HAVE_NET_IF_ARP_H*/
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif /* HAVE_NET_IF_H*/
#ifdef HAVE_NETINET_IF_ETHER_H
#include <netinet/if_ether.h>
#endif /* HAVE_NETINET_IF_ETHER_H */
/* This macro is to remove sudden jitter which would cause PTP unstable */
#define huge_jitter_counts_max 3
#ifdef HAVE_SYS_CPUSET_H
#include <sys/cpuset.h>
#endif /* HAVE_SYS_CPUSET_H */
#include "constants.h"
#include "limits.h"
#include "dep/ipv4_acl.h"
#include "dep/constants_dep.h"
#include "dep/datatypes_dep.h"
#include "datatypes.h"
#include "dep/ptpd_dep.h"
#include "dep/daemonconfig.h"
int64_t llabs(int64_t i);
/* NOTE: this macro can be refactored into a function */
#define XMALLOC(ptr,size) \
if(!((ptr)=malloc(size))) { \
PERROR("failed to allocate memory"); \
return; \
}
#define IS_SET(data, bitpos) \
((data & ( 0x1 << bitpos )) == (0x1 << bitpos))
#define SET_FIELD(data, bitpos) \
data << bitpos
/*
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
*/
/** \name arith.c
* -Timing management and arithmetic*/
/**\{*/
/* arith.c */
/**
* \brief Convert Integer64 into TimeInternal structure
*/
void integer64_to_internalTime(Integer64,TimeInternal*);
/**
* \brief Convert TimeInternal structure to Integer64
*/
void internalTime_to_integer64(TimeInternal, Integer64*);
/**
* \brief Convert TimeInternal into Timestamp structure (defined by the spec)
*/
void fromInternalTime(const TimeInternal*,Timestamp*);
/**
* \brief Convert Timestamp to TimeInternal structure (defined by the spec)
*/
void toInternalTime(TimeInternal*, const Timestamp*);
void ts_to_InternalTime(const struct timespec *, TimeInternal *);
void tv_to_InternalTime(const struct timeval *, TimeInternal *);
/**
* \brief Use to normalize a TimeInternal structure
*
* The nanosecondsField member must always be less than 10⁹
* This function is used after adding or substracting TimeInternal
*/
void normalizeTime(TimeInternal*);
/**
* \brief Add two InternalTime structure and normalize
*/
void addTime(TimeInternal*,const TimeInternal*,const TimeInternal*);
/**
* \brief Substract two InternalTime structure and normalize
*/
void subTime(TimeInternal*,const TimeInternal*,const TimeInternal*);
/** \}*/
/**
* \brief Divied an InternalTime by 2
*/
void div2Time(TimeInternal *);
/** \name bmc.c
* -Best Master Clock Algorithm functions*/
/**\{*/
/* bmc.c */
/**
* \brief Compare data set of foreign masters and local data set
* \return The recommended state for the port
*/
UInteger8 bmc(ForeignMasterRecord*, const RunTimeOpts*,PtpClock*);
/**
* \brief When recommended state is Master, copy local data into parent and grandmaster dataset
*/
void m1(const RunTimeOpts *, PtpClock*);
/**
* \brief When recommended state is Slave, copy dataset of master into parent and grandmaster dataset
*/
void s1(MsgHeader*,MsgAnnounce*,PtpClock*, const RunTimeOpts *);
void p1(PtpClock *ptpClock, const RunTimeOpts *rtOpts);
/**
* \brief Initialize datas
*/
void initData(RunTimeOpts*,PtpClock*);
/** \}*/
/** \name protocol.c
* -Execute the protocol engine*/
/**\{*/
/**
* \brief Protocol engine
*/
/* protocol.c */
void protocol(RunTimeOpts*,PtpClock*);
/** \}*/
/** \name management.c
* -Management message support*/
/**\{*/
/* management.c */
/**
* \brief Management message support
*/
void handleMMNullManagement(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMClockDescription(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMSlaveOnly(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMUserDescription(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMSaveInNonVolatileStorage(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMResetNonVolatileStorage(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMInitialize(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMDefaultDataSet(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMCurrentDataSet(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMParentDataSet(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMTimePropertiesDataSet(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMPortDataSet(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMPriority1(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMPriority2(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMDomain(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMLogAnnounceInterval(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMAnnounceReceiptTimeout(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMLogSyncInterval(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMVersionNumber(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMEnablePort(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMDisablePort(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMTime(MsgManagement*, MsgManagement*, PtpClock*, RunTimeOpts*);
void handleMMClockAccuracy(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMUtcProperties(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMTraceabilityProperties(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMDelayMechanism(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMLogMinPdelayReqInterval(MsgManagement*, MsgManagement*, PtpClock*);
void handleMMErrorStatus(MsgManagement*);
void handleErrorManagementMessage(MsgManagement *incoming, MsgManagement *outgoing,
PtpClock *ptpClock, Enumeration16 mgmtId,
Enumeration16 errorId);
/** \}*/
/*
* \brief Packing and Unpacking macros
*/
#define DECLARE_PACK( type ) void pack##type( void*, void* );
DECLARE_PACK( NibbleUpper )
DECLARE_PACK( Enumeration4Lower )
DECLARE_PACK( UInteger4Lower )
DECLARE_PACK( UInteger16 )
DECLARE_PACK( UInteger8 )
DECLARE_PACK( Octet )
DECLARE_PACK( Integer8 )
DECLARE_PACK( UInteger48 )
DECLARE_PACK( Integer64 )
#define DECLARE_UNPACK( type ) void unpack##type( void*, void*, PtpClock *ptpClock );
DECLARE_UNPACK( Boolean )
DECLARE_UNPACK( Enumeration4Lower )
DECLARE_UNPACK( Octet )
DECLARE_UNPACK( UInteger48 )
DECLARE_UNPACK( Integer64 )
/*Diplay functions usefull to debug */
void displayRunTimeOpts(const RunTimeOpts*);
void displayDefault (const PtpClock*);
void displayCurrent (const PtpClock*);
void displayParent (const PtpClock*);
void displayGlobal (const PtpClock*);
void displayPort (const PtpClock*);
void displayForeignMaster (const PtpClock*);
void displayOthers (const PtpClock*);
void displayBuffer (const PtpClock*);
void displayPtpClock (const PtpClock*);
void timeInternal_display(const TimeInternal*);
void clockIdentity_display(const ClockIdentity);
void netPath_display(const NetPath*);
void intervalTimer_display(const IntervalTimer*);
void integer64_display (const Integer64*);
void timeInterval_display(const TimeInterval*);
void portIdentity_display(const PortIdentity*);
void clockQuality_display (const ClockQuality*);
void PTPText_display(const PTPText*, const PtpClock*);
void unicast_display(const Octet*);
const char *portState_getName(Enumeration8 portState);
void timestamp_display(const Timestamp * timestamp);
void displayCounters(const PtpClock*);
void displayStatistics(const PtpClock*);
void clearCounters(PtpClock *);
void msgHeader_display(const MsgHeader*);
void msgAnnounce_display(const MsgAnnounce*);
void msgSync_display(const MsgSync *sync);
void msgFollowUp_display(const MsgFollowUp*);
void msgPDelayReq_display(const MsgPDelayReq*);
void msgDelayReq_display(const MsgDelayReq * req);
void msgDelayResp_display(const MsgDelayResp * resp);
void msgPDelayResp_display(const MsgPDelayResp * presp);
void msgPDelayRespFollowUp_display(const MsgPDelayRespFollowUp * prespfollow);
void msgManagement_display(const MsgManagement * manage);
void mMSlaveOnly_display(const MMSlaveOnly*, const PtpClock*);
void mMClockDescription_display(const MMClockDescription*, const PtpClock*);
void mMUserDescription_display(const MMUserDescription*, const PtpClock*);
void mMInitialize_display(const MMInitialize*, const PtpClock*);
void mMDefaultDataSet_display(const MMDefaultDataSet*, const PtpClock*);
void mMCurrentDataSet_display(const MMCurrentDataSet*, const PtpClock*);
void mMParentDataSet_display(const MMParentDataSet*, const PtpClock*);
void mMTimePropertiesDataSet_display(const MMTimePropertiesDataSet*, const PtpClock*);
void mMPortDataSet_display(const MMPortDataSet*, const PtpClock*);
void mMPriority1_display(const MMPriority1*, const PtpClock*);
void mMPriority2_display(const MMPriority2*, const PtpClock*);
void mMDomain_display(const MMDomain*, const PtpClock*);
void mMLogAnnounceInterval_display(const MMLogAnnounceInterval*, const PtpClock*);
void mMAnnounceReceiptTimeout_display(const MMAnnounceReceiptTimeout*, const PtpClock*);
void mMLogSyncInterval_display(const MMLogSyncInterval*, const PtpClock*);
void mMVersionNumber_display(const MMVersionNumber*, const PtpClock*);
void mMTime_display(const MMTime*, const PtpClock*);
void mMClockAccuracy_display(const MMClockAccuracy*, const PtpClock*);
void mMUtcProperties_display(const MMUtcProperties*, const PtpClock*);
void mMTraceabilityProperties_display(const MMTraceabilityProperties*, const PtpClock*);
void mMDelayMechanism_display(const MMDelayMechanism*, const PtpClock*);
void mMLogMinPdelayReqInterval_display(const MMLogMinPdelayReqInterval*, const PtpClock*);
void mMErrorStatus_display(const MMErrorStatus*, const PtpClock*);
void clearTime(TimeInternal *time);
char *dump_TimeInternal(const TimeInternal * p);
char *dump_TimeInternal2(const char *st1, const TimeInternal * p1, const char *st2, const TimeInternal * p2);
int snprint_TimeInternal(char *s, int max_len, const TimeInternal * p);
void nano_to_Time(TimeInternal *time, int nano);
int gtTime(const TimeInternal *x, const TimeInternal *b);
void absTime(TimeInternal *time);
int is_Time_close(const TimeInternal *x, const TimeInternal *b, int nanos);
int isTimeInternalNegative(const TimeInternal * p);
double timeInternalToDouble(const TimeInternal * p);
TimeInternal doubleToTimeInternal(const double d);
void toState(UInteger8,RunTimeOpts*,PtpClock*);
/* helper functions for leap second handling */
float secondsToMidnight(RunTimeOpts*);
float getPauseAfterMidnight(Integer8 announceInterval);
Boolean respectUtcOffset(RunTimeOpts * rtOpts, PtpClock * ptpClock);
void ptpdBondarySyncTime(int threadNum);
#endif /*PTPD_H_*/