pptp.h 11.2 KB
Newer Older
1
/*
2
 * Aurelio Colosimo for CERN, 2011 -- GNU LGPL v2.1 or later
3
 */
4

5 6 7 8 9 10
#ifndef __PTP_PROTO_H__
#define __PTP_PROTO_H__

#include <stdint.h>
#include <stdarg.h>
#include <arch/arch.h> /* ntohs and so on */
11 12 13
#include <pptp/lib.h>
#include <pptp/ieee1588_types.h>
#include <pptp/constants.h>
Aurelio Colosimo's avatar
Aurelio Colosimo committed
14

15 16

/*
17
 * Runtime options. Default values can be overridden by command line.
18 19
 */
struct pp_runtime_opts {
20
	ClockQuality clock_quality;
21
	TimeInternal inbound_latency, outbound_latency;
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
	Integer32 max_rst; /* Maximum number of nanoseconds to reset */
	Integer32 max_dly; /* Maximum number of nanoseconds of delay */
	Integer32 ttl;
	char *unicast_addr;
	UInteger32	slave_only:1,
			no_adjust:1,
			display_stats:1,
			csv_stats:1,
			ethernet_mode:1,
			e2e_mode:1,
			ofst_first_updated:1,
			no_rst_clk:1,
			use_syslog:1;
	Integer16 ap, ai;
	Integer16 s;
	Integer16 max_foreign_records;
	Integer16 cur_utc_ofst;
	Integer8 announce_intvl;
	Integer8 sync_intvl;
	UInteger8 prio1;
	UInteger8 prio2;
	UInteger8 domain_number;
	char *iface_name;
	void *arch_opts;

	/*TODO ARCH: arch_opts, for arch-gnu-linux, might include the following:
	 * int log_fd;
	 * char *record_file; [PP_PATH_MAX]
	 * FILE *record_fp;
	 * char *file; [PP_PATH_MAX]
	 */
53
};
54
extern struct pp_runtime_opts default_rt_opts; /* preinited with defaults */
55 56

/*
57 58
 * Communication channel. Is the abstraction of a posix socket, so that
 * this struct is platform independent
59
 */
60
struct pp_channel {
61
	union {
62
		int fd;		/* Posix wants fid descriptor */
63 64 65 66 67
		void *custom;	/* Other archs want other stuff */
	};
	void *arch_data;	/* Other arch-private info, if any */
	unsigned char addr[6];	/* Our own MAC address */
	unsigned char peer[6];	/* Our peer's MAC address */
68
	int pkt_present;
69 70
};

71 72 73
/*
 * Foreign master record. Used to manage Foreign masters
 */
74
struct pp_frgn_master {
75 76 77 78 79 80 81
	PortIdentity port_identity;
	UInteger16 ann_messages;

	//This one is not in the spec
	MsgAnnounce ann;
	MsgHeader hdr;
};
82 83

/*
84 85
 * Timer. Struct which contains timestamp of timer start and desired interval
 * for timer expiration computation. Both are seconds
86
 */
87
struct pp_timer {
88 89 90 91
	uint32_t start;
	uint32_t interval;
};

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132

/*
 * Servo. Structs which contain filters for delay average computation. They
 * are used in servo.c src, where specific function for time setting of the
 * machine are implemented.
 *
 * pp_ofm_fltr: The FIR filtering of the offset from master input is a simple,
 * two-sample average
 *
 * pp_owd_fltr: It is a variable cutoff/delay low-pass, infinite impulse
 * response (IIR) filter. The one-way delay filter has the difference equation:
 * s*y[n] - (s-1)*y[n-1] = x[n]/2 + x[n-1]/2,
 * where increasing the stiffness (s) lowers the cutoff and increases the delay.
 */
struct pp_ofm_fltr {
	Integer32 nsec_prev;
	Integer32 y;
};

struct pp_owd_fltr {
	Integer32 nsec_prev;
	Integer32 y;
	Integer32 s_exp;
};

