msg.c 17.1 KB
Newer Older
1
/*
2 3
 * Copyright (C) 2011 CERN (www.cern.ch)
 * Author: Aurelio Colosimo
4
 * Based on PTPd project v. 2.1.0 (see AUTHORS for details)
5 6
 *
 * Released according to the GNU LGPL, version 2.1 or any later version.
7 8
 */

Alessandro Rubini's avatar
Alessandro Rubini committed
9
#include <ppsi/ppsi.h>
10
#include "common-fun.h"
11

12
/* Unpack header from in buffer to receieved_ptp_header field */
13
int msg_unpack_header(struct pp_instance *ppi, void *buf, int plen)
14
{
15
	MsgHeader *hdr = &ppi->received_ptp_header;
16
	uint32_t lsb, msb;
17 18 19
	hdr->transportSpecific = (*(Nibble *) (buf + 0)) >> 4;
	hdr->messageType = (*(Enumeration4 *) (buf + 0)) & 0x0F;
	hdr->versionPTP = (*(UInteger4 *) (buf + 1)) & 0x0F;
20

21
	/* force reserved bit to zero if not */
22
	hdr->messageLength = htons(*(UInteger16 *) (buf + 2));
23 24
	hdr->domainNumber = (*(UInteger8 *) (buf + 4));

25
	memcpy(hdr->flagField, (buf + 6), PP_FLAG_FIELD_LENGTH);
26

27 28
	msb = htonl(*(uint32_t *)(buf + 8));
	lsb = htonl(*(uint32_t *)(buf + 12));
29 30
	hdr->cField.secs = 0LL;
	hdr->cField.scaled_nsecs = (uint64_t)msb << 32 | (uint64_t)lsb;
31
	memcpy(&hdr->sourcePortIdentity.clockIdentity, (buf + 20),
32 33
	       PP_CLOCK_IDENTITY_LENGTH);
	hdr->sourcePortIdentity.portNumber =
34 35
		htons(*(UInteger16 *) (buf + 28));
	hdr->sequenceId = htons(*(UInteger16 *) (buf + 30));
36 37
	hdr->logMessageInterval = (*(Integer8 *) (buf + 33));

38

39
	/*
40
	 * This FLAG_FROM_CURRENT_PARENT must be killed. Meanwhile, say it's
41 42 43 44
	 * from current parent if we have no current parent, so the rest works
	 */
	if (!DSPAR(ppi)->parentPortIdentity.portNumber ||
	    (!memcmp(&DSPAR(ppi)->parentPortIdentity.clockIdentity,
45
			&hdr->sourcePortIdentity.clockIdentity,
46 47
			PP_CLOCK_IDENTITY_LENGTH) &&
			(DSPAR(ppi)->parentPortIdentity.portNumber ==
48
			 hdr->sourcePortIdentity.portNumber)))
49
		ppi->flags |= PPI_FLAG_FROM_CURRENT_PARENT;
50
	else
51
		ppi->flags &= ~PPI_FLAG_FROM_CURRENT_PARENT;
52
	return 0;
53 54
}

55
/* Pack header into output buffer -- only called by state-initializing */
56
void msg_init_header(struct pp_instance *ppi, void *buf)
57
{
58 59 60
	memset(buf, 0, 34);
	*(char *)(buf + 1) = DSPOR(ppi)->versionNumber;
	*(char *)(buf + 4) = DSDEF(ppi)->domainNumber;
61

62
	memcpy((buf + 20), &DSPOR(ppi)->portIdentity.clockIdentity,
63
	       PP_CLOCK_IDENTITY_LENGTH);
64
	*(UInteger16 *)(buf + 28) =
65
				htons(DSPOR(ppi)->portIdentity.portNumber);
66 67
}

68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/* Helper used by all "msg_pack" below */
static int __msg_pack_header(struct pp_instance *ppi, unsigned msgtype)
{
	struct pp_msgtype_info *i = pp_msgtype_info + msgtype;
	void *buf = ppi->tx_ptp;
	int len, log;
	uint16_t *flags16 = buf + 6;
	signed char *logp = buf + 33;


	if (msgtype > 15)
		return 0;

	len = i->msglen;
	log = i->logMessageInterval;
	*(char *)(buf + 0) = msgtype;
	*(UInteger16 *) (buf + 2) = htons(len);
	memset((buf + 8), 0, 8); /* correctionField: default is cleared */
	*flags16 = 0; /* most message types wont 0 here */
	*(UInteger8 *)(buf + 32) = i->controlField;
	switch(log) {
	case PP_LOG_ANNOUNCE:
		*logp = DSPOR(ppi)->logAnnounceInterval; break;
	case PP_LOG_SYNC:
		*logp = DSPOR(ppi)->logSyncInterval; break;
	case PP_LOG_REQUEST:
		*logp = DSPOR(ppi)->logMinDelayReqInterval; break;
	default:
		*logp = log; break;
	}
	return len;
}

101
/* Pack Sync message into out buffer of ppi */
102
static int msg_pack_sync(struct pp_instance *ppi, struct pp_time *orig_tstamp)
103
{
104 105
	void *buf = ppi->tx_ptp;
	UInteger8 *flags8 = buf + 6;;
106
	int len = __msg_pack_header(ppi, PPM_SYNC);
107

108
	ppi->sent_seq[PPM_SYNC]++;
109
	/* Header */
110
	flags8[0] = PP_TWO_STEP_FLAG; /* Table 20 */
111
	*(UInteger16 *) (buf + 30) = htons(ppi->sent_seq[PPM_SYNC]);
112 113

	/* Sync message */
114 115 116
	*(UInteger16 *)(buf + 34) = htons(orig_tstamp->secs >> 32);
	*(UInteger32 *)(buf + 36) = htonl(orig_tstamp->secs);
	*(UInteger32 *)(buf + 40) = htonl(orig_tstamp->scaled_nsecs >> 16);
117
	return len;
118 119
}

120 121
/* Unpack Sync message from in buffer */
void msg_unpack_sync(void *buf, MsgSync *sync)
122
{
123 124 125 126 127 128 129
	int64_t secs, nsecs;

	secs = htons(*(UInteger16 *) (buf + 34));
	secs <<= 32;
	secs |= htonl(*(UInteger32 *) (buf + 36));
	nsecs = htonl(*(UInteger32 *) (buf + 40));

130
	/* The cField is added in the caller according to 1-step vs. 2-step */
131 132
	sync->originTimestamp.secs = secs;
	sync->originTimestamp.scaled_nsecs = nsecs << 16;
133 134
}

135 136 137 138 139
/*
 * Setup flags for an announce message.
 * Set byte 1 of flags taking it from timepropertiesDS' flags field,
 * see 13.3.2.6, Table 20
 */
140
static void msg_set_announce_flags(struct pp_instance *ppi, UInteger8 *flags)
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
{
	struct DSTimeProperties *prop = DSPRO(ppi);
	const Boolean *ptrs[] = {
		&prop->leap61,
		&prop->leap59,
		&prop->currentUtcOffsetValid,
		&prop->ptpTimescale,
		&prop->timeTraceable,
		&prop->frequencyTraceable,
	};
	int i;

	/*
	 * alternate master always false, twoStepFlag false in announce,
	 * unicastFlag always false, other flags always false
	 */
	flags[0] = 0;
	for (flags[1] = 0, i = 0; i < ARRAY_SIZE(ptrs); i++)
		if (*ptrs[i])
			flags[1] |= (1 << i);
}

