From a1a8d72d91b1e5f00bc67611f6cd5d6de1f2e473 Mon Sep 17 00:00:00 2001
From: Srinivasan Ramasubramanian <srini@bigswitch.com>
Date: Tue, 9 Apr 2013 12:24:09 -0700
Subject: [PATCH] [BSC-3431] Introduce 'direction' as a field in LinkWithType. 
 The REST API will now return links with direction field that will indicate if
 the link bidirectional or unidirectional.

---
 .../linkdiscovery/ILinkDiscovery.java         | 15 ++++++
 .../web/ExternalLinksResource.java            | 37 ++++++++++++--
 .../linkdiscovery/web/LinkWithType.java       | 51 ++++++++++---------
 .../linkdiscovery/web/LinksResource.java      | 41 ++++++++++++---
 4 files changed, 110 insertions(+), 34 deletions(-)

diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
index 1e24d804e..a7d996d02 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
@@ -177,4 +177,19 @@ public interface ILinkDiscovery {
         	}
         }
     };
+
+    public enum LinkDirection {
+        UNIDIRECTIONAL {
+            @Override
+            public String toString() {
+                return "unidirectional";
+            }
+        },
+        BIDIRECTIONAL {
+            @Override
+            public String toString() {
+                return "bidirectional";
+            }
+        }
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/ExternalLinksResource.java b/src/main/java/net/floodlightcontroller/linkdiscovery/web/ExternalLinksResource.java
index 1553a8cc3..69b39eeab 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/ExternalLinksResource.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/web/ExternalLinksResource.java
@@ -21,6 +21,7 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkDirection;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkType;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.floodlightcontroller.linkdiscovery.LinkInfo;
@@ -44,12 +45,38 @@ public class ExternalLinksResource extends ServerResource {
                 LinkInfo info = links.get(link);
                 LinkType type = ld.getLinkType(link, info);
                 if (type == LinkType.MULTIHOP_LINK) {
-                    LinkWithType lwt = new LinkWithType(link,
-                                                        info.getSrcPortState(),
-                                                        info.getDstPortState(),
-                                                        type);
+                    LinkWithType lwt;
 
-                    returnLinkSet.add(lwt);
+                    long src = link.getSrc();
+                    long dst = link.getDst();
+                    short srcPort = link.getSrcPort();
+                    short dstPort = link.getDstPort();
+                    Link otherLink = new Link(dst, dstPort, src, srcPort);
+                    LinkInfo otherInfo = links.get(otherLink);
+                    LinkType otherType = null;
+                    if (otherInfo != null)
+                        otherType = ld.getLinkType(otherLink, otherInfo);
+                    if (otherType == LinkType.MULTIHOP_LINK) {
+                        // This is a bi-direcitonal link.
+                        // It is sufficient to add only one side of it.
+                        if ((src < dst) || (src == dst && srcPort < dstPort)) {
+                            lwt = new LinkWithType(link,
+                                    info.getSrcPortState(),
+                                    info.getDstPortState(),
+                                    type,
+                                    LinkDirection.BIDIRECTIONAL);
+                            returnLinkSet.add(lwt);
+                        }
+                    } else {
+                        // This is a unidirectional link.
+                        lwt = new LinkWithType(link,
+                                info.getSrcPortState(),
+                                info.getDstPortState(),
+                                type,
+                                LinkDirection.UNIDIRECTIONAL);
+                        returnLinkSet.add(lwt);
+
+                    }
                 }
             }
         }
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java b/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java
index dc859d338..a09cc12ab 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java
@@ -25,6 +25,7 @@ import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 import org.openflow.util.HexString;
 
+import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkDirection;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkType;
 import net.floodlightcontroller.routing.Link;
 