struct pp_servo {
	/* TODO check. Which is the difference between m_to_s_dly (which
	 * comes from ptpd's master_to_slave_delay) and delay_ms (which comes
	 * from ptpd's delay_MS? Seems like ptpd actually uses only delay_MS.
	 * The same of course must be checked for their equivalents,
	 * s_to_m_dly and delay_sm
	 */
	TimeInternal m_to_s_dly;
	TimeInternal s_to_m_dly;
	TimeInternal delay_ms;
	TimeInternal delay_sm;
	Integer32 obs_drift;
	struct pp_owd_fltr owd_fltr;
	struct pp_ofm_fltr ofm_fltr;
};

133
/*
134 135
 * Net Path. Struct which contains the network configuration parameters and
 * the event/general channels (sockets on most platforms, see above)
136
 */
137 138 139

#define PP_NP_GEN	0
#define PP_NP_EVT	1
140
struct pp_net_path {
141 142
	struct pp_channel ch[2]; /* event and general channel (see above
				  * #define's */
143 144 145 146
	Integer32 ucast_addr;
	Integer32 mcast_addr;
	Integer32 peer_mcast_addr;
};
147

148
/*
149
 * Structure for the standard protocol
150 151 152
 */
struct pp_instance {
	int state;
153
	int next_state, next_delay, is_new_state; /* set by state processing */
154 155 156
	void *arch_data;		/* if arch needs it */
	void *ext_data;			/* if protocol ext needs it */
	struct pp_runtime_opts *rt_opts;
157
	struct pp_net_path *net_path;
158
	struct pp_servo *servo;
Aurelio Colosimo's avatar
Aurelio Colosimo committed
159 160 161 162 163 164 165

	/* Data sets */
	DSDefault *defaultDS;
	DSCurrent *currentDS;
	DSParent *parentDS;
	DSPort *portDS;
	DSTimeProperties *timePropertiesDS;
166
	struct pp_timer *timers[PP_TIMER_ARRAY_SIZE];
167

168
	/* FIXME: check the variables from now on. Now inherited from ptpd src*/
169 170 171 172 173
	UInteger16 number_foreign_records;
	Integer16  max_foreign_records;
	Integer16  foreign_record_i;
	Integer16  foreign_record_best;
	Boolean  record_update;
174
	struct pp_frgn_master *frgn_master;
175
	Octet *buf_out;
176
	Octet *buf_in;	/* FIXME really useful? Probably not*/
177 178
	TimeInternal sync_receive_time;
	UInteger16 recv_sync_sequence_id;
179 180 181

	TimeInternal last_rcv_time; /* used to store timestamp retreived from
				     * received packet */
182 183 184
	TimeInternal last_sync_corr_field;
	TimeInternal last_pdelay_req_corr_field;
	TimeInternal last_pdelay_resp_corr_field;
185 186 187 188
	TimeInternal pdelay_req_send_time;
	TimeInternal pdelay_req_receive_time;
	TimeInternal pdelay_resp_send_time;
	TimeInternal pdelay_resp_receive_time;
189 190 191
	TimeInternal delay_req_send_time;
	TimeInternal delay_req_receive_time;
	Integer8 log_min_delay_req_interval;
192

193 194 195 196 197 198 199 200 201 202 203 204
	union {
		MsgSync  sync;
		MsgFollowUp  follow;
		MsgDelayReq  req;
		MsgDelayResp resp;
		MsgPDelayReq  preq;
		MsgPDelayResp  presp;
		MsgPDelayRespFollowUp  prespfollow;
		MsgManagement  manage;
		MsgAnnounce  announce;
		MsgSignaling signaling;
	} msg_tmp;
205 206 207 208 209
	UInteger16 *sent_seq_id; /* sequence id of the last message sent of the
				  * same type
				  */
	MsgHeader msg_tmp_header;
	MsgHeader pdelay_req_hdr;
210
	MsgHeader delay_req_hdr;
211 212 213 214
	UInteger32
		is_from_self:1,
		is_from_cur_par:1,
		waiting_for_follow:1;
215 216
};

