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

Signed-off-by: Jiri Benc <jb...@redhat.com>
---
 port.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------
 port.h |    9 ++++++
 2 files changed, 82 insertions(+), 20 deletions(-)

diff --git a/port.c b/port.c
index d8974ed1156b..a78eab24f8aa 100644
--- a/port.c
+++ b/port.c
@@ -603,26 +603,19 @@ static void port_management_send_error(struct port *p, 
struct port *ingress,
 static const Octet profile_id_drr[] = {0x00, 0x1B, 0x19, 0x00, 0x01, 0x00};
 static const Octet profile_id_p2p[] = {0x00, 0x1B, 0x19, 0x00, 0x02, 0x00};
 
-static int port_management_get_response(struct port *target,
-                                       struct port *ingress, int id,
-                                       struct ptp_message *req)
+static int port_management_fill_response(struct port *target,
+                                        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 portDS *pds;
        struct port_ds_np *pdsnp;
-       struct PortIdentity pid = port_identity(target);
        struct clock_description *desc;
        struct mgmt_clock_description *cd;
        uint8_t *buf;
        uint16_t u16;
 
-       rsp = port_management_reply(pid, ingress, req);
-       if (!rsp) {
-               return 0;
-       }
        tlv = (struct management_tlv *) rsp->management.suffix;
        tlv->type = TLV_MANAGEMENT;
        tlv->id = id;
@@ -776,10 +769,27 @@ static int port_management_get_response(struct port 
*target,
                tlv->length = sizeof(tlv->id) + datalen;
                rsp->header.messageLength += sizeof(*tlv) + datalen;
                rsp->tlv_count = 1;
-               port_prepare_and_send(ingress, rsp, 0);
        }
+       return respond;
+}
+
+static int port_management_get_response(struct port *target,
+                                       struct port *ingress, int id,
+                                       struct ptp_message *req)
+{
+       struct PortIdentity pid = port_identity(target);
+       struct ptp_message *rsp;
+       int respond;
+
+       rsp = port_management_reply(pid, ingress, req);
+       if (!rsp) {
+               return 0;
+       }
+       respond = port_management_fill_response(target, rsp, id);
+       if (respond)
+               port_prepare_and_send(ingress, rsp, 0);
        msg_put(rsp);
-       return respond ? 1 : 0;
+       return respond;
 }
 
 static int port_management_set(struct port *target,
@@ -2280,9 +2290,11 @@ int port_management_error(struct PortIdentity pid, 
struct port *ingress,
        return err;
 }
 
-struct ptp_message *port_management_reply(struct PortIdentity pid,
-                                         struct port *ingress,
-                                         struct ptp_message *req)
+static struct ptp_message *
+port_management_construct(struct PortIdentity pid, struct port *ingress,
+                         UInteger16 sequenceId,
+                         struct PortIdentity *targetPortIdentity,
+                         UInteger8 boundaryHops, uint8_t action)
 {
        struct ptp_message *msg;
        int pdulen;
@@ -2299,16 +2311,16 @@ struct ptp_message *port_management_reply(struct 
PortIdentity pid,
        msg->header.messageLength      = pdulen;
        msg->header.domainNumber       = clock_domain_number(ingress->clock);
        msg->header.sourcePortIdentity = pid;
-       msg->header.sequenceId         = req->header.sequenceId;
+       msg->header.sequenceId         = sequenceId;
        msg->header.control            = CTL_MANAGEMENT;
        msg->header.logMessageInterval = 0x7f;
 
-       msg->management.targetPortIdentity = req->header.sourcePortIdentity;
-       msg->management.startingBoundaryHops =
-               req->management.startingBoundaryHops - 
req->management.boundaryHops;
-       msg->management.boundaryHops = msg->management.startingBoundaryHops;
+       if (targetPortIdentity)
+               msg->management.targetPortIdentity = *targetPortIdentity;
+       msg->management.startingBoundaryHops = boundaryHops;
+       msg->management.boundaryHops = boundaryHops;
 
-       switch (management_action(req)) {
+       switch (action) {
        case GET: case SET:
                msg->management.flags = RESPONSE;
                break;
@@ -2319,6 +2331,47 @@ struct ptp_message *port_management_reply(struct 
PortIdentity pid,
        return msg;
 }
 
+struct ptp_message *port_management_reply(struct PortIdentity pid,
+                                         struct port *ingress,
+                                         struct ptp_message *req)
+{
+       UInteger8 boundaryHops;
+
+       boundaryHops = req->management.startingBoundaryHops - 
req->management.boundaryHops;
+       return port_management_construct(pid, ingress,
+                                        req->header.sequenceId,
+                                        &req->header.sourcePortIdentity,
+                                        boundaryHops,
+                                        management_action(req));
+}
+
+void port_notify_event(struct port *p, enum notification event)
+{
+       struct PortIdentity pid = port_identity(p);
+       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_construct(pid, p, 0, NULL, 1, GET);
+       if (!msg)
+               return;
+       if (!port_management_fill_response(p, msg, id))
+               goto err;
+       msg_len = msg->header.messageLength;
+       if (msg_pre_send(msg))
+               goto err;
+       clock_send_notification(p->clock, msg, msg_len, event);
+err:
+       msg_put(msg);
+}
+
 struct port *port_open(int phc_index,
                       enum timestamp_type timestamping,
                       int number,
diff --git a/port.h b/port.h
index 8d78370992ca..f4941ad8ac23 100644
--- a/port.h
+++ b/port.h
@@ -23,6 +23,7 @@
 #include "fd.h"
 #include "foreign.h"
 #include "fsm.h"
+#include "notification.h"
 #include "transport.h"
 
 /* forward declarations */
@@ -170,6 +171,14 @@ struct ptp_message *port_management_reply(struct 
PortIdentity pid,
                                          struct ptp_message *req);
 
 /**
+ * Construct and send notification to subscribers about an event that
+ * occured on the port.
+ * @param p        The port.
+ * @param event    The identification of the event.
+ */
+void port_notify_event(struct port *p, enum notification event);
+
+/**
  * Open a network port.
  * @param phc_index     The PHC device index for the network device.
  * @param timestamping  The timestamping mode for this port.
-- 
1.7.6.5


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to