Re: [Linuxptp-devel] [PATCH RFC v3 06/10] Add the ALTERNATE_TIME_OFFSET_PROPERTIES management messa
PTP IEEE 1588 stack for Linux
                
                Brought to you by:
                
                    rcochran
                    
                
            
            
        
        
        
    | 
      
      
      From: Geva, E. <ere...@si...> - 2021-11-10 10:30:19
      
     | 
| Hi,
According to IEEE 1588 timeOfNextJump is 48 bits.
The alternate_time_offset_properties structure reserve the full 48 bits.
The pre and the post function do full handle.
But the rest handle only the low 32 bits.
I can understand the PMC set use 32 bits only, but the rest?
Erez
-----Original Message-----
From: Richard Cochran <ric...@gm...> 
Sent: Tuesday, 9 November 2021 21:12
To: lin...@li...
Subject: [Linuxptp-devel] [PATCH RFC v3 06/10] Add the ALTERNATE_TIME_OFFSET_PROPERTIES management message.
Signed-off-by: Richard Cochran <ric...@gm...>
---
 clock.c      | 66 ++++++++++++++++++++++++++++++++++++++++++++++++----
 pmc.c        | 13 +++++++++++
 pmc_common.c | 24 ++++++++++++++++++-
 tlv.c        | 21 +++++++++++++++++
 util.h       |  7 ++++++
 5 files changed, 126 insertions(+), 5 deletions(-)
diff --git a/clock.c b/clock.c
index b5b729a..1e3ff3e 100644
--- a/clock.c
+++ b/clock.c
@@ -156,6 +156,32 @@ static int clock_resize_pollfd(struct clock *c, int new_nports);  static void clock_remove_port(struct clock *c, struct port *p);  static void clock_stats_display(struct clock_stats *s);
 
+uint8_t clock_alttime_offset_get_key(struct ptp_message *req) {
+	struct management_tlv_datum *mtd;
+	struct management_tlv *mgt =
+		(struct management_tlv *) req->management.suffix;
+
+	/*
+	 * The data field of incoming management request messages is
+	 * normally ignored.  Indeed it can even be empty.  However
+	 * the ALTERNATE_TIME_OFFSET requests are exceptional because
+	 * the key field selects one of the configured time zones.
+	 *
+	 * Provide the first time zone for an empty GET, and validate
+	 * the length of the request when non-empty.
+	 */
+	if (mgt->length == sizeof(mgt->id)) {
+		return 0;
+	}
+	if (mgt->length < sizeof(mgt->id) + sizeof(*mtd)) {
+		return MAX_TIME_ZONES;
+	}
+	mtd = (struct management_tlv_datum *) mgt->data;
+
+	return mtd->val;
+}
+
 static void remove_subscriber(struct clock_subscriber *s)  {
 	LIST_REMOVE(s, list);
@@ -353,6 +379,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
 					  struct ptp_message *req,
 					  struct ptp_message *rsp, int id)  {
+	struct alternate_time_offset_properties *atop;
 	struct grandmaster_settings_np *gsn;
 	struct management_tlv_datum *mtd;
 	struct subscribe_events_np *sen;
@@ -362,6 +389,7 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
 	struct PTPText *text;
 	uint16_t duration;
 	int datalen = 0;
+	uint8_t key;
 
 	extra = tlv_extra_alloc();
 	if (!extra) {
@@ -432,6 +460,22 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
 		mtd->val = c->tds.flags & PTP_TIMESCALE;
 		datalen = sizeof(*mtd);
 		break;
+	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
+		key = clock_alttime_offset_get_key(req);
+		if (key >= MAX_TIME_ZONES) {
+			break;
+		}
+		atop = (struct alternate_time_offset_properties *) tlv->data;
+		atop->keyField = key;
+		/* Message alignment broken by design. */
+		memcpy(&atop->currentOffset, &c->tz[key].current_offset,
+		       sizeof(atop->currentOffset));
+		memcpy(&atop->jumpSeconds, &c->tz[key].jump_seconds,
+		       sizeof(atop->jumpSeconds));
+		memcpy(&atop->timeOfNextJump.seconds_lsb, &c->tz[key].next_jump,
+		       sizeof(atop->timeOfNextJump.seconds_lsb));
+		datalen = sizeof(*atop);
+		break;
 	case MID_TIME_STATUS_NP:
 		tsn = (struct time_status_np *) tlv->data;
 		tsn->master_offset = tmv_to_nanoseconds(c->master_offset);
@@ -510,11 +554,12 @@ static int clock_management_get_response(struct clock *c, struct port *p,  static int clock_management_set(struct clock *c, struct port *p,
 				int id, struct ptp_message *req, int *changed)  {
-	int respond = 0;
-	struct management_tlv *tlv;
-	struct management_tlv_datum *mtd;
+	struct alternate_time_offset_properties *atop;
 	struct grandmaster_settings_np *gsn;
+	struct management_tlv_datum *mtd;
 	struct subscribe_events_np *sen;
+	struct management_tlv *tlv;
+	int key, respond = 0;
 
 	tlv = (struct management_tlv *) req->management.suffix;
 
@@ -531,6 +576,20 @@ static int clock_management_set(struct clock *c, struct port *p,
 		*changed = 1;
 		respond = 1;
 		break;
+	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
+		atop = (struct alternate_time_offset_properties *) tlv->data;
+		key = atop->keyField;
+		if (key < MAX_TIME_ZONES) {
+			/* Message alignment broken by design. */
+			memcpy(&c->tz[key].current_offset, &atop->currentOffset,
+			       sizeof(c->tz[key].current_offset));
+			memcpy(&c->tz[key].jump_seconds, &atop->jumpSeconds,
+			       sizeof(c->tz[key].jump_seconds));
+			memcpy(&c->tz[key].next_jump, &atop->timeOfNextJump.seconds_lsb,
+			       sizeof(c->tz[key].next_jump));
+			respond = 1;
+		}
+		break;
 	case MID_GRANDMASTER_SETTINGS_NP:
 		gsn = (struct grandmaster_settings_np *) tlv->data;
 		c->dds.clockQuality = gsn->clockQuality; @@ -1529,7 +1588,6 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
 	case MID_ALTERNATE_TIME_OFFSET_ENABLE:
 	case MID_ALTERNATE_TIME_OFFSET_NAME:
 	case MID_ALTERNATE_TIME_OFFSET_MAX_KEY:
-	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
 	case MID_TRANSPARENT_CLOCK_DEFAULT_DATA_SET:
 	case MID_PRIMARY_DOMAIN:
 	case MID_TIME_STATUS_NP:
diff --git a/pmc.c b/pmc.c
index 28d96a8..e4dd566 100644
--- a/pmc.c
+++ b/pmc.c
@@ -139,6 +139,7 @@ static void pmc_show_signaling(struct ptp_message *msg, FILE *fp)
 
 static void pmc_show(struct ptp_message *msg, FILE *fp)  {
+	struct alternate_time_offset_properties *atop;
 	struct ieee_c37_238_settings_np *pwr;
 	struct grandmaster_settings_np *gsn;
 	struct mgmt_clock_description *cd;
@@ -336,6 +337,18 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
 		fprintf(fp, "TIMESCALE_PROPERTIES "
 			IFMT "ptpTimescale %d", mtd->val & PTP_TIMESCALE ? 1 : 0);
 		break;
+	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
+		atop = (struct alternate_time_offset_properties *) mgt->data;
+		fprintf(fp, "ALTERNATE_TIME_OFFSET_PROPERTIES "
+			IFMT "keyField       %hhu"
+			IFMT "currentOffset  %d"
+			IFMT "jumpSeconds    %d"
+			IFMT "timeOfNextJump %u",
+			atop->keyField,
+			align32(&atop->currentOffset),
+			align32(&atop->jumpSeconds),
+			align32(&atop->timeOfNextJump.seconds_lsb));
+		break;
 	case MID_MASTER_ONLY:
 		mtd = (struct management_tlv_datum *) mgt->data;
 		fprintf(fp, "MASTER_ONLY "
diff --git a/pmc_common.c b/pmc_common.c index e40c3d8..6ba8616 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -104,7 +104,7 @@ struct management_id idtab[] = {
 	{ "ALTERNATE_TIME_OFFSET_ENABLE", MID_ALTERNATE_TIME_OFFSET_ENABLE, not_supported },
 	{ "ALTERNATE_TIME_OFFSET_NAME", MID_ALTERNATE_TIME_OFFSET_NAME, not_supported },
 	{ "ALTERNATE_TIME_OFFSET_MAX_KEY", MID_ALTERNATE_TIME_OFFSET_MAX_KEY, not_supported },
-	{ "ALTERNATE_TIME_OFFSET_PROPERTIES", MID_ALTERNATE_TIME_OFFSET_PROPERTIES, not_supported },
+	{ "ALTERNATE_TIME_OFFSET_PROPERTIES", 
+MID_ALTERNATE_TIME_OFFSET_PROPERTIES, do_set_action },
 	{ "MASTER_ONLY", MID_MASTER_ONLY, do_get_action },
 	{ "TRANSPARENT_CLOCK_DEFAULT_DATA_SET", MID_TRANSPARENT_CLOCK_DEFAULT_DATA_SET, not_supported },
 	{ "PRIMARY_DOMAIN", MID_PRIMARY_DOMAIN, not_supported }, @@ -148,6 +148,7 @@ static void do_set_action(struct pmc *pmc, int action, int index, char *str)  {
 	int cnt, code = idtab[index].code, freq_traceable, leap_59, leap_61,
 		ptp_timescale, time_traceable, utc_off_valid;
+	struct alternate_time_offset_properties atop;
 	struct ieee_c37_238_settings_np pwr;
 	struct grandmaster_settings_np gsn;
 	struct management_tlv_datum mtd;
@@ -181,6 +182,24 @@ static void do_set_action(struct pmc *pmc, int action, int index, char *str)
 		}
 		pmc_send_set_action(pmc, code, &mtd, sizeof(mtd));
 		break;
+	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
+		memset(&atop, 0, sizeof(atop));
+		cnt = sscanf(str, " %*s %*s "
+			     "keyField       %hhu "
+			     "currentOffset  %d "
+			     "jumpSeconds    %d "
+			     "timeOfNextJump %u ",
+			     &atop.keyField,
+			     &atop.currentOffset,
+			     &atop.jumpSeconds,
+			     &atop.timeOfNextJump.seconds_lsb);
+		if (cnt != 4) {
+			fprintf(stderr, "%s SET needs 4 values\n",
+				idtab[index].name);
+			break;
+		}
+		pmc_send_set_action(pmc, code, &atop, sizeof(atop));
+		break;
 	case MID_GRANDMASTER_SETTINGS_NP:
 		cnt = sscanf(str, " %*s %*s "
 			     "clockClass              %hhu "
@@ -551,6 +570,9 @@ static int pmc_tlv_datalen(struct pmc *pmc, int id)
 	case MID_TIME_STATUS_NP:
 		len += sizeof(struct time_status_np);
 		break;
+	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
+		len += sizeof(struct alternate_time_offset_properties);
+		break;
 	case MID_GRANDMASTER_SETTINGS_NP:
 		len += sizeof(struct grandmaster_settings_np);
 		break;
diff --git a/tlv.c b/tlv.c
index 03faa74..fdff99a 100644
--- a/tlv.c
+++ b/tlv.c
@@ -167,6 +167,7 @@ static void alttime_offset_pre_send(struct tlv_extra *extra)  static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
 			 struct tlv_extra *extra)
 {
+	struct alternate_time_offset_properties *atop;
 	struct ieee_c37_238_settings_np *pwr;
 	struct grandmaster_settings_np *gsn;
 	struct mgmt_clock_description *cd;
@@ -333,6 +334,17 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
 		p->portIdentity.portNumber = ntohs(p->portIdentity.portNumber);
 		p->peerMeanPathDelay = net2host64(p->peerMeanPathDelay);
 		break;
+	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
+		atop = (struct alternate_time_offset_properties *) m->data;
+		if (data_len != sizeof(*atop)) {
+			goto bad_length;
+		}
+		/* Message alignment broken by design. */
+		net2host32_unaligned(&atop->currentOffset);
+		net2host32_unaligned(&atop->jumpSeconds);
+		flip16(&atop->timeOfNextJump.seconds_msb);
+		net2host32_unaligned(&atop->timeOfNextJump.seconds_lsb);
+		break;
 	case MID_TIME_STATUS_NP:
 		if (data_len != sizeof(struct time_status_np))
 			goto bad_length;
@@ -419,6 +431,7 @@ bad_length:
 
 static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra)  {
+	struct alternate_time_offset_properties *atop;
 	struct ieee_c37_238_settings_np *pwr;
 	struct grandmaster_settings_np *gsn;
 	struct mgmt_clock_description *cd;
@@ -476,6 +489,14 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra)
 		p->portIdentity.portNumber = htons(p->portIdentity.portNumber);
 		p->peerMeanPathDelay = host2net64(p->peerMeanPathDelay);
 		break;
+	case MID_ALTERNATE_TIME_OFFSET_PROPERTIES:
+		atop = (struct alternate_time_offset_properties *) m->data;
+		/* Message alignment broken by design. */
+		host2net32_unaligned(&atop->currentOffset);
+		host2net32_unaligned(&atop->jumpSeconds);
+		flip16(&atop->timeOfNextJump.seconds_msb);
+		host2net32_unaligned(&atop->timeOfNextJump.seconds_lsb);
+		break;
 	case MID_TIME_STATUS_NP:
 		tsn = (struct time_status_np *) m->data;
 		tsn->master_offset = host2net64(tsn->master_offset); diff --git a/util.h b/util.h index 739c8fd..0386409 100644
--- a/util.h
+++ b/util.h
@@ -64,6 +64,13 @@ static inline uint16_t align16(void *p)
 	return v;
 }
 
+static inline uint32_t align32(void *p) {
+	uint32_t v;
+	memcpy(&v, p, sizeof(v));
+	return v;
+}
+
 char *bin2str_impl(Octet *data, int len, char *buf, int buf_len);
 
 /**
--
2.20.1
_______________________________________________
Linuxptp-devel mailing list
Lin...@li...
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.sourceforge.net%2Flists%2Flistinfo%2Flinuxptp-devel&data=04%7C01%7Cerez.geva.ext%40siemens.com%7C7c711b996e574f6328dc08d9a3bd6d6d%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637720856242186481%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=O69Ic1RW3cdZ8%2FnbeI1HkkQS9FXcrlcN3%2BtQ141Ccl0%3D&reserved=0
 |