217 218
#define OPTS(x) ((x)->rt_opts)

219 220 221 222 223
#define DSDEF(x) ((x)->defaultDS)
#define DSCUR(x) ((x)->currentDS)
#define DSPAR(x) ((x)->parentDS)
#define DSPOR(x) ((x)->portDS)
#define DSPRO(x) ((x)->timePropertiesDS)
224

225
#define NP(x) ((x)->net_path)
226

227 228
#define SRV(x) ((x)->servo)

229 230
/* The channel for an instance must be created and possibly destroyed. */
extern int pp_open_instance(struct pp_instance *ppi,
231
			    struct pp_runtime_opts *rt_opts);
232 233 234 235 236

extern int pp_close_instance(struct pp_instance *ppi);

extern int pp_parse_cmdline(struct pp_instance *ppi, int argc, char **argv);

237
/* Network stuff */
238
extern int pp_net_init(struct pp_instance *ppi);
239
extern int pp_net_shutdown(struct pp_instance *ppi);
240 241
extern int pp_recv_packet(struct pp_instance *ppi, void *pkt, int len,
			  TimeInternal *t);
242 243
extern int pp_send_packet(struct pp_instance *ppi, void *pkt, int len,
			  int chtype); /* chtype: PP_NP_GEN || PP_NP_EVT */
244

245
/* Timers */
246
extern int pp_timer_init(struct pp_instance *ppi); /* initializes timer common
247
						      structure */
248
extern int pp_timer_start(uint32_t interval, struct pp_timer *tm);
249
extern int pp_timer_stop(struct pp_timer *tm);
250
extern int pp_timer_expired(struct pp_timer *tm); /* returns 1 when expired */
251

252
/* Servo */
253
extern void pp_init_clock(struct pp_instance *ppi);
254 255
extern void pp_update_delay(struct pp_instance *ppi,
			    TimeInternal *correction_field);
256 257 258 259
extern void pp_update_offset(struct pp_instance *ppi,
			     TimeInternal *send_time,
			     TimeInternal *recv_time,
			     TimeInternal *correctionField);
260 261 262
			/* FIXME: offset_from_master_filter: put it in ppi */
extern void pp_update_clock(struct pp_instance *ppi);

263

264 265
/* bmc.c */
extern void m1(struct pp_instance *ppi);
266 267 268 269
extern void s1(struct pp_instance *ppi, MsgHeader *header, MsgAnnounce *ann);
extern UInteger8 bmc(struct pp_instance *ppi,
		     struct pp_frgn_master *frgn_master,
		     struct pp_runtime_opts *rt_opts);
270 271

/* msg.c */
272 273
extern void msg_pack_header(struct pp_instance *ppi, void *buf);
extern void msg_unpack_header(struct pp_instance *ppi, void *buf);
274
void *msg_copy_header(MsgHeader *dest, MsgHeader *src);
275
extern void msg_pack_sync(struct pp_instance *ppi, Timestamp *orig_tstamp);
276
extern void msg_unpack_sync(void *buf, MsgSync *sync);
277
extern void msg_pack_announce(struct pp_instance *ppi);
278
extern void msg_unpack_announce(void *buf, MsgAnnounce *ann);
279
extern void msg_pack_follow_up(struct pp_instance *ppi,
280
			       Timestamp *prec_orig_tstamp);
281
extern void msg_unpack_follow_up(void *buf, MsgFollowUp *flwup);
282
extern void msg_pack_pdelay_req(struct pp_instance *ppi,
283
				Timestamp *orig_tstamp);
284
extern void msg_unpack_pdelay_req(void *buf, MsgPDelayReq *pdelay_req);
285
extern void msg_pack_delay_req(struct pp_instance *ppi,
286
			       Timestamp *orig_tstamp);