163
/* Pack Announce message into out buffer of ppi */
164
static int msg_pack_announce(struct pp_instance *ppi)
165
{
166 167
	void *buf = ppi->tx_ptp;
	UInteger8 *flags8 = buf + 6;;
168
	int len = __msg_pack_header(ppi, PPM_ANNOUNCE);
169

170 171
	ppi->sent_seq[PPM_ANNOUNCE]++;
	/* Header */
172
	msg_set_announce_flags(ppi, flags8);
173
	*(UInteger16 *) (buf + 30) = htons(ppi->sent_seq[PPM_ANNOUNCE]);
174 175

	/* Announce message */
176
	memset((buf + 34), 0, 10);
177
	*(Integer16 *) (buf + 44) = htons(DSPRO(ppi)->currentUtcOffset);
178
	*(UInteger8 *) (buf + 47) = DSPAR(ppi)->grandmasterPriority1;
179 180
	*(UInteger8 *) (buf + 48) = DSPAR(ppi)->grandmasterClockQuality.clockClass;
	*(Enumeration8 *) (buf + 49) = DSPAR(ppi)->grandmasterClockQuality.clockAccuracy;
181
	*(UInteger16 *) (buf + 50) =
182
		htons(DSPAR(ppi)->grandmasterClockQuality.offsetScaledLogVariance);
183
	*(UInteger8 *) (buf + 52) = DSPAR(ppi)->grandmasterPriority2;
184
	memcpy((buf + 53), &DSPAR(ppi)->grandmasterIdentity,
185
	       PP_CLOCK_IDENTITY_LENGTH);
186
	*(UInteger16 *) (buf + 61) = htons(DSCUR(ppi)->stepsRemoved);
187
	*(Enumeration8 *) (buf + 63) = DSPRO(ppi)->timeSource;
188

189
	if (pp_hooks.pack_announce)
190 191
		len = pp_hooks.pack_announce(ppi);
	return len;
192 193
}

194
/* Unpack Announce message from in buffer of ppi to internal structure */
195
void msg_unpack_announce(void *buf, MsgAnnounce *ann)
196
{
197
	ann->originTimestamp.secondsField.msb =
198
		htons(*(UInteger16 *) (buf + 34));
199
	ann->originTimestamp.secondsField.lsb =
200
		htonl(*(UInteger32 *) (buf + 36));
201
	ann->originTimestamp.nanosecondsField =
202
		htonl(*(UInteger32 *) (buf + 40));
203
	ann->currentUtcOffset = htons(*(UInteger16 *) (buf + 44));
204 205
	ann->grandmasterPriority1 = *(UInteger8 *) (buf + 47);
	ann->grandmasterClockQuality.clockClass =
206
		*(UInteger8 *) (buf + 48);
207
	ann->grandmasterClockQuality.clockAccuracy =
208
		*(Enumeration8 *) (buf + 49);
209
	ann->grandmasterClockQuality.offsetScaledLogVariance =
210
		htons(*(UInteger16 *) (buf + 50));
211
	ann->grandmasterPriority2 = *(UInteger8 *) (buf + 52);
212
	memcpy(&ann->grandmasterIdentity, (buf + 53),
213
	       PP_CLOCK_IDENTITY_LENGTH);
214
	ann->stepsRemoved = htons(*(UInteger16 *) (buf + 61));
215 216
	ann->timeSource = *(Enumeration8 *) (buf + 63);

217 218
	if (pp_hooks.unpack_announce)
		pp_hooks.unpack_announce(buf, ann);
219 220
}

221
/* Pack Follow Up message into out buffer of ppi*/
222 223
static int msg_pack_follow_up(struct pp_instance *ppi,
			       struct pp_time *prec_orig_tstamp)
224
{
225
	void *buf = ppi->tx_ptp;
226
	int len = __msg_pack_header(ppi, PPM_FOLLOW_UP);
227

228
	/* Header */
229
	*(UInteger16 *) (buf + 30) = htons(ppi->sent_seq[PPM_SYNC]);
230

231
	/* Follow Up message */
232 233 234
	*(UInteger16 *)(buf + 34) = htons(prec_orig_tstamp->secs >> 32);
	*(UInteger32 *)(buf + 36) = htonl(prec_orig_tstamp->secs);
	*(UInteger32 *)(buf + 40) = htonl(prec_orig_tstamp->scaled_nsecs >> 16);
235 236 237
	/* Fractional part in cField */
	*(UInteger32 *)(buf + 12) =
		htonl(prec_orig_tstamp->scaled_nsecs & 0xffff);
238
	return len;
239 240
}

241
/* Pack PDelay Follow Up message into out buffer of ppi*/
242
static int msg_pack_pdelay_resp_follow_up(struct pp_instance *ppi,
243 244
					  MsgHeader * hdr,
					  struct pp_time *prec_orig_tstamp)
245
{
246
	void *buf = ppi->tx_ptp;
247
	int len = __msg_pack_header(ppi, PPM_PDELAY_R_FUP);
248

249
	/* Header */
250
	*(UInteger8 *) (buf + 4) = hdr->domainNumber; /* FIXME: why? */
251 252 253 254
	/* We should copy the correction field and add our fractional part */
	hdr->cField.scaled_nsecs
		+= htonl(prec_orig_tstamp->scaled_nsecs & 0xffff);
	normalize_pp_time(&hdr->cField);
255 256
	*(Integer32 *) (buf + 8) = htonl(hdr->cField.scaled_nsecs >> 32);
	*(Integer32 *) (buf + 12) = htonl((int)hdr->cField.scaled_nsecs);
257

258 259 260
	*(UInteger16 *) (buf + 30) = htons(hdr->sequenceId);

	/* requestReceiptTimestamp */
261 262 263
	*(UInteger16 *)(buf + 34) = htons(prec_orig_tstamp->secs >> 32);
	*(UInteger32 *)(buf + 36) = htonl(prec_orig_tstamp->secs);
	*(UInteger32 *)(buf + 40) = htonl(prec_orig_tstamp->scaled_nsecs >> 16);
264 265 266 267 268

	/* requestingPortIdentity */
	memcpy((buf + 44), &hdr->sourcePortIdentity.clockIdentity,
	       PP_CLOCK_IDENTITY_LENGTH);
	*(UInteger16 *) (buf + 52) = htons(hdr->sourcePortIdentity.portNumber);
269
	return len;
270 271
}

272
/* Unpack FollowUp message from in buffer of ppi to internal structure */
273
void msg_unpack_follow_up(void *buf, MsgFollowUp *flwup)
274
{
275 276 277 278 279 280 281
	int64_t secs, nsecs;

	secs = htons(*(UInteger16 *) (buf + 34));
	secs <<= 32;
	secs |= htonl(*(UInteger32 *) (buf + 36));
	nsecs = htonl(*(UInteger32 *) (buf + 40));

282
	/* cField add1ed by the caller, from already-converted header */
283 284
	flwup->preciseOriginTimestamp.secs = secs;
	flwup->preciseOriginTimestamp.scaled_nsecs = nsecs << 16;
285 286
}

287
/* Unpack PDelayRespFollowUp message from in buffer of ppi to internal struct */
288 289 290
void msg_unpack_pdelay_resp_follow_up(void *buf,
				      MsgPDelayRespFollowUp * pdelay_resp_flwup)
{
291
	int64_t secs, nsecs;
292 293 294 295 296 297

	secs = htons(*(UInteger16 *) (buf + 34));
	secs <<= 32;
	secs |= htonl(*(UInteger32 *) (buf + 36));
	nsecs = htonl(*(UInteger32 *) (buf + 40));

298
	/* cField added by the caller, as it's already converted */
299 300 301 302
	pdelay_resp_flwup->responseOriginTimestamp.secs = secs;
	pdelay_resp_flwup->responseOriginTimestamp.scaled_nsecs =
		nsecs << 16;

303 304 305 306 307 308
	memcpy(&pdelay_resp_flwup->requestingPortIdentity.clockIdentity,
	       (buf + 44), PP_CLOCK_IDENTITY_LENGTH);
	pdelay_resp_flwup->requestingPortIdentity.portNumber =
	    htons(*(UInteger16 *) (buf + 52));
}

309
/* pack DelayReq message into out buffer of ppi */
310
static int msg_pack_delay_req(struct pp_instance *ppi,
311
			       struct pp_time *now)
312
{
313
	void *buf = ppi->tx_ptp;
314
	int len = __msg_pack_header(ppi, PPM_DELAY_REQ);
315

316
	ppi->sent_seq[PPM_DELAY_REQ]++;
317
	/* Header */
318
	*(UInteger16 *) (buf + 30) = htons(ppi->sent_seq[PPM_DELAY_REQ]);
319

320 321 322 323
	/* Delay_req message - we may send zero instead */
	*(UInteger16 *) (buf + 34) = htons(now->secs >> 32);
	*(UInteger32 *) (buf + 36) = htonl(now->secs);
	*(UInteger32 *) (buf + 40) = htonl(now->scaled_nsecs >> 16);
324
	return len;
325 326
}

327
/* pack DelayReq message into out buffer of ppi */
328
static int msg_pack_pdelay_req(struct pp_instance *ppi,
329
				struct pp_time *now)
330
{
331
	void *buf = ppi->tx_ptp;
332
	int len = __msg_pack_header(ppi, PPM_PDELAY_REQ);
333

334
	ppi->sent_seq[PPM_PDELAY_REQ]++;
335
	/* Header */
336 337
	*(UInteger16 *) (buf + 30) = htons(ppi->sent_seq[PPM_PDELAY_REQ]);

338 339 340 341
	/* PDelay_req message - we may send zero instead */
	*(UInteger16 *) (buf + 34) = htons(now->secs >> 32);
	*(UInteger32 *) (buf + 36) = htonl(now->secs);
	*(UInteger32 *) (buf + 40) = htonl(now->scaled_nsecs >> 16);
342
	memset(buf + 44, 0, 10); /* reserved to match pdelay_resp length */
343
	return len;
344 345
}

346
/* pack PDelayResp message into OUT buffer of ppi */
347
static int msg_pack_pdelay_resp(struct pp_instance *ppi,
348
			  MsgHeader * hdr, struct pp_time *rcv_tstamp)
349
{
350 351
	void *buf = ppi->tx_ptp;
	UInteger8 *flags8 = buf + 6;;
352
	int len = __msg_pack_header(ppi, PPM_PDELAY_RESP);
353

354 355
	/* Header */
	flags8[0] = PP_TWO_STEP_FLAG; /* Table 20) */
356 357
	*(UInteger16 *) (buf + 30) = htons(hdr->sequenceId);

358 359 360 361
	/* cField: shdould be the fractional negated (see README-cfield) */
	*(UInteger32 *) (buf + 12)
		= htonl(rcv_tstamp->scaled_nsecs & 0xffff);

362
	/* requestReceiptTimestamp */
363 364 365
	*(UInteger16 *) (buf + 34) = htons(rcv_tstamp->secs >> 32);
	*(UInteger32 *) (buf + 36) = htonl(rcv_tstamp->secs);
	*(UInteger32 *) (buf + 40) = htonl(rcv_tstamp->scaled_nsecs >> 16);
366 367 368 369 370

	/* requestingPortIdentity */
	memcpy((buf + 44), &hdr->sourcePortIdentity.clockIdentity,
	       PP_CLOCK_IDENTITY_LENGTH);
	*(UInteger16 *) (buf + 52) = htons(hdr->sourcePortIdentity.portNumber);
371
	return len;
372 373
}

374
/* pack DelayResp message into OUT buffer of ppi */
375
static int msg_pack_delay_resp(struct pp_instance *ppi,
376
			 MsgHeader *hdr, struct pp_time *rcv_tstamp)
377
{
378
	void *buf = ppi->tx_ptp;
379
	int len = __msg_pack_header(ppi, PPM_DELAY_RESP);
380

381
	/* Header */
382 383 384 385
	/*
	 * We should copy the cField of the request, and then subract
	 * our fractional part. However, we add it (see README-cfield::BUG)
	 */
386 387
	*(Integer32 *) (buf + 8) = 0;
	*(Integer32 *) (buf + 12) = htonl(rcv_tstamp->scaled_nsecs & 0xffff);
388
	*(UInteger16 *) (buf + 30) = htons(hdr->sequenceId);
389

390
	/* Delay_resp message */
391 392 393 394
	*(UInteger16 *)(buf + 34) = htons(rcv_tstamp->secs >> 32);
	*(UInteger32 *)(buf + 36) = htonl(rcv_tstamp->secs);
	*(UInteger32 *)(buf + 40) = htonl(rcv_tstamp->scaled_nsecs >> 16);

395
	memcpy((buf + 44), &hdr->sourcePortIdentity.clockIdentity,
396
		  PP_CLOCK_IDENTITY_LENGTH);
397
	*(UInteger16 *) (buf + 52) =
398
		htons(hdr->sourcePortIdentity.portNumber);
399
	return len;
400 401
}

402
/* Unpack delayReq message from in buffer of ppi to internal structure */
403
void msg_unpack_delay_req(void *buf, MsgDelayReq *delay_req)
404
{
405 406 407 408 409 410 411 412
	int64_t secs, nsecs;

	secs = htons(*(UInteger16 *) (buf + 34));
	secs <<= 32;
	secs |= htonl(*(UInteger32 *) (buf + 36));
	nsecs = htonl(*(UInteger32 *) (buf + 40));

	delay_req->originTimestamp.secs = secs;
413
	delay_req->originTimestamp.scaled_nsecs = nsecs << 16;;
414 415
}

416
/* Unpack PDelayReq message from in buffer of ppi to internal structure */
417 418
void msg_unpack_pdelay_req(void *buf, MsgPDelayReq * pdelay_req)
{
419 420 421 422 423 424 425 426 427
	int64_t secs, nsecs;

	secs = htons(*(UInteger16 *) (buf + 34));
	secs <<= 32;
	secs |= htonl(*(UInteger32 *) (buf + 36));
	nsecs = htonl(*(UInteger32 *) (buf + 40));

	pdelay_req->originTimestamp.secs = secs;
	pdelay_req->originTimestamp.scaled_nsecs = nsecs << 16;
428 429
}

430
/* Unpack delayResp message from IN buffer of ppi to internal structure */
431
void msg_unpack_delay_resp(void *buf, MsgDelayResp *resp)
432
{
433
	int64_t secs, nsecs;
434 435 436 437 438 439

	secs = htons(*(UInteger16 *) (buf + 34));
	secs <<= 32;
	secs |= htonl(*(UInteger32 *) (buf + 36));
	nsecs = htonl(*(UInteger32 *) (buf + 40));

440
	/* cfield added in the caller */
441 442 443
	resp->receiveTimestamp.secs = secs;
	resp->receiveTimestamp.scaled_nsecs = nsecs << 16;

444
	memcpy(&resp->requestingPortIdentity.clockIdentity,
445
	       (buf + 44), PP_CLOCK_IDENTITY_LENGTH);
446
	resp->requestingPortIdentity.portNumber =
447
		htons(*(UInteger16 *) (buf + 52));
448 449
}

