Split management message creation to more fine-grained functions to allow
notification messages to be created.

The new clock_management_fill_response is called from
clock_management_get_response (so the function behaves exactly the same as
before this patch) and from a new clock_notify_event function. The
difference is clock_management_get_response uses the request message to
construct the reply message, while clock_notify_event constructs the reply
message based on the notification id.

Signed-off-by: Jiri Benc <jb...@redhat.com>
---
 clock.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 clock.h |    8 ++++++++
 port.c  |    8 +++++++-
 port.h  |   14 ++++++++++++++
 4 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/clock.c b/clock.c
index e5d58bacc22c..32ba4907119c 100644
--- a/clock.c
+++ b/clock.c
@@ -314,23 +314,22 @@ static void clock_management_send_error(struct port *p,
                pr_err("failed to send management error status");
 }
 
-static int clock_management_get_response(struct clock *c, struct port *p,
-                                        int id, struct ptp_message *req)
+/* The 'p' and 'req' paremeters are needed for the GET actions that operate
+ * on per-client datasets. If such actions do not apply to the caller, it is
+ * allowed to pass both of them as NULL.
+ */
+static int clock_management_fill_response(struct clock *c, struct port *p,
+                                         struct ptp_message *req,
+                                         struct ptp_message *rsp, int id)
 {
        int datalen = 0, respond = 0;
        struct management_tlv *tlv;
        struct management_tlv_datum *mtd;
-       struct ptp_message *rsp;
        struct time_status_np *tsn;
        struct grandmaster_settings_np *gsn;
        struct subscribe_events_np *sen;
-       struct PortIdentity pid = port_identity(p);
        struct PTPText *text;
 
-       rsp = port_management_reply(pid, p, req);
-       if (!rsp) {
-               return 0;
-       }
        tlv = (struct management_tlv *) rsp->management.suffix;
        tlv->type = TLV_MANAGEMENT;
        tlv->id = id;
@@ -450,10 +449,26 @@ static int clock_management_get_response(struct clock *c, 
struct port *p,
                tlv->length = sizeof(tlv->id) + datalen;
                rsp->header.messageLength += sizeof(*tlv) + datalen;
                rsp->tlv_count = 1;
-               port_prepare_and_send(p, rsp, 0);
        }
+       return respond;
+}
+
+static int clock_management_get_response(struct clock *c, struct port *p,
+                                        int id, struct ptp_message *req)
+{
+       struct PortIdentity pid = port_identity(p);
+       struct ptp_message *rsp;
+       int respond;
+
+       rsp = port_management_reply(pid, p, req);
+       if (!rsp) {
+               return 0;
+       }
+       respond = clock_management_fill_response(c, p, req, rsp, id);
+       if (respond)
+               port_prepare_and_send(p, rsp, 0);
        msg_put(rsp);
-       return respond ? 1 : 0;
+       return respond;
 }
 
 static int clock_management_set(struct clock *c, struct port *p,
@@ -1064,6 +1079,34 @@ int clock_manage(struct clock *c, struct port *p, struct 
ptp_message *msg)
        return changed;
 }
 
+void clock_notify_event(struct clock *c, enum notification event)
+{
+       struct port *uds = c->port[c->nports];
+       struct PortIdentity pid = port_identity(uds);
+       struct ptp_message *msg;
+       UInteger16 msg_len;
+       int id;
+
+       switch (event) {
+       /* set id */
+       default:
+               return;
+       }
+       /* targetPortIdentity and sequenceId will be filled by
+        * clock_send_notification */
+       msg = port_management_notify(pid, uds);
+       if (!msg)
+               return;
+       if (!clock_management_fill_response(c, NULL, NULL, msg, id))
+               goto err;
+       msg_len = msg->header.messageLength;
+       if (msg_pre_send(msg))
+               goto err;
+       clock_send_notification(c, msg, msg_len, event);
+err:
+       msg_put(msg);
+}
+
 struct parent_ds *clock_parent_ds(struct clock *c)
 {
        return &c->dad;
diff --git a/clock.h b/clock.h
index 8718f2db715b..92ec163d962f 100644
--- a/clock.h
+++ b/clock.h
@@ -145,6 +145,14 @@ void clock_send_notification(struct clock *c, struct 
ptp_message *msg,
                             int msglen, enum notification event);
 
 /**
+ * Construct and send notification to subscribers about an event that
+ * occured on the clock.
+ * @param c      The clock instance.
+ * @param event  The identification of the event.
+ */
+void clock_notify_event(struct clock *c, enum notification event);
+
+/**
  * Obtain a clock's parent data set.
  * @param c  The clock instance.
  * @return   A pointer to the parent data set of the clock.
diff --git a/port.c b/port.c
index bdddd3abc5d0..388f7571d680 100644
--- a/port.c
+++ b/port.c
@@ -2337,6 +2337,12 @@ struct ptp_message *port_management_reply(struct 
PortIdentity pid,
                                         management_action(req));
 }
 
+struct ptp_message *port_management_notify(struct PortIdentity pid,
+                                          struct port *port)
+{
+       return port_management_construct(pid, port, 0, NULL, 1, GET);
+}
+
 void port_notify_event(struct port *p, enum notification event)
 {
        struct PortIdentity pid = port_identity(p);
@@ -2351,7 +2357,7 @@ void port_notify_event(struct port *p, enum notification 
event)
        }
        /* targetPortIdentity and sequenceId will be filled by
         * clock_send_notification */
-       msg = port_management_construct(pid, p, 0, NULL, 1, GET);
+       msg = port_management_notify(pid, p);
        if (!msg)
                return;
        if (!port_management_fill_response(p, msg, id))
diff --git a/port.h b/port.h
index 34c18a3e2d0c..a1b8ad795040 100644
--- a/port.h
+++ b/port.h
@@ -157,6 +157,20 @@ struct ptp_message *port_management_reply(struct 
PortIdentity pid,
                                          struct ptp_message *req);
 
 /**
+ * Allocate a standalone reply management message.
+ *
+ * See note in @ref port_management_reply description about freeing the
+ * message. Also note that the constructed message does not have
+ * targetPortIdentity and sequenceId filled.
+ *
+ * @param pid      The id of the responding port.
+ * @param port     The port to which the message will be sent.
+ * @return         Pointer to a message on success, NULL otherwise.
+ */
+struct ptp_message *port_management_notify(struct PortIdentity pid,
+                                          struct port *port);
+
+/**
  * Construct and send notification to subscribers about an event that
  * occured on the port.
  * @param p        The port.
-- 
1.7.6.5


------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to