@@ -42,14 +43,16 @@ public class LinkWithType extends JsonSerializer<LinkWithType> {
     public short dstPort;
     public int dstPortState;
     public LinkType type;
+    public LinkDirection direction;
 
     // Do NOT delete this, it's required for the serializer
     public LinkWithType() {}
-    
+
     public LinkWithType(Link link,
-                        int srcPortState,
-                        int dstPortState,
-                        LinkType type) {
+            int srcPortState,
+            int dstPortState,
+            LinkType type,
+            LinkDirection direction) {
         this.srcSwDpid = link.getSrc();
         this.srcPort = link.getSrcPort();
         this.srcPortState = srcPortState;
@@ -57,25 +60,27 @@ public class LinkWithType extends JsonSerializer<LinkWithType> {
         this.dstPort = link.getDstPort();
         this.dstPortState = dstPortState;
         this.type = type;
+        this.direction = direction;
+    }
+
+    @Override
+    public void serialize(LinkWithType lwt, JsonGenerator jgen, SerializerProvider arg2)
+            throws IOException, JsonProcessingException {
+        // You ****MUST*** use lwt for the fields as it's actually a different object.
+        jgen.writeStartObject();
+        jgen.writeStringField("src-switch", HexString.toHexString(lwt.srcSwDpid));
+        jgen.writeNumberField("src-port", lwt.srcPort);
+        jgen.writeNumberField("src-port-state", lwt.srcPortState);
+        jgen.writeStringField("dst-switch", HexString.toHexString(lwt.dstSwDpid));
+        jgen.writeNumberField("dst-port", lwt.dstPort);
+        jgen.writeNumberField("dst-port-state", lwt.dstPortState);
+        jgen.writeStringField("type", lwt.type.toString());
+        jgen.writeStringField("direction", lwt.direction.toString());
+        jgen.writeEndObject();
     }
 
-	@Override
-	public void serialize(LinkWithType lwt, JsonGenerator jgen, SerializerProvider arg2) 
-			throws IOException, JsonProcessingException {
-		// You ****MUST*** use lwt for the fields as it's actually a different object.
-		jgen.writeStartObject();
-		jgen.writeStringField("src-switch", HexString.toHexString(lwt.srcSwDpid));
-		jgen.writeNumberField("src-port", lwt.srcPort);
-		jgen.writeNumberField("src-port-state", lwt.srcPortState);
-		jgen.writeStringField("dst-switch", HexString.toHexString(lwt.dstSwDpid));
-		jgen.writeNumberField("dst-port", lwt.dstPort);
-		jgen.writeNumberField("dst-port-state", lwt.dstPortState);
-		jgen.writeStringField("type", lwt.type.toString());
-		jgen.writeEndObject();
-	}
-	
-	@Override
-	public Class<LinkWithType> handledType() {
-		return LinkWithType.class;
-	}
+    @Override
+    public Class<LinkWithType> handledType() {
+        return LinkWithType.class;
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinksResource.java b/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinksResource.java
index 6f3f98d8a..c8edf4333 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinksResource.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinksResource.java
@@ -21,6 +21,7 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkDirection;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkType;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.floodlightcontroller.linkdiscovery.LinkInfo;
@@ -43,13 +44,41 @@ public class LinksResource extends ServerResource {
             for (Link link: links.keySet()) {
                 LinkInfo info = links.get(link);
                 LinkType type = ld.getLinkType(link, info);
-                LinkWithType lwt = new LinkWithType(link,
-                                                    info.getSrcPortState(),
-                                                    info.getDstPortState(),
-                                                    type);
+                if (type == LinkType.DIRECT_LINK || type == LinkType.TUNNEL) {
+                    LinkWithType lwt;
 
-                if (type == LinkType.DIRECT_LINK || type == LinkType.TUNNEL)
-                    returnLinkSet.add(lwt);
+                    long src = link.getSrc();
+                    long dst = link.getDst();
+                    short srcPort = link.getSrcPort();
+                    short dstPort = link.getDstPort();
+                    Link otherLink = new Link(dst, dstPort, src, srcPort);
+                    LinkInfo otherInfo = links.get(otherLink);
+                    LinkType otherType = null;
+                    if (otherInfo != null)
+                        otherType = ld.getLinkType(otherLink, otherInfo);
+                    if (otherType == LinkType.DIRECT_LINK ||
+                            otherType == LinkType.TUNNEL) {
+                        // This is a bi-direcitonal link.
+                        // It is sufficient to add only one side of it.
+                        if ((src < dst) || (src == dst && srcPort < dstPort)) {
+                            lwt = new LinkWithType(link,
+                                    info.getSrcPortState(),
+                                    info.getDstPortState(),
+                                    type,
+                                    LinkDirection.BIDIRECTIONAL);
+                            returnLinkSet.add(lwt);
+                        }
+                    } else {
+                        // This is a unidirectional link.
+                        lwt = new LinkWithType(link,
+                                info.getSrcPortState(),
+                                info.getDstPortState(),
+                                type,
+                                LinkDirection.UNIDIRECTIONAL);
+                        returnLinkSet.add(lwt);
+
+                    }
+                }
             }
         }
         return returnLinkSet;
-- 
GitLab