Hello everyone,

I am new to the list. When I asked a question on the users list Richard
helped me out and suggested to implement a push notification for
TIME_STATUS_NP in ptp4l:

If your sync rate is really high, then you should want to implement
the "push" notification from ptp4l for TIME_STATUS_NP.  This would
happen on every Sync message.  That would save you periodic queries
from your application.  Right now the only push notification is for
PORT_DATA_SET, but I would like to have TIME_STATUS_NP as well.

So I tried this, but I am not quite sure about the place, where the
notification is fired, namely clock_synchronization(). Please have a look.

j

----

From 9f062b08652512ae4c66f9ad20747098666ae8f6 Mon Sep 17 00:00:00 2001
From: Juergen Werner <pogoj...@gmx.net>
Date: Wed, 20 Jan 2021 20:11:34 +0100
Subject: [PATCH] Implement push notification for TIME_STATUS_NP

Subscribers to NOTIFY_TIME_SYNC will be notified on every clock
synchronization.

Signed-off-by: Juergen Werner <pogoj...@gmx.net>
---
 clock.c        | 15 ++++++++++-----
 notification.h | 19 +++++++++++++++++++
 pmc.c          |  6 ++++--
 pmc_agent.c    |  3 ++-
 pmc_common.c   | 23 +++++++++++++++--------
 5 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/clock.c b/clock.c
index 08c61eb..1b57cb5 100644
--- a/clock.c
+++ b/clock.c
@@ -243,13 +243,11 @@ static void clock_prune_subscriptions(struct clock *c)
 void clock_send_notification(struct clock *c, struct ptp_message *msg,
                             enum notification event)
 {
-       unsigned int event_pos = event / 8;
-       uint8_t mask = 1 << (event % 8);
        struct port *uds = c->uds_port;
        struct clock_subscriber *s;

        LIST_FOREACH(s, &c->subscribers, list) {
-               if (!(s->events[event_pos] & mask))
+               if (!event_bitmask_get(s->events, event))
                        continue;
                /* send event */
                msg->header.sequenceId = htons(s->sequenceId);
@@ -1502,7 +1500,9 @@ void clock_notify_event(struct clock *c, enum
notification event)
        int id;

        switch (event) {
-       /* set id */
+       case NOTIFY_TIME_SYNC:
+               id = TLV_TIME_STATUS_NP;
+               break;
        default:
                return;
        }
@@ -1732,7 +1732,9 @@ enum servo_state clock_synchronize(struct clock
*c, tmv_t ingress, tmv_t origin)
        c->cur.offsetFromMaster = tmv_to_TimeInterval(c->master_offset);

        if (c->free_running) {
-               return clock_no_adjust(c, ingress, origin);
+               state = clock_no_adjust(c, ingress, origin);
+               clock_notify_event(c, NOTIFY_TIME_SYNC);
+               return state;
        }

        offset = tmv_to_nanoseconds(c->master_offset);
@@ -1778,6 +1780,9 @@ enum servo_state clock_synchronize(struct clock
*c, tmv_t ingress, tmv_t origin)
                        tmv_to_nanoseconds(c->path_delay));
        }

+
+       clock_notify_event(c, NOTIFY_TIME_SYNC);
+
        return state;
 }

diff --git a/notification.h b/notification.h
index 47c9b56..d56e563 100644
--- a/notification.h
+++ b/notification.h
@@ -20,8 +20,27 @@
 #ifndef HAVE_NOTIFICATION_H
 #define HAVE_NOTIFICATION_H

+#include "pdt.h"
+
+static inline void event_bitmask_set(UInteger8 *bitmask, int event,
Boolean value)
+{
+       unsigned int event_pos = event / 8;
+       UInteger8 event_bit = 1 << (event % 8);
+
+       if (value)
+               bitmask[event_pos] |= event_bit;
+       else
+               bitmask[event_pos] &= ~(event_bit);
+}
+
+static inline Boolean event_bitmask_get(UInteger8 *bitmask, int event)
+{
+       return (bitmask[event / 8] & (1 << (event % 8))) ? TRUE : FALSE;
+}
+
 enum notification {
        NOTIFY_PORT_STATE,
+       NOTIFY_TIME_SYNC,
 };

 #endif
diff --git a/pmc.c b/pmc.c
index 65d1d61..3678800 100644
--- a/pmc.c
+++ b/pmc.c
@@ -387,9 +387,11 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
                sen = (struct subscribe_events_np *) mgt->data;
                fprintf(fp, "SUBSCRIBE_EVENTS_NP "
                        IFMT "duration          %hu"
-                       IFMT "NOTIFY_PORT_STATE %s",
+                       IFMT "NOTIFY_PORT_STATE %s"
+                       IFMT "NOTIFY_TIME_SYNC  %s",
                        sen->duration,
-                       (sen->bitmask[0] & 1 << NOTIFY_PORT_STATE) ? "on" : 
"off");
+                       event_bitmask_get(sen->bitmask, NOTIFY_PORT_STATE) ? "on" : 
"off",
+                       event_bitmask_get(sen->bitmask, NOTIFY_TIME_SYNC) ? "on" : 
"off");
                break;
        case TLV_SYNCHRONIZATION_UNCERTAIN_NP:
                mtd = (struct management_tlv_datum *) mgt->data;
diff --git a/pmc_agent.c b/pmc_agent.c
index 5871f12..a3f1461 100644
--- a/pmc_agent.c
+++ b/pmc_agent.c
@@ -57,7 +57,8 @@ static void send_subscription(struct pmc_agent *node)

        memset(&sen, 0, sizeof(sen));
        sen.duration = PMC_SUBSCRIBE_DURATION;
-       sen.bitmask[0] = 1 << NOTIFY_PORT_STATE;
+       event_bitmask_set(sen.bitmask, NOTIFY_PORT_STATE, TRUE);
+       event_bitmask_set(sen.bitmask, NOTIFY_TIME_SYNC, TRUE);
        pmc_send_set_action(node->pmc, TLV_SUBSCRIBE_EVENTS_NP, &sen,
sizeof(sen));
 }

diff --git a/pmc_common.c b/pmc_common.c
index a117904..c5cd992 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -149,7 +149,8 @@ static void do_set_action(struct pmc *pmc, int
action, int index, char *str)
        struct management_tlv_datum mtd;
        struct subscribe_events_np sen;
        struct port_ds_np pnp;
-       char onoff[4] = {0};
+       char onoff_port_state[4] = "off";
+       char onoff_time_status[4] = "off";

        switch (action) {
        case GET:
@@ -223,16 +224,22 @@ static void do_set_action(struct pmc *pmc, int
action, int index, char *str)
        case TLV_SUBSCRIBE_EVENTS_NP:
                memset(&sen, 0, sizeof(sen));
                cnt = sscanf(str, " %*s %*s "
-                            "duration %hu "
-                            "NOTIFY_PORT_STATE %3s ",
-                            &sen.duration, onoff);
-               if (cnt != 2) {
-                       fprintf(stderr, "%s SET needs 2 values\n",
+                            "duration          %hu "
+                            "NOTIFY_PORT_STATE %3s "
+                            "NOTIFY_TIME_SYNC  %3s ",
+                            &sen.duration,
+                            onoff_port_state,
+                            onoff_time_status);
+               if (cnt != 3) {
+                       fprintf(stderr, "%s SET needs 3 values\n",
                                idtab[index].name);
                        break;
                }
-               if (!strcasecmp(onoff, "on")) {
-                       sen.bitmask[0] = 1 << NOTIFY_PORT_STATE;
+               if (!strcasecmp(onoff_port_state, "on")) {
+                       event_bitmask_set(sen.bitmask, NOTIFY_PORT_STATE, TRUE);
+               }
+               if (!strcasecmp(onoff_time_status, "on")) {
+                       event_bitmask_set(sen.bitmask, NOTIFY_TIME_SYNC, TRUE);
                }
                pmc_send_set_action(pmc, code, &sen, sizeof(sen));
                break;
--
2.30.0




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

Reply via email to