pmc: support retrieving neighborPropDelayThresh and asCapable using management interface

Define new PORT_DATA_SET_NP TLV
neighborPropDelayThresh can also be set using the same TLV

Signed-off-by: Delio Brignoli <dbrignoli@audioscience.com>
master
Delio Brignoli 2014-02-04 10:56:06 +01:00 committed by Richard Cochran
parent f36af8e0c3
commit 29063a8227
6 changed files with 67 additions and 0 deletions

2
pmc.8
View File

@ -128,6 +128,8 @@ length TLV values instead.
.TP
.B PORT_DATA_SET
.TP
.B PORT_DATA_SET_NP
.TP
.B PRIORITY1
.TP
.B PRIORITY2

24
pmc.c
View File

@ -106,6 +106,7 @@ struct management_id idtab[] = {
{ "TRANSPARENT_CLOCK_PORT_DATA_SET", TRANSPARENT_CLOCK_PORT_DATA_SET, not_supported },
{ "DELAY_MECHANISM", DELAY_MECHANISM, do_get_action },
{ "LOG_MIN_PDELAY_REQ_INTERVAL", LOG_MIN_PDELAY_REQ_INTERVAL, do_get_action },
{ "PORT_DATA_SET_NP", PORT_DATA_SET_NP, do_set_action },
};
static char *action_string[] = {
@ -194,6 +195,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct grandmaster_settings_np *gsn;
struct mgmt_clock_description *cd;
struct portDS *p;
struct port_ds_np *pnp;
if (msg_type(msg) != MANAGEMENT) {
return;
}
@ -436,6 +438,14 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
p->logSyncInterval, p->delayMechanism,
p->logMinPdelayReqInterval, p->versionNumber);
break;
case PORT_DATA_SET_NP:
pnp = (struct port_ds_np *) mgt->data;
fprintf(fp, "PORT_DATA_SET_NP "
IFMT "neighborPropDelayThresh %u"
IFMT "asCapable %d",
pnp->neighborPropDelayThresh,
pnp->asCapable ? 1 : 0);
break;
case LOG_ANNOUNCE_INTERVAL:
mtd = (struct management_tlv_datum *) mgt->data;
fprintf(fp, "LOG_ANNOUNCE_INTERVAL "
@ -483,6 +493,7 @@ static void do_get_action(int action, int index, char *str)
static void do_set_action(int action, int index, char *str)
{
struct grandmaster_settings_np gsn;
struct port_ds_np pnp;
int cnt, code = idtab[index].code;
int leap_61, leap_59, utc_off_valid;
int ptp_timescale, time_traceable, freq_traceable;
@ -546,6 +557,19 @@ static void do_set_action(int action, int index, char *str)
gsn.time_flags |= FREQ_TRACEABLE;
pmc_send_set_action(pmc, code, &gsn, sizeof(gsn));
break;
case PORT_DATA_SET_NP:
cnt = sscanf(str, " %*s %*s "
"neighborPropDelayThresh %u "
"asCapable %d ",
&pnp.neighborPropDelayThresh,
&pnp.asCapable);
if (cnt != 2) {
fprintf(stderr, "%s SET needs 2 values\n",
idtab[index].name);
break;
}
pmc_send_set_action(pmc, code, &pnp, sizeof(pnp));
break;
}
}

View File

@ -204,6 +204,9 @@ static int pmc_tlv_datalen(struct pmc *pmc, int id)
case PORT_DATA_SET:
len += sizeof(struct portDS);
break;
case PORT_DATA_SET_NP:
len += sizeof(struct port_ds_np);
break;
case LOG_ANNOUNCE_INTERVAL:
case ANNOUNCE_RECEIPT_TIMEOUT:
case LOG_SYNC_INTERVAL:

18
port.c
View File

@ -602,6 +602,7 @@ static int port_management_get_response(struct port *target,
struct management_tlv_datum *mtd;
struct ptp_message *rsp;
struct portDS *pds;
struct port_ds_np *pdsnp;
struct PortIdentity pid = port_identity(target);
struct clock_description *desc;
struct mgmt_clock_description *cd;
@ -749,6 +750,13 @@ static int port_management_get_response(struct port *target,
datalen = sizeof(*mtd);
respond = 1;
break;
case PORT_DATA_SET_NP:
pdsnp = (struct port_ds_np *) tlv->data;
pdsnp->neighborPropDelayThresh = target->neighborPropDelayThresh;
pdsnp->asCapable = target->asCapable;
datalen = sizeof(*pdsnp);
respond = 1;
break;
}
if (respond) {
if (datalen % 2) {
@ -775,7 +783,17 @@ static int port_management_set(struct port *target,
struct ptp_message *req)
{
int respond = 0;
struct management_tlv *tlv;
struct port_ds_np *pdsnp;
tlv = (struct management_tlv *) req->management.suffix;
switch (id) {
case PORT_DATA_SET_NP:
pdsnp = (struct port_ds_np *) tlv->data;
target->neighborPropDelayThresh = pdsnp->neighborPropDelayThresh;
respond = 1;
break;
}
if (respond && !port_management_get_response(target, ingress, id, req))
pr_err("port %hu: failed to send management set response", portnum(target));

14
tlv.c
View File

@ -59,6 +59,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
struct parentDS *pds;
struct timePropertiesDS *tp;
struct portDS *p;
struct port_ds_np *pdsnp;
struct time_status_np *tsn;
struct grandmaster_settings_np *gsn;
struct mgmt_clock_description *cd;
@ -234,6 +235,13 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
ntohs(gsn->clockQuality.offsetScaledLogVariance);
gsn->utc_offset = ntohs(gsn->utc_offset);
break;
case PORT_DATA_SET_NP:
if (data_len != sizeof(struct port_ds_np))
goto bad_length;
pdsnp = (struct port_ds_np *) m->data;
pdsnp->neighborPropDelayThresh = ntohl(pdsnp->neighborPropDelayThresh);
pdsnp->asCapable = ntohl(pdsnp->asCapable);
break;
}
if (extra_len) {
if (extra_len % 2)
@ -253,6 +261,7 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra)
struct parentDS *pds;
struct timePropertiesDS *tp;
struct portDS *p;
struct port_ds_np *pdsnp;
struct time_status_np *tsn;
struct grandmaster_settings_np *gsn;
struct mgmt_clock_description *cd;
@ -314,6 +323,11 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra)
htons(gsn->clockQuality.offsetScaledLogVariance);
gsn->utc_offset = htons(gsn->utc_offset);
break;
case PORT_DATA_SET_NP:
pdsnp = (struct port_ds_np *) m->data;
pdsnp->neighborPropDelayThresh = htonl(pdsnp->neighborPropDelayThresh);
pdsnp->asCapable = htonl(pdsnp->asCapable);
break;
}
}

6
tlv.h
View File

@ -98,6 +98,7 @@ enum management_action {
#define TRANSPARENT_CLOCK_PORT_DATA_SET 0x4001
#define DELAY_MECHANISM 0x6000
#define LOG_MIN_PDELAY_REQ_INTERVAL 0x6001
#define PORT_DATA_SET_NP 0xC002
/* Management error ID values */
#define RESPONSE_TOO_BIG 0x0001
@ -190,6 +191,11 @@ struct grandmaster_settings_np {
Enumeration8 time_source;
} PACKED;
struct port_ds_np {
UInteger32 neighborPropDelayThresh; /*nanoseconds*/
Integer32 asCapable;
} PACKED;
enum clock_type {
CLOCK_TYPE_ORDINARY = 0x8000,
CLOCK_TYPE_BOUNDARY = 0x4000,