450
/* Unpack PDelayResp message from IN buffer of ppi to internal structure */
451 452
void msg_unpack_pdelay_resp(void *buf, MsgPDelayResp * presp)
{
453
	int64_t secs, nsecs;
454

455
	secs = ntohs(*(UInteger16 *) (buf + 34));
456
	secs <<= 32;
457 458
	secs |= ntohl(*(UInteger32 *) (buf + 36));
	nsecs = ntohl(*(UInteger32 *) (buf + 40));
459

460
	/* cfield added in the caller */
461 462 463
	presp->requestReceiptTimestamp.secs = secs;
	presp->requestReceiptTimestamp.scaled_nsecs = nsecs << 16;

464 465 466 467 468 469
	memcpy(&presp->requestingPortIdentity.clockIdentity,
	       (buf + 44), PP_CLOCK_IDENTITY_LENGTH);
	presp->requestingPortIdentity.portNumber =
	    htons(*(UInteger16 *) (buf + 52));
}

470 471 472
/* Pack and send on general multicast ip adress an Announce message */
int msg_issue_announce(struct pp_instance *ppi)
{
473 474
	int len = msg_pack_announce(ppi);

475
	return __send_and_log(ppi, len, PP_NP_GEN);
476 477 478
}

/* Pack and send on event multicast ip adress a Sync message */
479
int msg_issue_sync_followup(struct pp_instance *ppi)
480
{
481
	struct pp_time now;
482
	int e, len;
483

484 485
	/* Send sync on the event channel with the "current" timestamp */
	ppi->t_ops->get(ppi, &now);
486
	len = msg_pack_sync(ppi, &now);
487
	e = __send_and_log(ppi, len, PP_NP_EVT);
488 489 490
	if (e) return e;

	/* Send followup on general channel with sent-stamp of sync */
491
	len = msg_pack_follow_up(ppi, &ppi->last_snt_time);
492
	return __send_and_log(ppi, len, PP_NP_GEN);
493 494
}

495
/* Pack and send on general multicast ip address a FollowUp message */
496
int msg_issue_pdelay_resp_followup(struct pp_instance *ppi, struct pp_time *t)
497
{
498 499
	int len;

500
	len = msg_pack_pdelay_resp_follow_up(ppi, &ppi->received_ptp_header, t);
501
	return __send_and_log(ppi, len, PP_NP_GEN);
502 503
}

504
/* Pack and send on event multicast ip adress a DelayReq message */
505
static int msg_issue_delay_req(struct pp_instance *ppi)
506
{
507
	struct pp_time now;
508 509
	int len;

510
	ppi->t_ops->get(ppi, &now);
511
	len = msg_pack_delay_req(ppi, &now);
512

513
	return __send_and_log(ppi, len, PP_NP_EVT);
514 515
}

516
/* Pack and send on event multicast ip adress a PDelayReq message */
517
static int msg_issue_pdelay_req(struct pp_instance *ppi)
518
{
519
	struct pp_time now;
520 521
	int len;

522
	ppi->t_ops->get(ppi, &now);
523
	len = msg_pack_pdelay_req(ppi, &now);
524
	return __send_and_log(ppi, len, PP_NP_EVT);
525 526
}

527 528
int msg_issue_request(struct pp_instance *ppi)
{
529
	if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
530 531
		return msg_issue_pdelay_req(ppi);
	return msg_issue_delay_req(ppi);
532 533
}

534
/* Pack and send on event multicast ip adress a DelayResp message */
535
int msg_issue_delay_resp(struct pp_instance *ppi, struct pp_time *t)
536
{
537 538
	int len;

539
	len = msg_pack_delay_resp(ppi, &ppi->received_ptp_header, t);
540
	return __send_and_log(ppi, len, PP_NP_GEN);
541
}
542 543

/* Pack and send on event multicast ip adress a DelayResp message */
544
int msg_issue_pdelay_resp(struct pp_instance *ppi, struct pp_time *t)
545
{
546 547
	int len;

548
	len = msg_pack_pdelay_resp(ppi, &ppi->received_ptp_header, t);
549
	return __send_and_log(ppi, len, PP_NP_EVT);
550
}