A PTP Master Clock, which is not the Best Master, may act as a master with the Alternate Master flag set on the messages it sends. Need to support Alternate Master, including using Slave Event Monitoring channel for the alternate connections (to pass along timestamps to external servo). See ITU-T G.8275.2 Appendix III & V.
Signed-off-by: Greg Armstrong <greg.armstrong...@renesas.com> Signed-off-by: Leon Goldin <leon.goldin...@renesas.com> Signed-off-by: Devasish Dey <devasish....@syncmonk.net> Signed-off-by: Vipin Sharma <vipin.sha...@syncmonk.net> --- monitor.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ monitor.h | 3 +++ pmc.c | 31 +++++++++++++++++++++++++++ tlv.h | 21 +++++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/monitor.c b/monitor.c index ed451ac..1965a89 100644 --- a/monitor.c +++ b/monitor.c @@ -21,8 +21,10 @@ struct monitor_message { struct monitor { struct port *dst_port; struct slave_rx_sync_timing_data_tlv *sync_tlv; + struct slave_rx_sync_computed_data_tlv *computed_tlv; struct slave_delay_timing_data_tlv *delay_tlv; struct monitor_message delay; + struct monitor_message computed; struct monitor_message sync; }; @@ -115,6 +117,23 @@ static int monitor_init_sync(struct monitor *monitor, struct address address) return 0; } +static int monitor_init_computed(struct monitor *monitor, struct address address) +{ + const size_t tlv_size = sizeof(struct slave_rx_sync_computed_data_tlv) + + sizeof(struct slave_rx_sync_computed_record) * RECORDS_PER_MESSAGE; + struct tlv_extra *extra; + + extra = monitor_init_message(&monitor->computed, monitor->dst_port, + TLV_SLAVE_RX_SYNC_COMPUTED_DATA, tlv_size, + address); + if (!extra) { + return -1; + } + monitor->computed_tlv = (struct slave_rx_sync_computed_data_tlv *) extra->tlv; + + return 0; +} + struct monitor *monitor_create(struct config *config, struct port *dst) { struct monitor *monitor; @@ -148,6 +167,12 @@ struct monitor *monitor_create(struct config *config, struct port *dst) free(monitor); return NULL; } + if (monitor_init_computed(monitor, address)) { + msg_put(monitor->sync.msg); + msg_put(monitor->delay.msg); + free(monitor); + return NULL; + } return monitor; } @@ -193,6 +218,9 @@ void monitor_destroy(struct monitor *monitor) if (monitor->sync.msg) { msg_put(monitor->sync.msg); } + if (monitor->computed.msg) { + msg_put(monitor->computed.msg); + } free(monitor); } @@ -229,3 +257,38 @@ int monitor_sync(struct monitor *monitor, struct PortIdentity source_pid, } return 0; } + +int monitor_computed(struct monitor *monitor, struct PortIdentity source_pid, + uint16_t seqid, tmv_t offset, tmv_t pathdelay, int32_t ratio, + uint8_t best_master) +{ + struct slave_rx_sync_computed_record *record; + struct ptp_message *msg; + + if (!monitor_active(monitor)) { + return 0; + } + + msg = monitor->computed.msg; + + if (!pid_eq(&monitor->computed_tlv->sourcePortIdentity, &source_pid)) { + /* There was a change in remote master. Drop stale records. */ + memcpy(&monitor->computed_tlv->sourcePortIdentity, &source_pid, + sizeof(monitor->computed_tlv->sourcePortIdentity)); + monitor->computed.count = 0; + } + + record = monitor->computed_tlv->record + monitor->computed.count; + monitor->computed_tlv->reserved = 0; + record->sequenceId = seqid; + record->offsetFromMaster = tmv_to_TimeInterval(offset); + record->meanPathDelay = tmv_to_TimeInterval(pathdelay); + record->scaledNeighborRateRatio = ratio; + + monitor->computed.count++; + if (monitor->computed.count == monitor->computed.records_per_msg) { + monitor->computed.count = 0; + return monitor_forward(monitor->dst_port, msg); + } + return 0; +} diff --git a/monitor.h b/monitor.h index c489aa9..9beb57e 100644 --- a/monitor.h +++ b/monitor.h @@ -22,4 +22,7 @@ void monitor_destroy(struct monitor *monitor); int monitor_sync(struct monitor *monitor, struct PortIdentity source_pid, uint16_t seqid, tmv_t t1, tmv_t corr, tmv_t t2); +int monitor_computed(struct monitor *monitor, struct PortIdentity source_pid, + uint16_t seqid, tmv_t offset, tmv_t pathdelay, int32_t ratio, + uint8_t best_master); #endif diff --git a/pmc.c b/pmc.c index e218ca4..b6227dd 100644 --- a/pmc.c +++ b/pmc.c @@ -88,6 +88,19 @@ static void pmc_show_rx_sync_timing(struct slave_rx_sync_timing_record *record, SHOW_TIMESTAMP(record->syncEventIngressTimestamp)); } +static void pmc_show_rx_sync_computed_data(struct slave_rx_sync_computed_record *record, + FILE *fp) +{ + fprintf(fp, + IFMT "sequenceId %hu" + IFMT "offsetFromMaster %" PRId64 + IFMT "meanPathDelay %" PRId64 + IFMT "scaledNeighborRateRatio %d", + record->sequenceId, + record->offsetFromMaster, + record->meanPathDelay, + record->scaledNeighborRateRatio); +} static void pmc_show_unicast_master_entry(struct unicast_master_entry *entry, FILE *fp) @@ -110,8 +123,10 @@ 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_computed_record *sync_computed_record; struct slave_rx_sync_timing_data_tlv *srstd; struct slave_delay_timing_data_tlv *sdtdt; + struct slave_rx_sync_computed_data_tlv *srscdt; struct tlv_extra *extra; int i, cnt; @@ -147,6 +162,22 @@ static void pmc_show_signaling(struct ptp_message *msg, FILE *fp) delay_record++; } break; + case TLV_SLAVE_RX_SYNC_COMPUTED_DATA: + srscdt = (struct slave_rx_sync_computed_data_tlv *) extra->tlv; + cnt = (srscdt->length - sizeof(srscdt->sourcePortIdentity)) / + sizeof(*sync_computed_record); + fprintf(fp, "SLAVE_RX_SYNC_COMPUTED_DATA N %d " + IFMT "sourcePortIdentity %s" + IFMT "computedFlags %02x" + IFMT "reserved %02x", + cnt, pid2str(&srscdt->sourcePortIdentity), + srscdt->computedFlags, srscdt->reserved); + sync_computed_record = srscdt->record; + for (i = 0; i < cnt; i++) { + pmc_show_rx_sync_computed_data(sync_computed_record, fp); + sync_computed_record++; + } + break; default: break; } diff --git a/tlv.h b/tlv.h index 8966696..38a48c9 100644 --- a/tlv.h +++ b/tlv.h @@ -283,6 +283,27 @@ struct slave_rx_sync_timing_data_tlv { sizeof(struct slave_rx_sync_timing_data_tlv)) / \ sizeof(struct slave_rx_sync_timing_record)) +struct slave_rx_sync_computed_record { + UInteger16 sequenceId; + TimeInterval offsetFromMaster; + TimeInterval meanPathDelay; + Integer32 scaledNeighborRateRatio; +} PACKED; + +struct slave_rx_sync_computed_data_tlv { + Enumeration16 type; + UInteger16 length; + struct PortIdentity sourcePortIdentity; + uint8_t computedFlags; + uint8_t reserved; + struct slave_rx_sync_computed_record record[0]; +} PACKED; + +#define SLAVE_RX_SYNC_COMPUTED_MAX \ + ((sizeof(struct message_data) - sizeof(struct signaling_msg) - \ + sizeof(struct slave_rx_sync_computed_data_tlv)) / \ + sizeof(struct slave_rx_sync_computed_record)) + typedef struct Integer96 { uint16_t nanoseconds_msb; uint64_t nanoseconds_lsb; -- 2.25.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel