Implement the master sync timer and message.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
39f5b2c449
commit
e2c02e49c7
3
fd.h
3
fd.h
|
@ -20,7 +20,7 @@
|
||||||
#ifndef HAVE_FD_H
|
#ifndef HAVE_FD_H
|
||||||
#define HAVE_FD_H
|
#define HAVE_FD_H
|
||||||
|
|
||||||
#define N_TIMER_FDS 4
|
#define N_TIMER_FDS 5
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FD_EVENT,
|
FD_EVENT,
|
||||||
|
@ -29,6 +29,7 @@ enum {
|
||||||
FD_DELAY_TIMER,
|
FD_DELAY_TIMER,
|
||||||
FD_QUALIFICATION_TIMER,
|
FD_QUALIFICATION_TIMER,
|
||||||
FD_MANNO_TIMER,
|
FD_MANNO_TIMER,
|
||||||
|
FD_SYNC_TIMER,
|
||||||
N_POLLFD,
|
N_POLLFD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
2
msg.c
2
msg.c
|
@ -205,7 +205,7 @@ int msg_pre_send(struct ptp_message *m)
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SYNC:
|
case SYNC:
|
||||||
return -1;
|
break;
|
||||||
case DELAY_REQ:
|
case DELAY_REQ:
|
||||||
break;
|
break;
|
||||||
case PDELAY_REQ:
|
case PDELAY_REQ:
|
||||||
|
|
87
port.c
87
port.c
|
@ -53,6 +53,7 @@ struct port {
|
||||||
struct {
|
struct {
|
||||||
UInteger16 announce;
|
UInteger16 announce;
|
||||||
UInteger16 delayreq;
|
UInteger16 delayreq;
|
||||||
|
UInteger16 sync;
|
||||||
} seqnum;
|
} seqnum;
|
||||||
struct tmtab tmtab;
|
struct tmtab tmtab;
|
||||||
/* portDS */
|
/* portDS */
|
||||||
|
@ -271,6 +272,15 @@ static int port_set_qualification_tmo(struct port *p)
|
||||||
return timerfd_settime(p->fda.fd[FD_QUALIFICATION_TIMER], 0, &tmo, NULL);
|
return timerfd_settime(p->fda.fd[FD_QUALIFICATION_TIMER], 0, &tmo, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int port_set_sync_tmo(struct port *p)
|
||||||
|
{
|
||||||
|
struct itimerspec tmo = {
|
||||||
|
{0, 0}, {0, 0}
|
||||||
|
};
|
||||||
|
tmo.it_value.tv_sec = (1 << p->logSyncInterval);
|
||||||
|
return timerfd_settime(p->fda.fd[FD_SYNC_TIMER], 0, &tmo, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void port_synchronize(struct port *p,
|
static void port_synchronize(struct port *p,
|
||||||
struct timespec ingress_ts,
|
struct timespec ingress_ts,
|
||||||
struct timestamp origin_ts,
|
struct timestamp origin_ts,
|
||||||
|
@ -387,6 +397,76 @@ out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int port_tx_sync(struct port *p)
|
||||||
|
{
|
||||||
|
struct ptp_message *msg, *fup;
|
||||||
|
int cnt, err = 0, pdulen;
|
||||||
|
|
||||||
|
msg = msg_allocate();
|
||||||
|
if (!msg)
|
||||||
|
return -1;
|
||||||
|
fup = msg_allocate();
|
||||||
|
if (!fup) {
|
||||||
|
msg_put(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(msg, 0, sizeof(*msg));
|
||||||
|
memset(fup, 0, sizeof(*fup));
|
||||||
|
|
||||||
|
pdulen = sizeof(struct sync_msg);
|
||||||
|
msg->hwts.type = p->timestamping;
|
||||||
|
|
||||||
|
msg->header.tsmt = SYNC;
|
||||||
|
msg->header.ver = PTP_VERSION;
|
||||||
|
msg->header.messageLength = pdulen;
|
||||||
|
msg->header.domainNumber = clock_domain_number(p->clock);
|
||||||
|
msg->header.sourcePortIdentity = p->portIdentity;
|
||||||
|
msg->header.sequenceId = p->seqnum.sync++;
|
||||||
|
msg->header.control = CTL_SYNC;
|
||||||
|
msg->header.logMessageInterval = p->logSyncInterval;
|
||||||
|
|
||||||
|
msg->header.flagField[0] |= TWO_STEP;
|
||||||
|
|
||||||
|
if (msg_pre_send(msg)) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cnt = p->transport->send(&p->fda, 1, msg, pdulen, &msg->hwts);
|
||||||
|
if (cnt <= 0) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the follow up message right away.
|
||||||
|
*/
|
||||||
|
pdulen = sizeof(struct follow_up_msg);
|
||||||
|
fup->hwts.type = p->timestamping;
|
||||||
|
|
||||||
|
fup->header.tsmt = FOLLOW_UP;
|
||||||
|
fup->header.ver = PTP_VERSION;
|
||||||
|
fup->header.messageLength = pdulen;
|
||||||
|
fup->header.domainNumber = clock_domain_number(p->clock);
|
||||||
|
fup->header.sourcePortIdentity = p->portIdentity;
|
||||||
|
fup->header.sequenceId = p->seqnum.sync - 1;
|
||||||
|
fup->header.control = CTL_FOLLOW_UP;
|
||||||
|
fup->header.logMessageInterval = p->logSyncInterval;
|
||||||
|
|
||||||
|
ts_to_timestamp(&msg->hwts.ts, &fup->follow_up.preciseOriginTimestamp);
|
||||||
|
|
||||||
|
if (msg_pre_send(fup)) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cnt = p->transport->send(&p->fda, 0, fup, pdulen, &fup->hwts);
|
||||||
|
if (cnt <= 0)
|
||||||
|
err = -1;
|
||||||
|
out:
|
||||||
|
msg_put(msg);
|
||||||
|
msg_put(fup);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int port_initialize(struct port *p)
|
static int port_initialize(struct port *p)
|
||||||
{
|
{
|
||||||
int fd[N_TIMER_FDS], i;
|
int fd[N_TIMER_FDS], i;
|
||||||
|
@ -721,6 +801,7 @@ void port_dispatch(struct port *p, enum fsm_event event)
|
||||||
port_clr_tmo(p->fda.fd[FD_DELAY_TIMER]);
|
port_clr_tmo(p->fda.fd[FD_DELAY_TIMER]);
|
||||||
port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]);
|
port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]);
|
||||||
port_clr_tmo(p->fda.fd[FD_MANNO_TIMER]);
|
port_clr_tmo(p->fda.fd[FD_MANNO_TIMER]);
|
||||||
|
port_clr_tmo(p->fda.fd[FD_SYNC_TIMER]);
|
||||||
|
|
||||||
switch (next) {
|
switch (next) {
|
||||||
case PS_INITIALIZING:
|
case PS_INITIALIZING:
|
||||||
|
@ -736,6 +817,7 @@ void port_dispatch(struct port *p, enum fsm_event event)
|
||||||
case PS_MASTER:
|
case PS_MASTER:
|
||||||
case PS_GRAND_MASTER:
|
case PS_GRAND_MASTER:
|
||||||
port_set_manno_tmo(p);
|
port_set_manno_tmo(p);
|
||||||
|
port_set_sync_tmo(p);
|
||||||
break;
|
break;
|
||||||
case PS_PASSIVE:
|
case PS_PASSIVE:
|
||||||
port_set_announce_tmo(p);
|
port_set_announce_tmo(p);
|
||||||
|
@ -776,6 +858,11 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
||||||
pr_debug("port %hu: master tx announce timeout", portnum(p));
|
pr_debug("port %hu: master tx announce timeout", portnum(p));
|
||||||
port_set_manno_tmo(p);
|
port_set_manno_tmo(p);
|
||||||
return port_tx_announce(p) ? EV_FAULT_DETECTED : EV_NONE;
|
return port_tx_announce(p) ? EV_FAULT_DETECTED : EV_NONE;
|
||||||
|
|
||||||
|
case FD_SYNC_TIMER:
|
||||||
|
pr_debug("port %hu: master sync timeout", portnum(p));
|
||||||
|
port_set_sync_tmo(p);
|
||||||
|
return port_tx_sync(p) ? EV_FAULT_DETECTED : EV_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = msg_allocate();
|
msg = msg_allocate();
|
||||||
|
|
Loading…
Reference in New Issue