287
extern void msg_unpack_delay_req(void *buf, MsgDelayReq *delay_req);
288
extern void msg_pack_delay_resp(struct pp_instance *ppi,
289
				MsgHeader *hdr, Timestamp *rcv_tstamp);
290
extern void msg_unpack_delay_resp(void *buf, MsgDelayResp *resp);
291
extern void msg_pack_pdelay_resp(struct pp_instance *ppi,
292
				 MsgHeader *hdr, Timestamp *req_rec_tstamp);
293
extern void msg_unpack_pdelay_resp(void *buf, MsgPDelayResp *presp);
294
extern void msg_pack_pdelay_resp_followup(struct pp_instance *ppi,
295 296
					  MsgHeader *hdr,
					  Timestamp *resp_orig_tstamp);
297 298 299
extern void msg_unpack_pdelay_resp_followup(void *buf,
	MsgPDelayRespFollowUp *presp_follow);

300 301 302 303 304 305 306 307 308 309 310
/* each of them returns 0 if no error and -1 in case of error in send */
extern int msg_issue_announce(struct pp_instance *ppi);
extern int msg_issue_sync(struct pp_instance *ppi);
extern int msg_issue_followup(struct pp_instance *ppi, TimeInternal *time);
extern int msg_issue_delay_req(struct pp_instance *ppi);
extern int msg_issue_pdelay_req(struct pp_instance *ppi);
extern int msg_issue_pdelay_resp(struct pp_instance *ppi, TimeInternal *time,
			MsgHeader *hdr);
extern int msg_issue_delay_resp(struct pp_instance *ppi, TimeInternal *time);
extern int msg_issue_pdelay_resp_follow_up(struct pp_instance *ppi,
			TimeInternal *time);
311

312 313

/* Functions for timestamp handling (internal to protocol format conversion*/
314 315
/* FIXME: add prefix in function name? */
extern void int64_to_TimeInternal(Integer64 bigint, TimeInternal *internal);
316 317
extern int from_TimeInternal(TimeInternal *internal, Timestamp *external);
extern int to_TimeInternal(TimeInternal *internal, Timestamp *external);
318 319
extern void add_TimeInternal(TimeInternal *r, TimeInternal *x, TimeInternal *y);
extern void sub_TimeInternal(TimeInternal *r, TimeInternal *x, TimeInternal *y);
320
extern void set_TimeInternal(TimeInternal *t, Integer32 s, Integer32 ns);
321

322
/* Get and Set system timestamp */
323
extern void pp_get_tstamp(TimeInternal *t);
324
extern void pp_set_tstamp(TimeInternal *t);
325

326 327 328
/* Virtualization of Linux adjtimex (or BSD adjtime) system clock time
 * adjustment. Boolean: returns 1 in case of success and 0 if failure */
extern int pp_adj_freq(Integer32 adj);
329
extern const Integer32 PP_ADJ_FREQ_MAX;
330

331 332 333 334 335 336 337 338 339 340 341 342
/*
 * The state machine itself is an array of these structures.
 */

struct pp_state_table_item {
	int state;
	int (*f1)(struct pp_instance *ppi, uint8_t *packet, int plen);
	int (*f2)(struct pp_instance *ppi, uint8_t *packet, int plen);
};

extern struct pp_state_table_item pp_state_table[]; /* 0-terminated */

343

344

345
/* Use a typedef, to avoid long prototypes */
346 347 348 349
typedef int pp_action(struct pp_instance *ppi, uint8_t *packet, int plen);

/* Standard state-machine functions */
extern pp_action pp_initializing, pp_faulty, pp_disabled, pp_listening,
350 351
		 pp_pre_master, pp_master, pp_passive, pp_uncalibrated,
		 pp_slave;
352 353 354 355 356 357 358 359 360 361 362

/* The engine */
extern int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen);

/*
 * FIXME
 * Whe talk raw sockets on PP_PROTO_NR.
 */
#define PP_PROTO_NR	0xcccc

#endif /* __PTP_PROTO_H__ */