Cherry-pick from https://gerrit.onos.onlab.us/#/c/338/

Lower the frequency of bug that PacketIn doesn't occur. (ONOS-1002)

Fixed a bug ProxyArpManager frequently deletes device from DB.

Change-Id: Ida1f8e36dee201b8d8dbd40325a2ee4a5c8736be

Fix compilation failure.

Change-Id: I0c3e253c6caa6f6b5315b30f2a647bb45d9c6b36
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index c7d495c..fd21265 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -87,22 +87,21 @@
 	private static class ArpRequest {
 		private final IArpRequester requester;
 		private final boolean retry;
+		private boolean sent = false;
 		private long requestTime;
 		
 		public ArpRequest(IArpRequester requester, boolean retry){
 			this.requester = requester;
 			this.retry = retry;
-			this.requestTime = System.currentTimeMillis();
 		}
 		
 		public ArpRequest(ArpRequest old) {
 			this.requester = old.requester;
 			this.retry = old.retry;
-			this.requestTime = System.currentTimeMillis();
 		}
 		
 		public boolean isExpired() {
-			return (System.currentTimeMillis() - requestTime) > ARP_REQUEST_TIMEOUT;
+			return sent && ((System.currentTimeMillis() - requestTime) > ARP_REQUEST_TIMEOUT);
 		}
 		
 		public boolean shouldRetry() {
@@ -112,6 +111,11 @@
 		public void dispatchReply(InetAddress ipAddress, MACAddress replyMacAddress) {
 			requester.arpResponse(ipAddress, replyMacAddress);
 		}
+		
+		public void setRequestTime() {
+			this.requestTime = System.currentTimeMillis();
+			this.sent = true;
+		}
 	}
 	
 	private class HostArpRequester implements IArpRequester {
@@ -355,8 +359,8 @@
 			
 			// We don't know the device so broadcast the request out
 			datagrid.sendPacketOutNotification(
-					new BroadcastPacketOutNotification(eth.serialize(), 
-							sw.getId(), pi.getInPort()));
+					new BroadcastPacketOutNotification(eth.serialize(),
+							target, sw.getId(), pi.getInPort()));
 		}
 		else {
 			// Even if the device exists in our database, we do not reply to
@@ -383,7 +387,7 @@
 				
 				datagrid.sendPacketOutNotification(
 						new BroadcastPacketOutNotification(eth.serialize(), 
-								sw.getId(), pi.getInPort()));
+								target, sw.getId(), pi.getInPort()));
 			} 
 			else {
 				for (IPortObject portObject : outPorts) {
@@ -410,7 +414,7 @@
 					
 					datagrid.sendPacketOutNotification(
 							new SinglePacketOutNotification(eth.serialize(), 
-									outSwitch, outPort));
+									target, outSwitch, outPort));
 				}
 			}
 		}
@@ -504,7 +508,8 @@
 		}
 		
 		//sendArpRequestToSwitches(ipAddress, eth.serialize());
-		datagrid.sendPacketOutNotification(new SinglePacketOutNotification(eth.serialize(),intf.getDpid(),intf.getPort()));
+		datagrid.sendPacketOutNotification(new SinglePacketOutNotification(eth.serialize(),
+				ipAddress, intf.getDpid(),intf.getPort()));
 	}
 	
 	private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest) {
@@ -854,12 +859,28 @@
 					(SinglePacketOutNotification) packetOutNotification;
 			sendArpRequestOutPort(notification.packet, notification.getOutSwitch(), 
 					notification.getOutPort());
+			
+			// set timestamp
+			InetAddress addr = notification.getTargetAddress();
+			if (addr != null) {
+				for (ArpRequest request : arpRequests.get(addr)) {
+					request.setRequestTime();
+				}
+			}
 		}
 		else if (packetOutNotification instanceof BroadcastPacketOutNotification) {
 			BroadcastPacketOutNotification notification = 
 					(BroadcastPacketOutNotification) packetOutNotification;
 			broadcastArpRequestOutMyEdge(notification.packet, 
 					notification.getInSwitch(), notification.getInPort());
+			
+			// set timestamp
+			InetAddress addr = notification.getTargetAddress();
+			if (addr != null) {
+				for (ArpRequest request : arpRequests.get(addr)) {
+					request.setRequestTime();
+				}
+			}
 		}
 		else {
 			log.warn("Unknown packet out notification received");