Introduce the time status management message.
This non-portable, implementation specific message is designed to inform external programs about the relationship between the local clock and the remote master clock. Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
4e09ff8585
commit
6c54c31dca
19
clock.c
19
clock.c
|
@ -134,6 +134,7 @@ static int clock_management_response(struct clock *c, struct port *p, int id,
|
||||||
int datalen = 0, err, pdulen, respond = 0;
|
int datalen = 0, err, pdulen, respond = 0;
|
||||||
struct management_tlv *tlv;
|
struct management_tlv *tlv;
|
||||||
struct ptp_message *rsp;
|
struct ptp_message *rsp;
|
||||||
|
struct time_status_np *tsn;
|
||||||
struct PortIdentity pid = port_identity(p);
|
struct PortIdentity pid = port_identity(p);
|
||||||
|
|
||||||
rsp = port_management_reply(pid, p, req);
|
rsp = port_management_reply(pid, p, req);
|
||||||
|
@ -150,6 +151,24 @@ static int clock_management_response(struct clock *c, struct port *p, int id,
|
||||||
datalen = sizeof(c->cur);
|
datalen = sizeof(c->cur);
|
||||||
respond = 1;
|
respond = 1;
|
||||||
break;
|
break;
|
||||||
|
case TIME_STATUS_NP:
|
||||||
|
tsn = (struct time_status_np *) tlv->data;
|
||||||
|
tsn->master_offset = c->master_offset;
|
||||||
|
tsn->ingress_time = tmv_to_nanoseconds(c->t2);
|
||||||
|
tsn->cumulativeScaledRateOffset =
|
||||||
|
(UInteger32) (c->status.cumulativeScaledRateOffset +
|
||||||
|
c->nrr * POW2_41 - POW2_41);
|
||||||
|
tsn->scaledLastGmPhaseChange = c->status.scaledLastGmPhaseChange;
|
||||||
|
tsn->gmTimeBaseIndicator = c->status.gmTimeBaseIndicator;
|
||||||
|
tsn->lastGmPhaseChange = c->status.lastGmPhaseChange;
|
||||||
|
if (cid_eq(&c->dad.grandmasterIdentity, &c->dds.clockIdentity))
|
||||||
|
tsn->gmPresent = 0;
|
||||||
|
else
|
||||||
|
tsn->gmPresent = 1;
|
||||||
|
tsn->gmIdentity = c->dad.grandmasterIdentity;
|
||||||
|
datalen = sizeof(*tsn);
|
||||||
|
respond = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (respond) {
|
if (respond) {
|
||||||
tlv->length = sizeof(tlv->id) + datalen;
|
tlv->length = sizeof(tlv->id) + datalen;
|
||||||
|
|
25
pmc.c
25
pmc.c
|
@ -35,6 +35,7 @@
|
||||||
#define BAD_ID -1
|
#define BAD_ID -1
|
||||||
#define AMBIGUOUS_ID -2
|
#define AMBIGUOUS_ID -2
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
#define P41 ((double)(1ULL << 41))
|
||||||
|
|
||||||
static UInteger16 sequence_id;
|
static UInteger16 sequence_id;
|
||||||
static UInteger8 boundary_hops = 1;
|
static UInteger8 boundary_hops = 1;
|
||||||
|
@ -87,6 +88,7 @@ struct management_id idtab[] = {
|
||||||
{ "ALTERNATE_TIME_OFFSET_PROPERTIES", ALTERNATE_TIME_OFFSET_PROPERTIES, not_supported },
|
{ "ALTERNATE_TIME_OFFSET_PROPERTIES", ALTERNATE_TIME_OFFSET_PROPERTIES, not_supported },
|
||||||
{ "TRANSPARENT_CLOCK_DEFAULT_DATA_SET", TRANSPARENT_CLOCK_DEFAULT_DATA_SET, not_supported },
|
{ "TRANSPARENT_CLOCK_DEFAULT_DATA_SET", TRANSPARENT_CLOCK_DEFAULT_DATA_SET, not_supported },
|
||||||
{ "PRIMARY_DOMAIN", PRIMARY_DOMAIN, not_supported },
|
{ "PRIMARY_DOMAIN", PRIMARY_DOMAIN, not_supported },
|
||||||
|
{ "TIME_STATUS_NP", TIME_STATUS_NP, do_get_action },
|
||||||
/* Port management ID values */
|
/* Port management ID values */
|
||||||
{ "NULL_MANAGEMENT", NULL_MANAGEMENT, null_management },
|
{ "NULL_MANAGEMENT", NULL_MANAGEMENT, null_management },
|
||||||
{ "CLOCK_DESCRIPTION", CLOCK_DESCRIPTION, not_supported },
|
{ "CLOCK_DESCRIPTION", CLOCK_DESCRIPTION, not_supported },
|
||||||
|
@ -169,6 +171,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
|
||||||
struct TLV *tlv;
|
struct TLV *tlv;
|
||||||
struct management_tlv *mgt;
|
struct management_tlv *mgt;
|
||||||
struct currentDS *cds;
|
struct currentDS *cds;
|
||||||
|
struct time_status_np *tsn;
|
||||||
if (msg_type(msg) != MANAGEMENT) {
|
if (msg_type(msg) != MANAGEMENT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -202,6 +205,28 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
|
||||||
cds->stepsRemoved, cds->offsetFromMaster / 65536.0,
|
cds->stepsRemoved, cds->offsetFromMaster / 65536.0,
|
||||||
cds->meanPathDelay / 65536.0);
|
cds->meanPathDelay / 65536.0);
|
||||||
break;
|
break;
|
||||||
|
case TIME_STATUS_NP:
|
||||||
|
tsn = (struct time_status_np *) mgt->data;
|
||||||
|
fprintf(fp, "TIME_STATUS_NP "
|
||||||
|
IFMT "master_offset %lld "
|
||||||
|
IFMT "ingress_time %lld "
|
||||||
|
IFMT "cumulativeScaledRateOffset %+.9f "
|
||||||
|
IFMT "scaledLastGmPhaseChange %d "
|
||||||
|
IFMT "gmTimeBaseIndicator %hu "
|
||||||
|
IFMT "lastGmPhaseChange 0x%04hx'%016llx.%04hx "
|
||||||
|
IFMT "gmPresent %s "
|
||||||
|
IFMT "gmIdentity %s ",
|
||||||
|
tsn->master_offset,
|
||||||
|
tsn->ingress_time,
|
||||||
|
1.0 + (tsn->cumulativeScaledRateOffset + 0.0) / P41,
|
||||||
|
tsn->scaledLastGmPhaseChange,
|
||||||
|
tsn->gmTimeBaseIndicator,
|
||||||
|
tsn->lastGmPhaseChange.nanoseconds_msb,
|
||||||
|
tsn->lastGmPhaseChange.nanoseconds_lsb,
|
||||||
|
tsn->lastGmPhaseChange.fractional_nanoseconds,
|
||||||
|
tsn->gmPresent ? "true" : "false",
|
||||||
|
cid2str(&tsn->gmIdentity));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
|
|
22
tlv.c
22
tlv.c
|
@ -41,6 +41,7 @@ static void scaled_ns_h2n(ScaledNs *sns)
|
||||||
static void mgt_post_recv(struct management_tlv *m)
|
static void mgt_post_recv(struct management_tlv *m)
|
||||||
{
|
{
|
||||||
struct currentDS *cds;
|
struct currentDS *cds;
|
||||||
|
struct time_status_np *tsn;
|
||||||
switch (m->id) {
|
switch (m->id) {
|
||||||
case CURRENT_DATA_SET:
|
case CURRENT_DATA_SET:
|
||||||
cds = (struct currentDS *) m->data;
|
cds = (struct currentDS *) m->data;
|
||||||
|
@ -48,12 +49,23 @@ static void mgt_post_recv(struct management_tlv *m)
|
||||||
cds->offsetFromMaster = net2host64(cds->offsetFromMaster);
|
cds->offsetFromMaster = net2host64(cds->offsetFromMaster);
|
||||||
cds->meanPathDelay = net2host64(cds->meanPathDelay);
|
cds->meanPathDelay = net2host64(cds->meanPathDelay);
|
||||||
break;
|
break;
|
||||||
|
case TIME_STATUS_NP:
|
||||||
|
tsn = (struct time_status_np *) m->data;
|
||||||
|
tsn->master_offset = net2host64(tsn->master_offset);
|
||||||
|
tsn->ingress_time = net2host64(tsn->ingress_time);
|
||||||
|
tsn->cumulativeScaledRateOffset = ntohl(tsn->cumulativeScaledRateOffset);
|
||||||
|
tsn->scaledLastGmPhaseChange = ntohl(tsn->scaledLastGmPhaseChange);
|
||||||
|
tsn->gmTimeBaseIndicator = ntohs(tsn->gmTimeBaseIndicator);
|
||||||
|
scaled_ns_n2h(&tsn->lastGmPhaseChange);
|
||||||
|
tsn->gmPresent = ntohl(tsn->gmPresent);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mgt_pre_send(struct management_tlv *m)
|
static void mgt_pre_send(struct management_tlv *m)
|
||||||
{
|
{
|
||||||
struct currentDS *cds;
|
struct currentDS *cds;
|
||||||
|
struct time_status_np *tsn;
|
||||||
switch (m->id) {
|
switch (m->id) {
|
||||||
case CURRENT_DATA_SET:
|
case CURRENT_DATA_SET:
|
||||||
cds = (struct currentDS *) m->data;
|
cds = (struct currentDS *) m->data;
|
||||||
|
@ -61,6 +73,16 @@ static void mgt_pre_send(struct management_tlv *m)
|
||||||
cds->offsetFromMaster = host2net64(cds->offsetFromMaster);
|
cds->offsetFromMaster = host2net64(cds->offsetFromMaster);
|
||||||
cds->meanPathDelay = host2net64(cds->meanPathDelay);
|
cds->meanPathDelay = host2net64(cds->meanPathDelay);
|
||||||
break;
|
break;
|
||||||
|
case TIME_STATUS_NP:
|
||||||
|
tsn = (struct time_status_np *) m->data;
|
||||||
|
tsn->master_offset = host2net64(tsn->master_offset);
|
||||||
|
tsn->ingress_time = host2net64(tsn->ingress_time);
|
||||||
|
tsn->cumulativeScaledRateOffset = htonl(tsn->cumulativeScaledRateOffset);
|
||||||
|
tsn->scaledLastGmPhaseChange = htonl(tsn->scaledLastGmPhaseChange);
|
||||||
|
tsn->gmTimeBaseIndicator = htons(tsn->gmTimeBaseIndicator);
|
||||||
|
scaled_ns_h2n(&tsn->lastGmPhaseChange);
|
||||||
|
tsn->gmPresent = htonl(tsn->gmPresent);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
tlv.h
4
tlv.h
|
@ -167,10 +167,14 @@ struct follow_up_info_tlv {
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
struct time_status_np {
|
struct time_status_np {
|
||||||
|
int64_t master_offset; /*nanoseconds*/
|
||||||
|
int64_t ingress_time; /*nanoseconds*/
|
||||||
Integer32 cumulativeScaledRateOffset;
|
Integer32 cumulativeScaledRateOffset;
|
||||||
Integer32 scaledLastGmPhaseChange;
|
Integer32 scaledLastGmPhaseChange;
|
||||||
UInteger16 gmTimeBaseIndicator;
|
UInteger16 gmTimeBaseIndicator;
|
||||||
ScaledNs lastGmPhaseChange;
|
ScaledNs lastGmPhaseChange;
|
||||||
|
Integer32 gmPresent;
|
||||||
|
struct ClockIdentity gmIdentity;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue