This implements transmission and receipt of message interval requests.
Using this mechanism, a time-aware device can request change in sync,
link delay and announce intervals on the device connected on the other
end.

As part of the commit, we are also saving the initial values of Announce
and Sync Interval.

For more information look at sections 10.2.4.4, 10.3.9.5, 10.3.14, 10.4,
10.5.4 and 11.2.17 of 802.1AS standard

Please note that this commit does not implement logic related to
computeNeighborRateRatio and computeNeighborPropDelay flags mentioned in
Section 10.5.4.3.9 of 802.1AS Standard.

Signed-off-by: Vedang Patel <[email protected]>
---
 msg.h            |  6 ++++
 port.c           |  2 ++
 port_private.h   |  7 ++++
 port_signaling.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tlv.h            | 12 +++++++
 5 files changed, 125 insertions(+)

diff --git a/msg.h b/msg.h
index b5a57fec6d2d..f04b9f42a30f 100644
--- a/msg.h
+++ b/msg.h
@@ -57,6 +57,12 @@
 #define TIME_TRACEABLE (1<<4)
 #define FREQ_TRACEABLE (1<<5)
 
+/*
+ * Signaling interval special values. For more info look at 802.1AS table 10-11
+ */
+#define SIGNAL_NO_CHANGE   -128
+#define SIGNAL_SET_INITIAL 126
+
 enum timestamp_type {
        TS_SOFTWARE,
        TS_HARDWARE,
diff --git a/port.c b/port.c
index 4c845358f612..015766103e05 100644
--- a/port.c
+++ b/port.c
@@ -1591,6 +1591,7 @@ int port_initialize(struct port *p)
        p->logMinDelayReqInterval  = config_get_int(cfg, p->name, 
"logMinDelayReqInterval");
        p->peerMeanPathDelay       = 0;
        p->logAnnounceInterval     = config_get_int(cfg, p->name, 
"logAnnounceInterval");
+       p->initialLogAnnounceInterval = p->logAnnounceInterval;
        p->inhibit_announce        = config_get_int(cfg, p->name, 
"inhibit_announce");
        p->ignore_source_id        = config_get_int(cfg, p->name, 
"ignore_source_id");
        p->announceReceiptTimeout  = config_get_int(cfg, p->name, 
"announceReceiptTimeout");
@@ -1600,6 +1601,7 @@ int port_initialize(struct port *p)
        p->match_transport_specific = !config_get_int(cfg, p->name, 
"ignore_transport_specific");
        p->localPriority           = config_get_int(cfg, p->name, 
"G.8275.portDS.localPriority");
        p->logSyncInterval         = config_get_int(cfg, p->name, 
"logSyncInterval");
+       p->initialLogSyncInterval  = p->logSyncInterval;
        p->logMinPdelayReqInterval = config_get_int(cfg, p->name, 
"logMinPdelayReqInterval");
        p->logPdelayReqInterval    = p->logMinPdelayReqInterval;
        p->neighborPropDelayThresh = config_get_int(cfg, p->name, 
"neighborPropDelayThresh");
diff --git a/port_private.h b/port_private.h
index b51a29121fc8..b02137847e44 100644
--- a/port_private.h
+++ b/port_private.h
@@ -107,12 +107,14 @@ struct port {
        enum as_capable     asCapable;
        Integer8            logMinDelayReqInterval;
        TimeInterval        peerMeanPathDelay;
+       Integer8            initialLogAnnounceInterval;
        Integer8            logAnnounceInterval;
        UInteger8           announceReceiptTimeout;
        int                 announce_span;
        UInteger8           syncReceiptTimeout;
        UInteger8           transportSpecific;
        UInteger8           localPriority;
+       Integer8            initialLogSyncInterval;
        Integer8            logSyncInterval;
        Enumeration8        delayMechanism;
        Integer8            logMinPdelayReqInterval;
@@ -185,5 +187,10 @@ enum fsm_event process_sync(struct port *p, struct 
ptp_message *m);
 int source_pid_eq(struct ptp_message *m1, struct ptp_message *m2);
 void ts_add(tmv_t *ts, Integer64 correction);
 int port_capable(struct port *p);
+int port_tx_signaling(struct port *p,
+                     Integer8 announceInterval,
+                     Integer8 timeSyncInterval,
+                     Integer8 linkDelayInterval);
+
 
 #endif
diff --git a/port_signaling.c b/port_signaling.c
index d4f1939b8bea..5bfb7584b999 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -17,7 +17,11 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA.
  */
+#include <errno.h>
+
+#include "port.h"
 #include "port_private.h"
+#include "print.h"
 #include "unicast_client.h"
 #include "unicast_service.h"
 
@@ -61,6 +65,48 @@ struct ptp_message *port_unicast_construct(struct port *p,
        return msg;
 }
 
+static void set_interval(int8_t *current_interval,
+                        int8_t new_interval,
+                        int8_t initial_interval)
+{
+       switch (new_interval) {
+       case SIGNAL_NO_CHANGE:
+               break;
+       case SIGNAL_SET_INITIAL:
+               *current_interval = initial_interval;
+               break;
+       default:
+               *current_interval = new_interval;
+               break;
+       }
+}
+
+static int process_interval_request(struct port *p,
+                                    struct tlv_extra *extra)
+{
+       struct msg_interval_req_tlv *r;
+
+       r = (struct msg_interval_req_tlv *) extra->tlv;
+
+       if (r->subtype[2] != 2) {
+               return -EBADMSG;
+       }
+
+       set_interval(&p->logAnnounceInterval,
+                    r->announceInterval,
+                    p->initialLogAnnounceInterval);
+
+       set_interval(&p->logSyncInterval,
+                    r->timeSyncInterval,
+                    p->initialLogSyncInterval);
+
+       set_interval(&p->logPdelayReqInterval,
+                    r->linkDelayInterval,
+                    p->logMinPdelayReqInterval);
+
+       return 0;
+}
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
        struct tlv_extra *extra;
@@ -109,7 +155,59 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
 
                case TLV_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION:
                        break;
+
+               case TLV_ORGANIZATION_EXTENSION:
+                       err = process_interval_request(p, extra);
+                       break;
                }
        }
        return err;
 }
