Make some DHCP options and host discovery configurable

- Added broadcast option
- Made host discovery from DHCP configurable
- Some code cleanups

Change-Id: I42191c2fd17ef309c73a5382730d708686b835cd
diff --git a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
index 84eab6e..b200605 100644
--- a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
+++ b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
@@ -19,7 +19,6 @@
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.HostId;
 
-import java.util.List;
 import java.util.Map;
 
 
@@ -58,16 +57,12 @@
 
     /**
      * Registers a static IP mapping with the DHCP Server.
-     * Supports rangeNotEnforced option
      *
-     * @param macID macID of the client
-     * @param ipAddress IP Address requested for the client
-     * @param rangeNotEnforced true if rangeNotEnforced was set and the mapping will be eternal
-     * @param addressList subnetMask, DHCP/Router/DNS IP Addresses if rangeNotEnforced was set
+     * @param macAddress mac address to have a given ip assignment
+     * @param ipRequest ip address and dhcp options
      * @return true if the mapping was successfully added, false otherwise
      */
-    boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean rangeNotEnforced,
-                             List<Ip4Address> addressList);
+    boolean setStaticMapping(MacAddress macAddress, IpAssignment ipRequest);
 
     /**
      * Removes a static IP mapping with the DHCP Server.
diff --git a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
index c4be7ed..0b95e5a 100644
--- a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
+++ b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
@@ -19,7 +19,6 @@
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.HostId;
 
-import java.util.List;
 import java.util.Map;
 
 
@@ -41,7 +40,7 @@
      *
      * @param hostId Host ID of the client requesting an IP
      * @param requestedIP requested IP address
-     * @return IP address assigned to the Mac ID
+     * @return IP address assigned to the Mac address; null if no available IP
      */
     Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP);
 
@@ -50,14 +49,10 @@
      * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message.
      *
      * @param hostId Host Id of the client requesting an IP
-     * @param ipAddr IP Address being requested
-     * @param leaseTime Lease time offered by the server for this mapping
-     * @param rangeNotEnforced true if rangeNotEnforced was set
-     * @param addressList subnetMask, DHCP/Router/DNS IP Addresses if rangeNotEnforced was set
+     * @param ipAssignment ip assignment
      * @return returns true if the assignment was successful, false otherwise
      */
-    boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean rangeNotEnforced,
-                     List<Ip4Address> addressList);
+    boolean assignIP(HostId hostId, IpAssignment ipAssignment);
 
 
     /**
@@ -92,21 +87,19 @@
     /**
      * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time.
      *
-     * @param macID macID of the client
-     * @param ipAddr IP Address requested for the client
-     * @param rangeNotEnforced true if rangeNotEnforced was set
-     * @param addressList subnetMask, DHCP/Router/DNS IP Addresses rangeNotEnforced was set
+     * @param macAddress mac address of the client
+     * @param ipAssignment ip address and dhcp options requested for the client
      * @return true if the mapping was successfully registered, false otherwise
      */
-    boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean rangeNotEnforced, List<Ip4Address> addressList);
+    boolean assignStaticIP(MacAddress macAddress, IpAssignment ipAssignment);
 
     /**
      * Removes a static IP mapping associated with the given MAC ID from the DHCP Server.
      *
-     * @param macID macID of the client
+     * @param macAddress mac address of the client
      * @return true if the mapping was successfully registered, false otherwise
      */
-    boolean removeStaticIP(MacAddress macID);
+    boolean removeStaticIP(MacAddress macAddress);
 
     /**
      * Returns the list of all the available IPs with the server.
diff --git a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
index e9c286c..bbf0c00 100644
--- a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
+++ b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
@@ -27,22 +27,15 @@
  */
 public final class IpAssignment {
 
+    // TODO make some dhcp options optional
     private final Ip4Address ipAddress;
-
     private final Date timestamp;
-
     private final long leasePeriod;
-
     private final Ip4Address subnetMask;
-
+    private final Ip4Address broadcast;
     private final Ip4Address dhcpServer;
-
     private final Ip4Address routerAddress;
-
     private final Ip4Address domainServer;
-
-    private final boolean rangeNotEnforced;
-
     private final AssignmentStatus assignmentStatus;
 
     public enum AssignmentStatus {
@@ -52,8 +45,10 @@
         Option_Requested,
 
         /**
-         * IP Assignment has been requested by a OpenStack.
+         * Static IP Assignment with unregistered IP range.
+         * This assignment can only be added or removed by set or remove static mapping.
          */
+        // TODO allow multiple IP ranges and remove this option
         Option_RangeNotEnforced,
         /**
          * IP has been assigned to a host.
@@ -70,30 +65,34 @@
      * Constructor for IPAssignment, where the ipAddress, the lease period, the timestamp
      * and assignment status is supplied.
      *
-     * @param ipAddress
-     * @param leasePeriod
-     * @param timestamp
-     * @param assignmentStatus
-     * @param subnetMask
-     * @param dhcpServer
-     * @param routerAddress
-     * @param domainServer
-     * @param rangeNotEnforced
+     * @param ipAddress ip address to assign
+     * @param leasePeriod lease period
+     * @param timestamp time stamp of the assignment
+     * @param assignmentStatus statue of the assignment
+     * @param subnetMask subnet mask of assigned ip range
+     * @param broadcast broadcast address
+     * @param dhcpServer dhcp server address
+     * @param routerAddress router address
+     * @param domainServer domain server address
      */
     private IpAssignment(Ip4Address ipAddress,
                          long leasePeriod,
                          Date timestamp,
-                         AssignmentStatus assignmentStatus, Ip4Address subnetMask, Ip4Address dhcpServer,
-                         Ip4Address routerAddress, Ip4Address domainServer, boolean rangeNotEnforced) {
+                         AssignmentStatus assignmentStatus,
+                         Ip4Address subnetMask,
+                         Ip4Address broadcast,
+                         Ip4Address dhcpServer,
+                         Ip4Address routerAddress,
+                         Ip4Address domainServer) {
         this.ipAddress = ipAddress;
         this.leasePeriod = leasePeriod;
         this.timestamp = timestamp;
         this.assignmentStatus = assignmentStatus;
         this.subnetMask = subnetMask;
+        this.broadcast = broadcast;
         this.dhcpServer = dhcpServer;
         this.routerAddress = routerAddress;
         this.domainServer = domainServer;
-        this.rangeNotEnforced = rangeNotEnforced;
     }
 
     /**
@@ -141,26 +140,51 @@
         return (int) this.leasePeriod * 1000;
     }
 
+    /**
+     * Returns subnet mask of the IP assignment.
+     *
+     * @return subnet mask
+     */
     public Ip4Address subnetMask() {
         return subnetMask;
     }
 
+    /**
+     * Returns broadcast address of the IP assignment.
+     *
+     * @return broadcast address
+     */
+    public Ip4Address broadcast() {
+        return broadcast;
+    }
+
+    /**
+     * Returns dhcp server of the IP assignment.
+     *
+     * @return dhcp server ip address
+     */
     public Ip4Address dhcpServer() {
         return dhcpServer;
     }
 
+    /**
+     * Returns router address of the IP assignment.
+     *
+     * @return router ip address
+     */
     public Ip4Address routerAddress() {
         return routerAddress;
     }
 
+    /**
+     * Returns domain server address.
+     *
+     * @return domain server ip address
+     */
     public Ip4Address domainServer() {
         return domainServer;
     }
 
-    public boolean rangeNotEnforced() {
-        return rangeNotEnforced;
-    }
-
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
@@ -169,10 +193,10 @@
                 .add("lease", leasePeriod)
                 .add("assignmentStatus", assignmentStatus)
                 .add("subnetMask", subnetMask)
+                .add("broadcast", broadcast)
                 .add("dhcpServer", dhcpServer)
                 .add("routerAddress", routerAddress)
                 .add("domainServer", domainServer)
-                .add("rangeNotEnforced", rangeNotEnforced)
                 .toString();
     }
 
@@ -201,25 +225,16 @@
     public static final class Builder {
 
         private Ip4Address ipAddress;
-
         private Date timeStamp;
-
         private long leasePeriod;
-
         private AssignmentStatus assignmentStatus;
-
         private Ip4Address subnetMask;
-
+        private Ip4Address broadcast;
         private Ip4Address dhcpServer;
-
+        private Ip4Address routerAddress;
         private Ip4Address domainServer;
 
-        private Ip4Address routerAddress;
-
-        private boolean rangeNotEnforced = false;
-
         private Builder() {
-
         }
 
         private Builder(IpAssignment ipAssignment) {
@@ -227,12 +242,24 @@
             timeStamp = ipAssignment.timestamp();
             leasePeriod = ipAssignment.leasePeriod();
             assignmentStatus = ipAssignment.assignmentStatus();
+            subnetMask = ipAssignment.subnetMask();
+            broadcast = ipAssignment.broadcast();
+            dhcpServer = ipAssignment.dhcpServer();
+            routerAddress = ipAssignment.routerAddress();
+            domainServer = ipAssignment.domainServer();
         }
 
         public IpAssignment build() {
             validateInputs();
-            return new IpAssignment(ipAddress, leasePeriod, timeStamp, assignmentStatus, subnetMask,
-                    dhcpServer, routerAddress, domainServer, rangeNotEnforced);
+            return new IpAssignment(ipAddress,
+                                    leasePeriod,
+                                    timeStamp,
+                                    assignmentStatus,
+                                    subnetMask,
+                                    broadcast,
+                                    dhcpServer,
+                                    routerAddress,
+                                    domainServer);
         }
 
         public Builder ipAddress(Ip4Address addr) {
@@ -260,6 +287,11 @@
             return this;
         }
 
+        public Builder broadcast(Ip4Address broadcast) {
+            this.broadcast = broadcast;
+            return this;
+        }
+
         public Builder dhcpServer(Ip4Address dhcpServer) {
             this.dhcpServer = dhcpServer;
             return this;
@@ -275,25 +307,12 @@
             return this;
         }
 
-        public Builder rangeNotEnforced(boolean rangeNotEnforced) {
-            this.rangeNotEnforced = rangeNotEnforced;
-            return this;
-        }
-
-
         private void validateInputs() {
             checkNotNull(ipAddress, "IP Address must be specified");
             checkNotNull(assignmentStatus, "Assignment Status must be specified");
             checkNotNull(leasePeriod, "Lease Period must be specified");
             checkNotNull(timeStamp, "Timestamp must be specified");
 
-            if (rangeNotEnforced) {
-                checkNotNull(subnetMask, "subnetMask must be specified in case of rangeNotEnforced");
-                checkNotNull(dhcpServer, "dhcpServer must be specified in case of rangeNotEnforced");
-                checkNotNull(domainServer, "domainServer must be specified in case of rangeNotEnforced");
-                checkNotNull(routerAddress, "routerAddress must be specified in case of rangeNotEnforced");
-            }
-
             switch (assignmentStatus) {
                 case Option_Requested:
                 case Option_RangeNotEnforced: