From 29063a822767617d87d3e7f9b3ac16fb30f160cf Mon Sep 17 00:00:00 2001 From: Delio Brignoli Date: Tue, 4 Feb 2014 10:56:06 +0100 Subject: [PATCH] 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 --- pmc.8 | 2 ++ pmc.c | 24 ++++++++++++++++++++++++ pmc_common.c | 3 +++ port.c | 18 ++++++++++++++++++ tlv.c | 14 ++++++++++++++ tlv.h | 6 ++++++ 6 files changed, 67 insertions(+) diff --git a/pmc.8 b/pmc.8 index 988581f..0d36354 100644 --- a/pmc.8 +++ b/pmc.8 @@ -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 diff --git a/pmc.c b/pmc.c index c9851cd..7ea0368 100644 --- a/pmc.c +++ b/pmc.c @@ -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; } } diff --git a/pmc_common.c b/pmc_common.c index ed3c5da..9b0720f 100644 --- a/pmc_common.c +++ b/pmc_common.c @@ -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: diff --git a/port.c b/port.c index 7229429..81556ae 100644 --- a/port.c +++ b/port.c @@ -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)); diff --git a/tlv.c b/tlv.c index 3767861..f32514f 100644 --- a/tlv.c +++ b/tlv.c @@ -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; } } diff --git a/tlv.h b/tlv.h index 1cd8a39..60c937d 100644 --- a/tlv.h +++ b/tlv.h @@ -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,