+
+int port_tx_signaling(struct port *p,
+                     Integer8 announceInterval,
+                     Integer8 timeSyncInterval,
+                     Integer8 linkDelayInterval)
+{
+       int err;
+       struct ptp_message *msg;
+       struct tlv_extra *extra;
+       struct msg_interval_req_tlv *mir;
+       struct PortIdentity tpid = {0};
+
+       tpid.portNumber = 0xFF;
+
+       if (!port_capable(p)) {
+               return 0;
+       }
+
+       msg = port_signaling_construct(p, &tpid);
+       if (!msg) {
+               return -1;
+       }
+
+       extra = msg_tlv_append(msg, sizeof(*mir));
+       if (!extra) {
+               err = -1;
+               goto out;
+       }
+
+       mir = (struct msg_interval_req_tlv *) extra->tlv;
+       mir->type = TLV_ORGANIZATION_EXTENSION;
+       mir->length = sizeof(*mir) - sizeof(mir->type) - sizeof(mir->length);
+       memcpy(mir->id, ieee8021_id, sizeof(ieee8021_id));
+       mir->subtype[2] = 2;
+       mir->timeSyncInterval = timeSyncInterval;
+       mir->announceInterval = announceInterval;
+       mir->linkDelayInterval = linkDelayInterval;
+       mir->flags = 0;
+
+       err = port_prepare_and_send(p, msg, TRANS_GENERAL);
+       if (err) {
+               pr_err("port %hu: send signaling failed", portnum(p));
+       }
+
+out:
+       msg_put(msg);
+       return err;
+}
diff --git a/tlv.h b/tlv.h
index 958555c4e280..bcbfdd9a1fde 100644
--- a/tlv.h
+++ b/tlv.h
@@ -230,6 +230,18 @@ struct follow_up_info_tlv {
        Integer32     scaledLastGmPhaseChange;
 } PACKED;
 
+struct msg_interval_req_tlv {
+       Enumeration16 type;
+       UInteger16    length;
+       Octet         id[3];
+       Octet         subtype[3];
+       Integer8      linkDelayInterval;
+       Integer8      timeSyncInterval;
+       Integer8      announceInterval;
+       Octet         flags;
+       Octet         reserved[2];
+} PACKED;
+
 struct time_status_np {
        int64_t       master_offset; /*nanoseconds*/
        int64_t       ingress_time;  /*nanoseconds*/
-- 
2.7.3



_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to