[SEBA-937] Multi Tcont support by DhcpL2Relay app.

Change-Id: Id9b8e4b507e5608a92a040b72c8d497cc5783ba8
diff --git a/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java b/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java
index 7bdd9c5..ba4bf1a 100755
--- a/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java
+++ b/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java
@@ -96,6 +96,7 @@
 import org.opencord.sadis.BaseInformationService;
 import org.opencord.sadis.SadisService;
 import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.UniTagInformation;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -231,7 +232,6 @@
         }
 
         publishCountersToKafka = new PublishCountersToKafka();
-        subsService = sadisService.getSubscriberInfoService();
         restartPublishCountersTask();
 
         log.info("DHCP-L2-RELAY Started");
@@ -568,13 +568,6 @@
         return subsService.get(serialNo);
     }
 
-    private SubscriberAndDeviceInformation getDevice(ConnectPoint cp) {
-        String serialNo = deviceService.getDevice(cp.deviceId()).
-                serialNumber();
-
-        return subsService.get(serialNo);
-    }
-
     private MacAddress relayAgentMacAddress(PacketContext context) {
 
         SubscriberAndDeviceInformation device = this.getDevice(context);
@@ -600,44 +593,19 @@
         return subsService.get(nasPortId(context));
     }
 
-    private VlanId cTag(PacketContext context) {
-        SubscriberAndDeviceInformation sub = getSubscriber(context);
-        if (sub == null) {
-            log.warn("Subscriber info not found for {}", context.inPacket().
-                    receivedFrom());
-            return VlanId.NONE;
+    private UniTagInformation getUnitagInformationFromPacketContext(PacketContext context,
+                                                                    SubscriberAndDeviceInformation sub) {
+        //If the ctag is defined in the tagList and dhcp is required, return the service info
+        List<UniTagInformation> tagList = sub.uniTagList();
+        for (UniTagInformation uniServiceInformation : tagList) {
+            if (uniServiceInformation.getPonCTag().toShort() == context.inPacket().parsed().getVlanID()) {
+                if (uniServiceInformation.getIsDhcpRequired()) {
+                    return uniServiceInformation;
+                }
+            }
         }
-        return sub.cTag();
-    }
 
-    private VlanId cTag(ConnectPoint cp) {
-        String portId = nasPortId(cp);
-        SubscriberAndDeviceInformation sub = subsService.get(portId);
-        if (sub == null) {
-            log.warn("Subscriber info not found for {} looking for C-TAG", cp);
-            return VlanId.NONE;
-        }
-        return sub.cTag();
-    }
-
-    private VlanId sTag(ConnectPoint cp) {
-        String portId = nasPortId(cp);
-        SubscriberAndDeviceInformation sub = subsService.get(portId);
-        if (sub == null) {
-            log.warn("Subscriber info not found for {} looking for S-TAG", cp);
-            return VlanId.NONE;
-        }
-        return sub.sTag();
-    }
-
-    private VlanId sTag(PacketContext context) {
-        SubscriberAndDeviceInformation sub = getSubscriber(context);
-        if (sub == null) {
-            log.warn("Subscriber info not found for {}", context.inPacket().
-                    receivedFrom());
-            return VlanId.NONE;
-        }
-        return sub.sTag();
+        return null;
     }
 
     private class DhcpRelayPacketProcessor implements PacketProcessor {
@@ -739,10 +707,10 @@
         /*
          * Get subscriber information based on it's DHCP payload.
          */
-        private SubscriberAndDeviceInformation getSubscriberInfoFromServer(DHCP dhcpPayload) {
+        private SubscriberAndDeviceInformation getSubscriberInfoFromServer(DHCP dhcpPayload, PacketContext context) {
             if (dhcpPayload != null) {
                 MacAddress descMac = valueOf(dhcpPayload.getClientHardwareAddress());
-                ConnectPoint subsCp = getConnectPointOfClient(descMac);
+                ConnectPoint subsCp = getConnectPointOfClient(descMac, context);
 
                 if (subsCp != null) {
                     String portId = nasPortId(subsCp);
@@ -792,9 +760,9 @@
                     Ethernet ethernetPacketOffer =
                             processDhcpPacketFromServer(context, packet);
                     if (ethernetPacketOffer != null) {
-                        sendReply(ethernetPacketOffer, dhcpPayload);
+                        sendReply(ethernetPacketOffer, dhcpPayload, context);
                     }
-                    entry = getSubscriberInfoFromServer(dhcpPayload);
+                    entry = getSubscriberInfoFromServer(dhcpPayload, context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounters.valueOf("DHCPOFFER"));
                     break;
                 case DHCPREQUEST:
@@ -811,9 +779,9 @@
                     Ethernet ethernetPacketAck =
                             processDhcpPacketFromServer(context, packet);
                     if (ethernetPacketAck != null) {
-                        sendReply(ethernetPacketAck, dhcpPayload);
+                        sendReply(ethernetPacketAck, dhcpPayload, context);
                     }
-                    entry = getSubscriberInfoFromServer(dhcpPayload);
+                    entry = getSubscriberInfoFromServer(dhcpPayload, context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounters.valueOf("DHCPACK"));
                     break;
                 case DHCPDECLINE:
@@ -821,7 +789,7 @@
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounters.valueOf("DHCPDECLINE"));
                     break;
                 case DHCPNAK:
-                    entry = getSubscriberInfoFromServer(dhcpPayload);
+                    entry = getSubscriberInfoFromServer(dhcpPayload, context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounters.valueOf("DHCPNACK"));
                     break;
                 case DHCPRELEASE:
@@ -866,6 +834,14 @@
                 return null;
             }
 
+            UniTagInformation uniTagInformation = getUnitagInformationFromPacketContext(context, entry);
+            if (uniTagInformation == null) {
+                log.warn("Missing service information for connectPoint {} / cTag {}",
+                        context.inPacket().receivedFrom(),  context.inPacket().parsed().getVlanID());
+                return null;
+            }
+
+
             DhcpAllocationInfo info = new DhcpAllocationInfo(
                     context.inPacket().receivedFrom(), dhcpPacket.getPacketType(),
                     entry.nasPortId(), clientMac, clientIp);
@@ -888,10 +864,13 @@
             }
 
             etherReply.setPriorityCode(ethernetPacket.getPriorityCode());
-            etherReply.setVlanID(cTag(context).toShort());
+            etherReply.setVlanID(uniTagInformation.getPonCTag().toShort());
             etherReply.setQinQTPID(Ethernet.TYPE_VLAN);
-            etherReply.setQinQVID(sTag(context).toShort());
-            log.info("Finished processing packet.. relaying to dhcpServer");
+            etherReply.setQinQVID(uniTagInformation.getPonSTag().toShort());
+            if (uniTagInformation.getUsPonSTagPriority() != -1) {
+                etherReply.setQinQPriorityCode((byte) uniTagInformation.getUsPonSTagPriority());
+            }
+            log.info("Finished processing packet.. relaying to dhcpServer {}");
             return etherReply;
         }
 
@@ -909,7 +888,7 @@
             DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
 
             MacAddress dstMac = valueOf(dhcpPayload.getClientHardwareAddress());
-            ConnectPoint subsCp = getConnectPointOfClient(dstMac);
+            ConnectPoint subsCp = getConnectPointOfClient(dstMac, context);
             // If we can't find the subscriber, can't process further
             if (subsCp == null) {
                 log.warn("Couldn't find connection point for mac address {} DHCPOFFERs won't be delivered", dstMac);
@@ -948,14 +927,25 @@
                 }
             } // end storing of info
 
-            SubscriberAndDeviceInformation entry = getSubscriberInfoFromServer(dhcpPayload);
+            SubscriberAndDeviceInformation entry = getSubscriberInfoFromServer(dhcpPayload, context);
+
+            UniTagInformation uniTagInformation = getUnitagInformationFromPacketContext(context, entry);
+            if (uniTagInformation == null) {
+                log.warn("Missing service information for connectPoint {} / cTag {}",
+                        context.inPacket().receivedFrom(),  context.inPacket().parsed().getVlanID());
+                return null;
+            }
+
             updateDhcpRelayCountersStore(entry, DhcpL2RelayCounters.valueOf("PACKETS_FROM_SERVER"));
 
             // we leave the srcMac from the original packet
+            etherReply.setQinQVID(VlanId.NO_VID);
+            etherReply.setQinQPriorityCode((byte) 0);
             etherReply.setDestinationMACAddress(dstMac);
-            etherReply.setQinQVID(sTag(subsCp).toShort());
-            etherReply.setPriorityCode(ethernetPacket.getPriorityCode());
-            etherReply.setVlanID((cTag(subsCp).toShort()));
+            etherReply.setVlanID(uniTagInformation.getPonCTag().toShort());
+            if (uniTagInformation.getUsPonCTagPriority() != -1) {
+                etherReply.setPriorityCode((byte) uniTagInformation.getUsPonCTagPriority());
+            }
 
             if (option82) {
                 udpPacket.setPayload(removeOption82(dhcpPayload));
@@ -972,7 +962,7 @@
         /*
          * Get ConnectPoint of the Client based on it's MAC address
          */
-        private ConnectPoint getConnectPointOfClient(MacAddress dstMac) {
+        private ConnectPoint getConnectPointOfClient(MacAddress dstMac, PacketContext context) {
             Set<Host> hosts = hostService.getHostsByMac(dstMac);
             if (hosts == null || hosts.isEmpty()) {
                 log.warn("Cannot determine host for DHCP client: {}. Aborting "
@@ -986,18 +976,28 @@
                 ConnectPoint cp = new ConnectPoint(h.location().deviceId(),
                         h.location().port());
 
-                if (sTag(cp) != VlanId.NONE) {
-                    return cp;
+                String portId = nasPortId(cp);
+                SubscriberAndDeviceInformation sub = subsService.get(portId);
+                if (sub == null) {
+                    log.warn("Subscriber info not found for {}", cp);
+                    return null;
                 }
-            }
 
+                UniTagInformation uniTagInformation = getUnitagInformationFromPacketContext(context, sub);
+                if (uniTagInformation == null) {
+                    log.warn("Missing service information for connectPoint {} / cTag {}",
+                            context.inPacket().receivedFrom(),  context.inPacket().parsed().getVlanID());
+                    return null;
+                }
+                return cp;
+            }
             return null;
         }
 
         //send the response to the requester host.
-        private void sendReply(Ethernet ethPacket, DHCP dhcpPayload) {
+        private void sendReply(Ethernet ethPacket, DHCP dhcpPayload, PacketContext context) {
             MacAddress descMac = valueOf(dhcpPayload.getClientHardwareAddress());
-            ConnectPoint subCp = getConnectPointOfClient(descMac);
+            ConnectPoint subCp = getConnectPointOfClient(descMac, context);
 
             // Send packet out to requester if the host information is available
             if (subCp != null) {