[Linuxptp-devel] [PATCH 07/10] tlv: Encode and decode SLAVE_DELAY_TIMING_DATA_NP TLVs.

2020-05-24 Thread Richard Cochran
Signed-off-by: Richard Cochran 
---
 tlv.c | 57 +
 tlv.h | 20 
 2 files changed, 77 insertions(+)

diff --git a/tlv.c b/tlv.c
index e12e5ae..738e404 100644
--- a/tlv.c
+++ b/tlv.c
@@ -594,6 +594,55 @@ static void org_pre_send(struct organization_tlv *org)
}
 }
 
+static int slave_delay_timing_data_post_revc(struct tlv_extra *extra)
+{
+   struct slave_delay_timing_data_tlv *slave_delay =
+   (struct slave_delay_timing_data_tlv *) extra->tlv;
+   size_t base_size = sizeof(slave_delay->sourcePortIdentity), n_items;
+   struct slave_delay_timing_record *record;
+
+   if (tlv_array_invalid(extra->tlv, base_size, sizeof(*record))) {
+   return -EBADMSG;
+   }
+   n_items = tlv_array_count(extra->tlv, base_size, sizeof(*record));
+   record = slave_delay->record;
+
+   NTOHS(slave_delay->sourcePortIdentity.portNumber);
+
+   while (n_items) {
+   NTOHS(record->sequenceId);
+   timestamp_net2host(>delayOriginTimestamp);
+   net2host64_unaligned(>totalCorrectionField);
+   timestamp_net2host(>delayResponseTimestamp);
+   n_items--;
+   record++;
+   }
+
+   return 0;
+}
+
+static void slave_delay_timing_data_pre_send(struct tlv_extra *extra)
+{
+   struct slave_delay_timing_data_tlv *slave_delay =
+   (struct slave_delay_timing_data_tlv *) extra->tlv;
+   size_t base_size = sizeof(slave_delay->sourcePortIdentity), n_items;
+   struct slave_delay_timing_record *record;
+
+   n_items = tlv_array_count(extra->tlv, base_size, sizeof(*record));
+   record = slave_delay->record;
+
+   HTONS(slave_delay->sourcePortIdentity.portNumber);
+
+   while (n_items) {
+   HTONS(record->sequenceId);
+   timestamp_host2net(>delayOriginTimestamp);
+   host2net64_unaligned(>totalCorrectionField);
+   timestamp_host2net(>delayResponseTimestamp);
+   n_items--;
+   record++;
+   }
+}
+
 static int slave_rx_sync_timing_data_post_revc(struct tlv_extra *extra)
 {
struct slave_rx_sync_timing_data_tlv *slave_data =
@@ -819,6 +868,10 @@ int tlv_post_recv(struct tlv_extra *extra)
break;
case TLV_SLAVE_RX_SYNC_COMPUTED_DATA:
case TLV_SLAVE_TX_EVENT_TIMESTAMPS:
+   break;
+   case TLV_SLAVE_DELAY_TIMING_DATA_NP:
+   result = slave_delay_timing_data_post_revc(extra);
+   break;
case TLV_CUMULATIVE_RATE_RATIO:
case TLV_PAD:
case TLV_AUTHENTICATION:
@@ -879,6 +932,10 @@ void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)
break;
case TLV_SLAVE_RX_SYNC_COMPUTED_DATA:
case TLV_SLAVE_TX_EVENT_TIMESTAMPS:
+   break;
+   case TLV_SLAVE_DELAY_TIMING_DATA_NP:
+   slave_delay_timing_data_pre_send(extra);
+   break;
case TLV_CUMULATIVE_RATE_RATIO:
case TLV_PAD:
case TLV_AUTHENTICATION:
diff --git a/tlv.h b/tlv.h
index 8212325..a205119 100644
--- a/tlv.h
+++ b/tlv.h
@@ -50,6 +50,7 @@
 #define TLV_SLAVE_RX_SYNC_TIMING_DATA  0x8004
 #define TLV_SLAVE_RX_SYNC_COMPUTED_DATA0x8005
 #define TLV_SLAVE_TX_EVENT_TIMESTAMPS  0x8006
+#define TLV_SLAVE_DELAY_TIMING_DATA_NP 0x7F00
 #define TLV_CUMULATIVE_RATE_RATIO  0x8007
 #define TLV_PAD0x8008
 #define TLV_AUTHENTICATION 0x8009
@@ -237,6 +238,25 @@ struct request_unicast_xmit_tlv {
UInteger32  durationField;
 } PACKED;
 
+struct slave_delay_timing_record {
+   UInteger16  sequenceId;
+   struct TimestampdelayOriginTimestamp;
+   TimeIntervaltotalCorrectionField;
+   struct TimestampdelayResponseTimestamp;
+} PACKED;
+
+struct slave_delay_timing_data_tlv {
+   Enumeration16type;
+   UInteger16   length;
+   struct PortIdentity  sourcePortIdentity;
+   struct slave_delay_timing_record record[0];
+} PACKED;
+
+#define SLAVE_DELAY_TIMING_MAX \
+   ((sizeof(struct message_data) - sizeof(struct signaling_msg) -  \
+ sizeof(struct slave_delay_timing_data_tlv)) / \
+sizeof(struct slave_delay_timing_record))
+
 struct slave_rx_sync_timing_record {
UInteger16  sequenceId;
struct TimestampsyncOriginTimestamp;
-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 06/10] pmc: Show slave receive timing data TLVs attached to signaling messages.

2020-05-24 Thread Richard Cochran
Signed-off-by: Richard Cochran 
---
 pmc.c | 57 +
 1 file changed, 57 insertions(+)

diff --git a/pmc.c b/pmc.c
index 490c140..8e30b1c 100644
--- a/pmc.c
+++ b/pmc.c
@@ -55,6 +55,59 @@ static char *bin2str(Octet *data, int len)
return bin2str_impl(data, len, buf, sizeof(buf));
 }
 
+#define SHOW_TIMESTAMP(ts) \
+   ((uint64_t)ts.seconds_lsb) | (((uint64_t)ts.seconds_msb) << 32), 
ts.nanoseconds
+
+static void pmc_show_rx_sync_timing(struct slave_rx_sync_timing_record *record,
+   FILE *fp)
+{
+   fprintf(fp,
+   IFMT "sequenceId %hu"
+   IFMT "syncOriginTimestamp%" PRId64 ".%09u"
+   IFMT "totalCorrectionField   %" PRId64
+   IFMT "scaledCumulativeRateOffset %u"
+   IFMT "syncEventIngressTimestamp  %" PRId64 ".%09u",
+   record->sequenceId,
+   SHOW_TIMESTAMP(record->syncOriginTimestamp),
+   record->totalCorrectionField << 16,
+   record->scaledCumulativeRateOffset,
+   SHOW_TIMESTAMP(record->syncEventIngressTimestamp));
+}
+
+static void pmc_show_signaling(struct ptp_message *msg, FILE *fp)
+{
+   struct slave_rx_sync_timing_record *sync_record;
+   struct slave_rx_sync_timing_data_tlv *srstd;
+   struct tlv_extra *extra;
+   int i, cnt;
+
+   fprintf(fp, "\t%s seq %hu %s ",
+   pid2str(>header.sourcePortIdentity),
+   msg->header.sequenceId, "SIGNALING");
+
+   TAILQ_FOREACH(extra, >tlv_list, list) {
+   switch (extra->tlv->type) {
+   case TLV_SLAVE_RX_SYNC_TIMING_DATA:
+   srstd = (struct slave_rx_sync_timing_data_tlv *) 
extra->tlv;
+   cnt = (srstd->length - 
sizeof(srstd->sourcePortIdentity)) /
+   sizeof(*sync_record);
+   fprintf(fp, "SLAVE_RX_SYNC_TIMING_DATA N %d "
+   IFMT "sourcePortIdentity %s",
+   cnt, pid2str(>sourcePortIdentity));
+   sync_record = srstd->record;
+   for (i = 0; i < cnt; i++) {
+   pmc_show_rx_sync_timing(sync_record, fp);
+   sync_record++;
+   }
+   break;
+   default:
+   break;
+   }
+   }
+   fprintf(fp, "\n");
+   fflush(fp);
+}
+
 static void pmc_show(struct ptp_message *msg, FILE *fp)
 {
struct grandmaster_settings_np *gsn;
@@ -75,6 +128,10 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct TLV *tlv;
int action;
 
+   if (msg_type(msg) == SIGNALING) {
+   pmc_show_signaling(msg, fp);
+   return;
+   }
if (msg_type(msg) != MANAGEMENT) {
return;
}
-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 05/10] port: Support slave event monitoring of Sync timing data.

2020-05-24 Thread Richard Cochran
The monitoring module accepts Sync timing events.  This patch hooks up the
port receive path to call into the monitor.

Signed-off-by: Richard Cochran 
---
 port.c | 22 +++---
 port_private.h |  3 +++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/port.c b/port.c
index 48fff1c..a74937c 100644
--- a/port.c
+++ b/port.c
@@ -1156,6 +1156,7 @@ static void message_interval_request(struct port *p,
 }
 
 static void port_synchronize(struct port *p,
+uint16_t seqid,
 tmv_t ingress_ts,
 struct timestamp origin_ts,
 Integer64 correction1, Integer64 correction2,
@@ -1172,6 +1173,17 @@ static void port_synchronize(struct port *p,
c2 = correction_to_tmv(correction2);
t1c = tmv_add(t1, tmv_add(c1, c2));
 
+   switch (p->state) {
+   case PS_UNCALIBRATED:
+   case PS_SLAVE:
+   monitor_sync(p->slave_event_monitor,
+clock_parent_identity(p->clock), seqid,
+t1, tmv_add(c1, c2), t2);
+   break;
+   default:
+   break;
+   }
+
last_state = clock_servo_state(p->clock);
state = clock_synchronize(p->clock, t2, t1c);
switch (state) {
@@ -1251,7 +1263,8 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
break;
case FUP_MATCH:
syn = p->last_syncfup;
-   port_synchronize(p, syn->hwts.ts, m->ts.pdu,
+   port_synchronize(p, syn->header.sequenceId,
+syn->hwts.ts, m->ts.pdu,
 syn->header.correction,
 m->header.correction,
 m->header.logMessageInterval);
@@ -1271,7 +1284,8 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
break;
case SYNC_MATCH:
fup = p->last_syncfup;
-   port_synchronize(p, m->hwts.ts, fup->ts.pdu,
+   port_synchronize(p, fup->header.sequenceId,
+m->hwts.ts, fup->ts.pdu,
 m->header.correction,
 fup->header.correction,
 m->header.logMessageInterval);
@@ -2297,7 +2311,8 @@ void process_sync(struct port *p, struct ptp_message *m)
m->header.correction += p->asymmetry;
 
if (one_step(m)) {
-   port_synchronize(p, m->hwts.ts, m->ts.pdu,
+   port_synchronize(p, m->header.sequenceId,
+m->hwts.ts, m->ts.pdu,
 m->header.correction, 0,
 m->header.logMessageInterval);
flush_last_sync(p);
@@ -3061,6 +3076,7 @@ struct port *port_open(const char *phc_device,
p->state = PS_INITIALIZING;
p->delayMechanism = config_get_int(cfg, p->name, "delay_mechanism");
p->versionNumber = PTP_VERSION;
+   p->slave_event_monitor = clock_slave_monitor(clock);
 
if (number && unicast_client_initialize(p)) {
goto err_transport;
diff --git a/port_private.h b/port_private.h
index 82d1801..fcabaa6 100644
--- a/port_private.h
+++ b/port_private.h
@@ -24,6 +24,7 @@
 #include "as_capable.h"
 #include "clock.h"
 #include "fsm.h"
+#include "monitor.h"
 #include "msg.h"
 #include "tmv.h"
 
@@ -150,6 +151,8 @@ struct port {
/* unicast service mode */
struct unicast_service *unicast_service;
int inhibit_multicast_service;
+   /* slave event monitoring */
+   struct monitor *slave_event_monitor;
 };
 
 #define portnum(p) (p->portIdentity.portNumber)
-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 10/10] pmc: Show slave delay timing data TLVs attached to signaling messages.

2020-05-24 Thread Richard Cochran
Signed-off-by: Richard Cochran 
---
 pmc.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/pmc.c b/pmc.c
index 8e30b1c..65d1d61 100644
--- a/pmc.c
+++ b/pmc.c
@@ -58,6 +58,20 @@ static char *bin2str(Octet *data, int len)
 #define SHOW_TIMESTAMP(ts) \
((uint64_t)ts.seconds_lsb) | (((uint64_t)ts.seconds_msb) << 32), 
ts.nanoseconds
 
+static void pmc_show_delay_timing(struct slave_delay_timing_record *record,
+ FILE *fp)
+{
+   fprintf(fp,
+   IFMT "sequenceId %hu"
+   IFMT "delayOriginTimestamp   %" PRId64 ".%09u"
+   IFMT "totalCorrectionField   %" PRId64
+   IFMT "delayResponseTimestamp %" PRId64 ".%09u",
+   record->sequenceId,
+   SHOW_TIMESTAMP(record->delayOriginTimestamp),
+   record->totalCorrectionField << 16,
+   SHOW_TIMESTAMP(record->delayResponseTimestamp));
+}
+
 static void pmc_show_rx_sync_timing(struct slave_rx_sync_timing_record *record,
FILE *fp)
 {
@@ -77,7 +91,9 @@ static void pmc_show_rx_sync_timing(struct 
slave_rx_sync_timing_record *record,
 static void pmc_show_signaling(struct ptp_message *msg, FILE *fp)
 {
struct slave_rx_sync_timing_record *sync_record;
+   struct slave_delay_timing_record *delay_record;
struct slave_rx_sync_timing_data_tlv *srstd;
+   struct slave_delay_timing_data_tlv *sdtdt;
struct tlv_extra *extra;
int i, cnt;
 
@@ -100,6 +116,19 @@ static void pmc_show_signaling(struct ptp_message *msg, 
FILE *fp)
sync_record++;
}
break;
+   case TLV_SLAVE_DELAY_TIMING_DATA_NP:
+   sdtdt = (struct slave_delay_timing_data_tlv *) 
extra->tlv;
+   cnt = (sdtdt->length - 
sizeof(sdtdt->sourcePortIdentity)) /
+   sizeof(*delay_record);
+   fprintf(fp, "SLAVE_DELAY_TIMING_DATA_NP N %d "
+   IFMT "sourcePortIdentity %s",
+   cnt, pid2str(>sourcePortIdentity));
+   delay_record = sdtdt->record;
+   for (i = 0; i < cnt; i++) {
+   pmc_show_delay_timing(delay_record, fp);
+   delay_record++;
+   }
+   break;
default:
break;
}
-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 01/10] tlv: Update macro definitions.

2020-05-24 Thread Richard Cochran
The 2019 version of 1588 known as v2.1 introduces new TLV type and
management IDs.  This patch adds the new definitions.

Signed-off-by: Richard Cochran 
---
 tlv.c | 28 ++--
 tlv.h | 19 ++-
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/tlv.c b/tlv.c
index 6ab54a5..0cf6d5c 100644
--- a/tlv.c
+++ b/tlv.c
@@ -728,7 +728,7 @@ int tlv_post_recv(struct tlv_extra *extra)
}
break;
case TLV_ALTERNATE_TIME_OFFSET_INDICATOR:
-   case TLV_AUTHENTICATION:
+   case TLV_AUTHENTICATION_2008:
case TLV_AUTHENTICATION_CHALLENGE:
case TLV_SECURITY_ASSOCIATION_UPDATE:
case TLV_CUM_FREQ_SCALE_FACTOR_OFFSET:
@@ -737,6 +737,18 @@ int tlv_post_recv(struct tlv_extra *extra)
case TLV_PTPMON_RESP:
result = nsm_resp_post_recv(extra);
break;
+   case TLV_ORGANIZATION_EXTENSION_PROPAGATE:
+   case TLV_ENHANCED_ACCURACY_METRICS:
+   case TLV_ORGANIZATION_EXTENSION_DO_NOT_PROPAGATE:
+   case TLV_L1_SYNC:
+   case TLV_PORT_COMMUNICATION_AVAILABILITY:
+   case TLV_PROTOCOL_ADDRESS:
+   case TLV_SLAVE_RX_SYNC_TIMING_DATA:
+   case TLV_SLAVE_RX_SYNC_COMPUTED_DATA:
+   case TLV_SLAVE_TX_EVENT_TIMESTAMPS:
+   case TLV_CUMULATIVE_RATE_RATIO:
+   case TLV_PAD:
+   case TLV_AUTHENTICATION:
default:
break;
}
@@ -773,7 +785,7 @@ void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)
break;
case TLV_PATH_TRACE:
case TLV_ALTERNATE_TIME_OFFSET_INDICATOR:
-   case TLV_AUTHENTICATION:
+   case TLV_AUTHENTICATION_2008:
case TLV_AUTHENTICATION_CHALLENGE:
case TLV_SECURITY_ASSOCIATION_UPDATE:
case TLV_CUM_FREQ_SCALE_FACTOR_OFFSET:
@@ -782,6 +794,18 @@ void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)
case TLV_PTPMON_RESP:
nsm_resp_pre_send(extra);
break;
+   case TLV_ORGANIZATION_EXTENSION_PROPAGATE:
+   case TLV_ENHANCED_ACCURACY_METRICS:
+   case TLV_ORGANIZATION_EXTENSION_DO_NOT_PROPAGATE:
+   case TLV_L1_SYNC:
+   case TLV_PORT_COMMUNICATION_AVAILABILITY:
+   case TLV_PROTOCOL_ADDRESS:
+   case TLV_SLAVE_RX_SYNC_TIMING_DATA:
+   case TLV_SLAVE_RX_SYNC_COMPUTED_DATA:
+   case TLV_SLAVE_TX_EVENT_TIMESTAMPS:
+   case TLV_CUMULATIVE_RATE_RATIO:
+   case TLV_PAD:
+   case TLV_AUTHENTICATION:
default:
break;
}
diff --git a/tlv.h b/tlv.h
index 75aa1de..f46a3b8 100644
--- a/tlv.h
+++ b/tlv.h
@@ -35,12 +35,24 @@
 #define TLV_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION0x0007
 #define TLV_PATH_TRACE 0x0008
 #define TLV_ALTERNATE_TIME_OFFSET_INDICATOR0x0009
-#define TLV_AUTHENTICATION 0x2000
+#define TLV_AUTHENTICATION_20080x2000
 #define TLV_AUTHENTICATION_CHALLENGE   0x2001
 #define TLV_SECURITY_ASSOCIATION_UPDATE0x2002
 #define TLV_CUM_FREQ_SCALE_FACTOR_OFFSET   0x2003
 #define TLV_PTPMON_REQ 0x21FE
 #define TLV_PTPMON_RESP0x21FF
+#define TLV_ORGANIZATION_EXTENSION_PROPAGATE   0x4000
+#define TLV_ENHANCED_ACCURACY_METRICS  0x4001
+#define TLV_ORGANIZATION_EXTENSION_DO_NOT_PROPAGATE0x8000
+#define TLV_L1_SYNC0x8001
+#define TLV_PORT_COMMUNICATION_AVAILABILITY0x8002
+#define TLV_PROTOCOL_ADDRESS   0x8003
+#define TLV_SLAVE_RX_SYNC_TIMING_DATA  0x8004
+#define TLV_SLAVE_RX_SYNC_COMPUTED_DATA0x8005
+#define TLV_SLAVE_TX_EVENT_TIMESTAMPS  0x8006
+#define TLV_CUMULATIVE_RATE_RATIO  0x8007
+#define TLV_PAD0x8008
+#define TLV_AUTHENTICATION 0x8009
 
 enum management_action {
GET,
@@ -79,6 +91,8 @@ enum management_action {
 #define TLV_ALTERNATE_TIME_OFFSET_NAME 0x201F
 #define TLV_ALTERNATE_TIME_OFFSET_MAX_KEY  0x2020
 #define TLV_ALTERNATE_TIME_OFFSET_PROPERTIES   0x2021
+#define TLV_EXTERNAL_PORT_CONFIGURATION_ENABLED0x3000
+#define TLV_HOLDOVER_UPGRADE_ENABLE0x3002
 #define TLV_TRANSPARENT_CLOCK_DEFAULT_DATA_SET 0x4000
 #define TLV_PRIMARY_DOMAIN 0x4002
 #define TLV_TIME_STATUS_NP 0xC000
@@ -101,6 +115,9 @@ enum management_action {
 #define TLV_UNICAST_MASTER_MAX_TABLE_SIZE  0x2019
 #define TLV_ACCEPTABLE_MASTER_TABLE_ENABLED0x201B
 #define TLV_ALTERNATE_MASTER   0x201D
+#define TLV_MASTER_ONLY0x3001
+#define 

[Linuxptp-devel] [PATCH 00/10] Slave event monitoring

2020-05-24 Thread Richard Cochran
The IEEE 1588 v2.1 standard introduces a new optional feature known as
slave event monitoring.  This feature defines three new TLVs.

1. SLAVE_RX_SYNC_TIMING_DATA

   This TLV provides the time stamps T1 and T2 from the message
   exchange between master and slave.

2. SLAVE_TX_EVENT_TIMESTAMPS

   This provides the T3 time stamp only.

3. SLAVE_RX_SYNC_COMPUTED_DATA

   This TLV provides the estimated offset and path delay.

The standard leaves the mechanism for enabling and configuring this
feature as implementation-defined.  This series implements slave
monitoring by offering a configuration option that specifies a UDS
address, allowing a local client such as the 'pmc' program to monitor
the time stamps.

While this series implements the first TLV verbatim, the second TLV
makes little sense as specified in the standard, because it omits the
T4 time stamp.  For this reason a custom TLV is used that provides
both T3 and T4.  The third TLV is not implemented here because it is
redundant, merely providing data already available in other management
messages.

Patches 1-5 implement the SLAVE_RX_SYNC_TIMING_DATA TLV in ptp4l, and
patch 6 adds that TLV into pmc.

Patches 7-9 then add the custom SLAVE_DELAY_TIMING_DATA_NP TLV into
ptp4l, and patch 10 adds it to pmc.


Richard Cochran (10):
  tlv: Update macro definitions.
  tlv: Encode and decode SLAVE_RX_SYNC_TIMING_DATA TLVs.
  Introduce a module for slave event monitoring.
  clock: Create a slave event monitor.
  port: Support slave event monitoring of Sync timing data.
  pmc: Show slave receive timing data TLVs attached to signaling
messages.
  tlv: Encode and decode SLAVE_DELAY_TIMING_DATA_NP TLVs.
  monitor: Add support for slave delay timing data TLV.
  port: Support slave event monitoring of delay timing data.
  pmc: Show slave delay timing data TLVs attached to signaling messages.

 clock.c|  13 +++
 clock.h|   8 ++
 config.c   |   1 +
 makefile   |   6 +-
 monitor.c  | 231 +
 monitor.h  |  25 ++
 pmc.c  |  86 ++
 port.c |  25 +-
 port_private.h |   3 +
 ptp4l.8|   6 ++
 tlv.c  | 163 +-
 tlv.h  |  67 --
 12 files changed, 620 insertions(+), 14 deletions(-)
 create mode 100644 monitor.c
 create mode 100644 monitor.h

-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 04/10] clock: Create a slave event monitor.

2020-05-24 Thread Richard Cochran
Signed-off-by: Richard Cochran 
---
 clock.c | 13 +
 clock.h |  8 
 2 files changed, 21 insertions(+)

diff --git a/clock.c b/clock.c
index a559cd4..f43cc2a 100644
--- a/clock.c
+++ b/clock.c
@@ -131,6 +131,7 @@ struct clock {
struct clockcheck *sanity_check;
struct interface *udsif;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
+   struct monitor *slave_event_monitor;
 };
 
 struct clock the_clock;
@@ -271,6 +272,7 @@ void clock_destroy(struct clock *c)
LIST_FOREACH_SAFE(p, >ports, list, tmp) {
clock_remove_port(c, p);
}
+   monitor_destroy(c->slave_event_monitor);
port_close(c->uds_port);
free(c->pollfd);
if (c->clkid != CLOCK_REALTIME) {
@@ -1185,6 +1187,12 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
}
clock_fda_changed(c);
 
+   c->slave_event_monitor = monitor_create(config, c->uds_port);
+   if (!c->slave_event_monitor) {
+   pr_err("failed to create slave event monitor");
+   return NULL;
+   }
+
/* Create the ports. */
STAILQ_FOREACH(iface, >interfaces, list) {
if (clock_add_port(c, phc_device, phc_index, timestamping, 
iface)) {
@@ -1626,6 +1634,11 @@ void clock_peer_delay(struct clock *c, tmv_t ppd, tmv_t 
req, tmv_t rx,
stats_add_value(c->stats.delay, tmv_dbl(ppd));
 }
 
+struct monitor *clock_slave_monitor(struct clock *c)
+{
+   return c->slave_event_monitor;
+}
+
 int clock_slave_only(struct clock *c)
 {
return c->dds.flags & DDS_SLAVE_ONLY;
diff --git a/clock.h b/clock.h
index 1256856..e7daf97 100644
--- a/clock.h
+++ b/clock.h
@@ -23,6 +23,7 @@
 #include "dm.h"
 #include "ds.h"
 #include "config.h"
+#include "monitor.h"
 #include "notification.h"
 #include "servo.h"
 #include "tlv.h"
@@ -267,6 +268,13 @@ struct servo *clock_servo(struct clock *c);
  */
 enum servo_state clock_servo_state(struct clock *c);
 
+/**
+ * Obtain the slave monitor instance from a clock.
+ * @param c The clock instance.
+ * @return  The slave monitor associated with the clock.
+ */
+struct monitor *clock_slave_monitor(struct clock *c);
+
 /**
  * Obtain the slave-only flag from a clock's default data set.
  * @param c  The clock instance.
-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 08/10] monitor: Add support for slave delay timing data TLV.

2020-05-24 Thread Richard Cochran
The slave delay timing data TLV provides the delay time stamps along with
the associated correction field.  This patch introduces a method to allow
publication of these values to a remote monitor.

Signed-off-by: Richard Cochran 
---
 monitor.c | 60 +++
 monitor.h |  3 +++
 2 files changed, 63 insertions(+)

diff --git a/monitor.c b/monitor.c
index 5706e5d..ed451ac 100644
--- a/monitor.c
+++ b/monitor.c
@@ -21,6 +21,8 @@ struct monitor_message {
 struct monitor {
struct port *dst_port;
struct slave_rx_sync_timing_data_tlv *sync_tlv;
+   struct slave_delay_timing_data_tlv *delay_tlv;
+   struct monitor_message delay;
struct monitor_message sync;
 };
 
@@ -79,6 +81,23 @@ static struct tlv_extra *monitor_init_message(struct 
monitor_message *mm,
return extra;
 }
 
+static int monitor_init_delay(struct monitor *monitor, struct address address)
+{
+   const size_t tlv_size = sizeof(struct slave_delay_timing_data_tlv) +
+   sizeof(struct slave_delay_timing_record) * RECORDS_PER_MESSAGE;
+   struct tlv_extra *extra;
+
+   extra = monitor_init_message(>delay, monitor->dst_port,
+TLV_SLAVE_DELAY_TIMING_DATA_NP, tlv_size,
+address);
+   if (!extra) {
+   return -1;
+   }
+   monitor->delay_tlv = (struct slave_delay_timing_data_tlv *) extra->tlv;
+
+   return 0;
+}
+
 static int monitor_init_sync(struct monitor *monitor, struct address address)
 {
const size_t tlv_size = sizeof(struct slave_rx_sync_timing_data_tlv) +
@@ -120,7 +139,12 @@ struct monitor *monitor_create(struct config *config, 
struct port *dst)
 
monitor->dst_port = dst;
 
+   if (monitor_init_delay(monitor, address)) {
+   free(monitor);
+   return NULL;
+   }
if (monitor_init_sync(monitor, address)) {
+   msg_put(monitor->delay.msg);
free(monitor);
return NULL;
}
@@ -128,8 +152,44 @@ struct monitor *monitor_create(struct config *config, 
struct port *dst)
return monitor;
 }
 
+int monitor_delay(struct monitor *monitor, struct PortIdentity source_pid,
+ uint16_t seqid, tmv_t t3, tmv_t corr, tmv_t t4)
+{
+   struct slave_delay_timing_record *record;
+   struct ptp_message *msg;
+
+   if (!monitor_active(monitor)) {
+   return 0;
+   }
+
+   msg = monitor->delay.msg;
+
+   if (!pid_eq(>delay_tlv->sourcePortIdentity, _pid)) {
+   /* There was a change in remote master. Drop stale records. */
+   memcpy(>delay_tlv->sourcePortIdentity, _pid,
+  sizeof(monitor->delay_tlv->sourcePortIdentity));
+   monitor->delay.count = 0;
+   }
+
+   record = monitor->delay_tlv->record + monitor->delay.count;
+   record->sequenceId  = seqid;
+   record->delayOriginTimestamp= tmv_to_Timestamp(t3);
+   record->totalCorrectionField= tmv_to_TimeInterval(corr);
+   record->delayResponseTimestamp  = tmv_to_Timestamp(t4);
+
+   monitor->delay.count++;
+   if (monitor->delay.count == monitor->delay.records_per_msg) {
+   monitor->delay.count = 0;
+   return monitor_forward(monitor->dst_port, msg);
+   }
+   return 0;
+}
+
 void monitor_destroy(struct monitor *monitor)
 {
+   if (monitor->delay.msg) {
+   msg_put(monitor->delay.msg);
+   }
if (monitor->sync.msg) {
msg_put(monitor->sync.msg);
}
diff --git a/monitor.h b/monitor.h
index e2a6ca3..c489aa9 100644
--- a/monitor.h
+++ b/monitor.h
@@ -14,6 +14,9 @@ struct monitor;
 
 struct monitor *monitor_create(struct config *config, struct port *dst);
 
+int monitor_delay(struct monitor *monitor, struct PortIdentity source_pid,
+ uint16_t seqid, tmv_t t3, tmv_t corr, tmv_t t4);
+
 void monitor_destroy(struct monitor *monitor);
 
 int monitor_sync(struct monitor *monitor, struct PortIdentity source_pid,
-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 03/10] Introduce a module for slave event monitoring.

2020-05-24 Thread Richard Cochran
This patch adds a new module for slave event monitoring with its own
configuration option, a UDS address.  If the option is enabled, then
the monitor will send events to the configured address.  The default
setting produces an inactive monitor that does nothing.

Signed-off-by: Richard Cochran 
---
 config.c  |   1 +
 makefile  |   6 +-
 monitor.c | 171 ++
 monitor.h |  22 +++
 ptp4l.8   |   6 ++
 5 files changed, 203 insertions(+), 3 deletions(-)
 create mode 100644 monitor.c
 create mode 100644 monitor.h

diff --git a/config.c b/config.c
index 269183c..d3446b4 100644
--- a/config.c
+++ b/config.c
@@ -297,6 +297,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_INT("sanity_freq_limit", 2, 0, INT_MAX),
GLOB_ITEM_INT("servo_num_offset_values", 10, 0, INT_MAX),
GLOB_ITEM_INT("servo_offset_threshold", 0, 0, INT_MAX),
+   GLOB_ITEM_STR("slave_event_monitor", ""),
GLOB_ITEM_INT("slaveOnly", 0, 0, 1),
GLOB_ITEM_INT("socket_priority", 0, 0, 15),
GLOB_ITEM_DBL("step_threshold", 0.0, 0.0, DBL_MAX),
diff --git a/makefile b/makefile
index acc94f7..27c4d78 100644
--- a/makefile
+++ b/makefile
@@ -29,9 +29,9 @@ TRANSP= raw.o transport.o udp.o udp6.o uds.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_master.o \
  ts2phc_master.o ts2phc_phc_master.o ts2phc_nmea_master.o ts2phc_slave.o
 OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
- e2e_tc.o fault.o $(FILTERS) fsm.o hash.o interface.o msg.o phc.o port.o \
- port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o rtnl.o $(SERVOS) sk.o \
- stats.o tc.o $(TRANSP) telecom.o tlv.o tsproc.o unicast_client.o \
+ e2e_tc.o fault.o $(FILTERS) fsm.o hash.o interface.o monitor.o msg.o phc.o \
+ port.o port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o rtnl.o $(SERVOS) \
+ sk.o stats.o tc.o $(TRANSP) telecom.o tlv.o tsproc.o unicast_client.o \
  unicast_fsm.o unicast_service.o util.o version.o
 
 OBJECTS= $(OBJ) hwstamp_ctl.o nsm.o phc2sys.o phc_ctl.o pmc.o 
pmc_common.o \
diff --git a/monitor.c b/monitor.c
new file mode 100644
index 000..5706e5d
--- /dev/null
+++ b/monitor.c
@@ -0,0 +1,171 @@
+/**
+ * @file monitor.c
+ * @note Copyright (C) 2020 Richard Cochran 
+ * @note SPDX-License-Identifier: GPL-2.0+
+ */
+#include 
+#include 
+
+#include "address.h"
+#include "monitor.h"
+#include "print.h"
+
+#define RECORDS_PER_MESSAGE 1
+
+struct monitor_message {
+   struct ptp_message *msg;
+   int records_per_msg;
+   int count;
+};
+
+struct monitor {
+   struct port *dst_port;
+   struct slave_rx_sync_timing_data_tlv *sync_tlv;
+   struct monitor_message sync;
+};
+
+static bool monitor_active(struct monitor *monitor)
+{
+   return monitor->dst_port ? true : false;
+}
+
+static int monitor_forward(struct port *port, struct ptp_message *msg)
+{
+   int err, pdulen = msg->header.messageLength;
+
+   if (msg_pre_send(msg)) {
+   return -1;
+   }
+   err = port_forward_to(port, msg);
+   if (err) {
+   pr_debug("failed to send signaling message to slave event 
monitor: %s",
+strerror(-err));
+   }
+   if (msg_post_recv(msg, pdulen)) {
+   return -1;
+   }
+   msg->header.sequenceId++;
+
+   return 0;
+}
+
+static struct tlv_extra *monitor_init_message(struct monitor_message *mm,
+ struct port *destination,
+ uint16_t tlv_type,
+ size_t tlv_size,
+ struct address address)
+{
+   struct ptp_message *msg;
+   struct tlv_extra *extra;
+
+   msg = port_signaling_construct(destination, _pid);
+   if (!msg) {
+   return NULL;
+   }
+   extra = msg_tlv_append(msg, tlv_size);
+   if (!extra) {
+   msg_put(msg);
+   return NULL;
+   }
+   extra->tlv->type = tlv_type;
+   extra->tlv->length = tlv_size - sizeof(extra->tlv->type) -
+   sizeof(extra->tlv->length);
+
+   mm->msg = msg;
+   mm->msg->address = address;
+   mm->records_per_msg = RECORDS_PER_MESSAGE;
+   mm->count = 0;
+
+   return extra;
+}
+
+static int monitor_init_sync(struct monitor *monitor, struct address address)
+{
+   const size_t tlv_size = sizeof(struct slave_rx_sync_timing_data_tlv) +
+   sizeof(struct slave_rx_sync_timing_record) * 
RECORDS_PER_MESSAGE;
+   struct tlv_extra *extra;
+
+   extra = monitor_init_message(>sync, monitor->dst_port,
+TLV_SLAVE_RX_SYNC_TIMING_DATA, tlv_size,
+address);
+   if (!extra) {
+   return -1;
+   }
+   monitor->sync_tlv = (struct slave_rx_sync_timing_data_tlv *) extra->tlv;
+
+   return 0;

[Linuxptp-devel] [PATCH 02/10] tlv: Encode and decode SLAVE_RX_SYNC_TIMING_DATA TLVs.

2020-05-24 Thread Richard Cochran
Signed-off-by: Richard Cochran 
---
 tlv.c | 78 ++-
 tlv.h | 28 ++---
 2 files changed, 101 insertions(+), 5 deletions(-)

diff --git a/tlv.c b/tlv.c
index 0cf6d5c..e12e5ae 100644
--- a/tlv.c
+++ b/tlv.c
@@ -53,6 +53,20 @@ static void scaled_ns_h2n(ScaledNs *sns)
sns->fractional_nanoseconds = htons(sns->fractional_nanoseconds);
 }
 
+static void timestamp_host2net(struct Timestamp *t)
+{
+   HTONL(t->seconds_lsb);
+   HTONS(t->seconds_msb);
+   HTONL(t->nanoseconds);
+}
+
+static void timestamp_net2host(struct Timestamp *t)
+{
+   NTOHL(t->seconds_lsb);
+   NTOHS(t->seconds_msb);
+   NTOHL(t->nanoseconds);
+}
+
 static uint16_t flip16(uint16_t *p)
 {
uint16_t v;
@@ -80,11 +94,16 @@ static int64_t net2host64_unaligned(int64_t *p)
return v;
 }
 
+static size_t tlv_array_count(struct TLV *tlv, size_t base_size, size_t 
item_size)
+{
+   return (tlv->length - base_size) / item_size;
+}
+
 static bool tlv_array_invalid(struct TLV *tlv, size_t base_size, size_t 
item_size)
 {
size_t expected_length, n_items;
 
-   n_items = (tlv->length - base_size) / item_size;
+   n_items = tlv_array_count(tlv, base_size, item_size);
 
expected_length = base_size + n_items * item_size;
 
@@ -575,6 +594,57 @@ static void org_pre_send(struct organization_tlv *org)
}
 }
 
+static int slave_rx_sync_timing_data_post_revc(struct tlv_extra *extra)
+{
+   struct slave_rx_sync_timing_data_tlv *slave_data =
+   (struct slave_rx_sync_timing_data_tlv *) extra->tlv;
+   size_t base_size = sizeof(slave_data->sourcePortIdentity), n_items;
+   struct slave_rx_sync_timing_record *record;
+
+   if (tlv_array_invalid(extra->tlv, base_size, sizeof(*record))) {
+   return -EBADMSG;
+   }
+   n_items = tlv_array_count(extra->tlv, base_size, sizeof(*record));
+   record = slave_data->record;
+
+   NTOHS(slave_data->sourcePortIdentity.portNumber);
+
+   while (n_items) {
+   NTOHS(record->sequenceId);
+   timestamp_net2host(>syncOriginTimestamp);
+   net2host64_unaligned(>totalCorrectionField);
+   NTOHL(record->scaledCumulativeRateOffset);
+   timestamp_net2host(>syncEventIngressTimestamp);
+   n_items--;
+   record++;
+   }
+
+   return 0;
+}
+
+static void slave_rx_sync_timing_data_pre_send(struct tlv_extra *extra)
+{
+   struct slave_rx_sync_timing_data_tlv *slave_data =
+   (struct slave_rx_sync_timing_data_tlv *) extra->tlv;
+   size_t base_size = sizeof(slave_data->sourcePortIdentity), n_items;
+   struct slave_rx_sync_timing_record *record;
+
+   n_items = tlv_array_count(extra->tlv, base_size, sizeof(*record));
+   record = slave_data->record;
+
+   HTONS(slave_data->sourcePortIdentity.portNumber);
+
+   while (n_items) {
+   HTONS(record->sequenceId);
+   timestamp_host2net(>syncOriginTimestamp);
+   host2net64_unaligned(>totalCorrectionField);
+   HTONL(record->scaledCumulativeRateOffset);
+   timestamp_host2net(>syncEventIngressTimestamp);
+   n_items--;
+   record++;
+   }
+}
+
 static int unicast_message_type_valid(uint8_t message_type)
 {
message_type >>= 4;
@@ -743,7 +813,10 @@ int tlv_post_recv(struct tlv_extra *extra)
case TLV_L1_SYNC:
case TLV_PORT_COMMUNICATION_AVAILABILITY:
case TLV_PROTOCOL_ADDRESS:
+   break;
case TLV_SLAVE_RX_SYNC_TIMING_DATA:
+   result = slave_rx_sync_timing_data_post_revc(extra);
+   break;
case TLV_SLAVE_RX_SYNC_COMPUTED_DATA:
case TLV_SLAVE_TX_EVENT_TIMESTAMPS:
case TLV_CUMULATIVE_RATE_RATIO:
@@ -800,7 +873,10 @@ void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)
case TLV_L1_SYNC:
case TLV_PORT_COMMUNICATION_AVAILABILITY:
case TLV_PROTOCOL_ADDRESS:
+   break;
case TLV_SLAVE_RX_SYNC_TIMING_DATA:
+   slave_rx_sync_timing_data_pre_send(extra);
+   break;
case TLV_SLAVE_RX_SYNC_COMPUTED_DATA:
case TLV_SLAVE_TX_EVENT_TIMESTAMPS:
case TLV_CUMULATIVE_RATE_RATIO:
diff --git a/tlv.h b/tlv.h
index f46a3b8..8212325 100644
--- a/tlv.h
+++ b/tlv.h
@@ -224,6 +224,11 @@ struct path_trace_tlv {
struct ClockIdentity cid[0];
 } PACKED;
 
+static inline unsigned int path_length(struct path_trace_tlv *p)
+{
+   return p->length / sizeof(struct ClockIdentity);
+}
+
 struct request_unicast_xmit_tlv {
Enumeration16   type;
UInteger16  length;
@@ -232,10 +237,25 @@ struct request_unicast_xmit_tlv {
UInteger32  durationField;
 } PACKED;
 
-static inline unsigned int path_length(struct path_trace_tlv *p)
-{
-   return p->length / sizeof(struct 

[Linuxptp-devel] [PATCH 09/10] port: Support slave event monitoring of delay timing data.

2020-05-24 Thread Richard Cochran
After a successful message exchange, the delay measurement values are
processed by the port code.  This patch makes the values available to a
monitor by calling the appropriate method.

Signed-off-by: Richard Cochran 
---
 port.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/port.c b/port.c
index a74937c..729cbd7 100644
--- a/port.c
+++ b/port.c
@@ -1952,6 +1952,9 @@ void process_delay_resp(struct port *p, struct 
ptp_message *m)
t4 = timestamp_to_tmv(m->ts.pdu);
t4c = tmv_sub(t4, c3);
 
+   monitor_delay(p->slave_event_monitor, clock_parent_identity(p->clock),
+ m->header.sequenceId, t3, c3, t4);
+
clock_path_delay(p->clock, t3, t4c);
 
TAILQ_REMOVE(>delay_req, req, list);
-- 
2.20.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH V1 2/2] Add support for write phase mode.

2020-05-24 Thread Richard Cochran
On Mon, May 18, 2020 at 09:43:51AM +0200, Miroslav Lichvar wrote:
> On Sat, May 16, 2020 at 07:42:26AM -0700, Richard Cochran wrote:
> > Recently the Linux kernel's PTP Hardware Clock interface was expanded
> > to include a "write phase" mode where the clock servo in implemented
> > in hardware.  This mode hearkens back to the tradition ntp_adjtime
> > interface, passing a measured offset into the kernel's servo.
> 
> Is there some description of how the hardware PLL works and why
> would linuxptp want to support it?

This isn't about a particular hardware PLL but rather making use of an
interface.  It isn't even really about hardware servos per se.
Together with SW time stamping, this lets the user choose the kernel's
servo, for example.

For another example, this one a HW implementation, check this out.

   
https://www.idt.com/us/en/products/clocks-timing/application-specific-clocks/network-synchronization/ieee-1588-and-synchronous-ethernet-clocks/8a34001-system-synchronizer-ieee-1588-eight-channels
 
> > --- a/clockadj.c
> > +++ b/clockadj.c
> > @@ -79,6 +79,18 @@ double clockadj_get_freq(clockid_t clkid)
> > return f;
> >  }
> >  
> > +void clockadj_set_phase(clockid_t clkid, long offset)
> > +{
> > +   struct timex tx;
> > +   memset(, 0, sizeof(tx));
> > +
> > +   tx.modes |= ADJ_OFFSET;
> 
> ADJ_NANO is not required?

Yes, good catch.  The kernel interface also needs this...

Thanks,
Richard


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH V1 2/2] Add support for write phase mode.

2020-05-24 Thread Richard Cochran
On Mon, May 18, 2020 at 07:58:47AM +, FUSTE Emmanuel wrote:
> Perhaps too late, and should have been raised on netdev but why ns 
> granularity for phase adjustment ?

This comes from the traditional NTP timex interface.

> Talking about net device phc clock and phase adjustment I directly think 
> "white rabbit". If your PHC is locked on the ethernet carrier (SyncE), 
> the final step is phase adjustment to go to sub ns sync.
> Choosing ps granularity would be more future proof for the interface and 
> would allow to expose white rabbit hardware clock/board as a PHC and 
> implement the WR control plane in userspace using standard interface 
> (would need more extension, but it is a start).

I think it wouldn't be hard to extend the interface.  You could take
one of the unused 32 bit fields and make that fractional nanoseconds,
for example.  If white rabbit wants to submit an patch to the kernel
along with a driver, then I would support the idea.

Thanks,
Richard


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel