diff --git a/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java b/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
new file mode 100644
index 0000000..e673674
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
@@ -0,0 +1,360 @@
+package net.onrc.onos.core.devicemanager;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFMessageListener;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IUpdate;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.datagrid.IDatagridService;
+import net.onrc.onos.core.datagrid.IEventChannel;
+import net.onrc.onos.core.datagrid.IEventChannelListener;
+import net.onrc.onos.packet.ARP;
+import net.onrc.onos.packet.DHCP;
+import net.onrc.onos.packet.Ethernet;
+import net.onrc.onos.packet.IPv4;
+import net.onrc.onos.packet.UDP;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OnosDeviceManager implements IFloodlightModule,
+					  IOFMessageListener,
+					  IOnosDeviceService,
+					  IEventChannelListener<Long, OnosDevice> {
+	protected final static Logger log = LoggerFactory.getLogger(OnosDeviceManager.class);
+	private static final int CLEANUP_SECOND = 60*60;
+	private static final int AGEING_MILLSEC = 60*60*1000;
+
+	private CopyOnWriteArrayList<IOnosDeviceListener> deviceListeners;
+	private IFloodlightProviderService floodlightProvider;
+	private final static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+
+	private IDatagridService datagrid;
+	private IEventChannel<Long, OnosDevice> eventChannel;
+	private static final String DEVICE_CHANNEL_NAME = "onos.device";
+	private Map<Long, OnosDevice> mapDevice = new ConcurrentHashMap<Long, OnosDevice>();
+	private INetworkGraphService networkGraphService;
+	private NetworkGraph networkGraph;
+
+    public enum OnosDeviceUpdateType {
+        ADD, DELETE, UPDATE;
+    }
+
+	private class OnosDeviceUpdate implements IUpdate {
+		private OnosDevice device;
+		private OnosDeviceUpdateType type;
+
+		public OnosDeviceUpdate(OnosDevice device, OnosDeviceUpdateType type) {
+			this.device = device;
+			this.type = type;
+		}
+
+		@Override
+		public void dispatch() {
+			if(type == OnosDeviceUpdateType.ADD) {
+				for(IOnosDeviceListener listener: deviceListeners) {
+					listener.onosDeviceAdded(device);
+				}
+			} else if (type == OnosDeviceUpdateType.DELETE){
+				for(IOnosDeviceListener listener: deviceListeners) {
+					listener.onosDeviceRemoved(device);
+				}
+			}
+		}
+	}
+
+	@Override
+	public String getName() {
+		return "onosdevicemanager";
+	}
+
+	@Override
+	public boolean isCallbackOrderingPrereq(OFType type, String name) {
+		// We want link discovery to consume LLDP first otherwise we'll
+		// end up reading bad device info from LLDP packets
+		return type == OFType.PACKET_IN && "linkdiscovery".equals(name);
+	}
+
+	@Override
+	public boolean isCallbackOrderingPostreq(OFType type, String name) {
+		return type == OFType.PACKET_IN &&
+				("proxyarpmanager".equals(name) || "onosforwarding".equals(name));
+	}
+
+	@Override
+	public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
+		if (msg.getType().equals(OFType.PACKET_IN)) {
+			OFPacketIn pi = (OFPacketIn) msg;
+
+			Ethernet eth = IFloodlightProviderService.bcStore.
+					get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+
+			return processPacketIn(sw, pi, eth);
+		}
+
+		return Command.CONTINUE;
+	}
+
+	private Command processPacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
+        long dpid =sw.getId();
+        short portId = pi.getInPort();
+        Long mac = eth.getSourceMAC().toLong();
+
+        OnosDevice srcDevice =
+                getSourceDeviceFromPacket(eth, dpid, portId);
+
+        if (srcDevice == null){
+        	return Command.STOP;
+        }
+
+        //We check if it is the same device in datagrid to suppress the device update
+        OnosDevice exDev = null;
+        if((exDev = mapDevice.get(mac)) != null ){
+	    	if(exDev.equals(srcDevice)) {
+	    		//There is the same existing device. Update only ActiveSince time.
+	        	exDev.setLastSeenTimestamp(new Date());
+	        	if(log.isTraceEnabled()) {
+			        log.debug("In the datagrid, there is the same device."
+							+ "Only update last seen time. dpid {}, port {}, mac {}, ip {}, lastSeenTime {}",
+			        		dpid, portId, srcDevice.getMacAddress(), srcDevice.getIpv4Address(), srcDevice.getLastSeenTimestamp().getTime());
+	        	}
+		        return Command.CONTINUE;
+	    	} else if (srcDevice.getIpv4Address() == null &&
+	    			exDev.getSwitchDPID().equals(srcDevice.getSwitchDPID()) &&
+	    			exDev.getSwitchPort() == srcDevice.getSwitchPort()) {
+	    			//Vlan should be handled based on the Onos spec. Until then, don't handle it.
+		    		//Device attachment point and mac address are the same
+		    		//but the packet does not have an ip address.
+		        	exDev.setLastSeenTimestamp(new Date());
+		        	if(log.isTraceEnabled()) {
+			        	log.debug("In the datagrid, there is the same device with no ip."
+								+ "Keep ip and update last seen time. dpid {}, port {}, mac {}, ip {} lastSeenTime {}",
+								dpid, portId, srcDevice.getMacAddress(), exDev.getIpv4Address(), srcDevice.getLastSeenTimestamp().getTime());
+		        	}
+		        	return Command.CONTINUE;
+	    		}
+	    	}
+
+        //If the switch port we try to attach a new device already has a link, then stop adding device
+        if(networkGraph.getLink(dpid, (long)portId) != null) {
+			if(log.isTraceEnabled()) {
+    			log.debug("Stop adding OnosDevice {} due to there is a link to: dpid {} port {}",
+						srcDevice.getMacAddress(), dpid, portId);
+			}
+			return Command.CONTINUE;
+        }
+
+        addOnosDevice(mac, srcDevice);
+
+        if(log.isTraceEnabled()) {
+	        log.debug("Add device info in the set. dpid {}, port {}, mac {}, ip {}, lastSeenTime {}",
+	       		dpid, portId, srcDevice.getMacAddress(), srcDevice.getIpv4Address(), srcDevice.getLastSeenTimestamp().getTime());
+        }
+        return Command.CONTINUE;
+	}
+
+     //Thread to delete devices periodically.
+	 //Remove all devices from the map first and then finally delete devices from the DB.
+	private class CleanDevice implements Runnable {
+		@Override
+		public void run() {
+			log.debug("called CleanDevice");
+			try{
+		        	Set<OnosDevice> deleteSet = new HashSet<OnosDevice>();
+			        for (OnosDevice dev : mapDevice.values() ) {
+			        	long now = new Date().getTime();
+			        	if((now - dev.getLastSeenTimestamp().getTime() > AGEING_MILLSEC)) {
+			        		if(log.isTraceEnabled()) {
+			        			log.debug("Remove device info in the datagrid. dpid {}, port {}, mac {}, ip {}, lastSeenTime {}, diff {}",
+				        				dev.getSwitchDPID(), dev.getSwitchPort(), dev.getMacAddress(), dev.getIpv4Address(),
+				        				dev.getLastSeenTimestamp().getTime(), now - dev.getLastSeenTimestamp().getTime());
+			        		}
+			        		deleteSet.add(dev);
+			        	}
+			        }
+
+			        for(OnosDevice dev : deleteSet) {
+			        	deleteOnosDevice(dev);
+			        }
+			 } catch(Exception e) {
+		    	 log.error("Error:", e);
+		     }
+		}
+	}
+
+    /**
+     * Get IP address from packet if the packet is either an ARP
+     * or a DHCP packet
+     * @param eth
+     * @param dlAddr
+     * @return
+     */
+    private int getSrcNwAddr(Ethernet eth, long dlAddr) {
+        if (eth.getPayload() instanceof ARP) {
+            ARP arp = (ARP) eth.getPayload();
+            if ((arp.getProtocolType() == ARP.PROTO_TYPE_IP) &&
+                    (Ethernet.toLong(arp.getSenderHardwareAddress()) == dlAddr)) {
+                return IPv4.toIPv4Address(arp.getSenderProtocolAddress());
+            }
+        } else if (eth.getPayload() instanceof IPv4) {
+            IPv4 ipv4 = (IPv4) eth.getPayload();
+            if (ipv4.getPayload() instanceof UDP) {
+                UDP udp = (UDP)ipv4.getPayload();
+                if (udp.getPayload() instanceof DHCP) {
+                    DHCP dhcp = (DHCP)udp.getPayload();
+                    if (dhcp.getOpCode() == DHCP.OPCODE_REPLY) {
+                        return ipv4.getSourceAddress();
+                    }
+                }
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Parse an entity from an {@link Ethernet} packet.
+     * @param eth the packet to parse
+     * @param sw the switch on which the packet arrived
+     * @param pi the original packetin
+     * @return the entity from the packet
+     */
+    private OnosDevice getSourceDeviceFromPacket(Ethernet eth,
+                                             long swdpid,
+                                             short port) {
+        byte[] dlAddrArr = eth.getSourceMACAddress();
+        long dlAddr = Ethernet.toLong(dlAddrArr);
+
+        // Ignore broadcast/multicast source
+        if ((dlAddrArr[0] & 0x1) != 0)
+            return null;
+
+        short vlan = eth.getVlanID();
+        int nwSrc = getSrcNwAddr(eth, dlAddr);
+        return new OnosDevice(MACAddress.valueOf(dlAddr),
+                          ((vlan >= 0) ? vlan : null),
+                          ((nwSrc != 0) ? nwSrc : null),
+                          swdpid,
+                          port,
+                          new Date());
+    }
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+		List<Class<? extends IFloodlightService>> services =
+				new ArrayList<Class<? extends IFloodlightService>>();
+		services.add(IOnosDeviceService.class);
+		return services;
+	}
+
+	@Override
+	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+		Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
+				new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+		impls.put(IOnosDeviceService.class, this);
+		return impls;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+		List<Class<? extends IFloodlightService>> dependencies =
+				new ArrayList<Class<? extends IFloodlightService>>();
+		dependencies.add(IFloodlightProviderService.class);
+		dependencies.add(INetworkGraphService.class);
+		dependencies.add(IDatagridService.class);
+		return dependencies;
+	}
+
+	@Override
+	public void init(FloodlightModuleContext context)
+			throws FloodlightModuleException {
+		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+		executor.scheduleAtFixedRate(new CleanDevice(), 30 ,CLEANUP_SECOND, TimeUnit.SECONDS);
+
+		deviceListeners = new CopyOnWriteArrayList<IOnosDeviceListener>();
+		datagrid = context.getServiceImpl(IDatagridService.class);
+		networkGraphService = context.getServiceImpl(INetworkGraphService.class);
+		networkGraph = networkGraphService.getNetworkGraph();
+	}
+
+	@Override
+	public void startUp(FloodlightModuleContext context) {
+		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+		eventChannel = datagrid.addListener(DEVICE_CHANNEL_NAME, this,
+						    Long.class,
+						    OnosDevice.class);
+	}
+
+    @Override
+	public void deleteOnosDevice(OnosDevice dev) {
+	    Long mac = dev.getMacAddress().toLong();
+	    eventChannel.removeEntry(mac);
+	    floodlightProvider.publishUpdate(new OnosDeviceUpdate(dev, OnosDeviceUpdateType.DELETE));
+	}
+    
+    @Override
+	public void deleteOnosDeviceByMac(MACAddress mac) {
+    	OnosDevice deleteDevice = mapDevice.get(mac);
+    	deleteOnosDevice(deleteDevice);
+	}
+	
+	@Override
+	public void addOnosDevice(Long mac, OnosDevice dev) {
+	    eventChannel.addEntry(mac, dev);
+	    floodlightProvider.publishUpdate(new OnosDeviceUpdate(dev, OnosDeviceUpdateType.ADD));
+	}
+
+	@Override
+	public void entryAdded(OnosDevice dev) {
+	    Long mac = dev.getMacAddress().toLong();
+	    mapDevice.put(mac, dev);
+	    log.debug("Device added: device mac {}", mac);
+	}
+
+	@Override
+	public void entryRemoved(OnosDevice dev) {
+	    Long mac = dev.getMacAddress().toLong();
+	    mapDevice.remove(mac);
+	    log.debug("Device removed: device mac {}", mac);
+	}
+
+	@Override
+	public void entryUpdated(OnosDevice dev) {
+	    Long mac = dev.getMacAddress().toLong();
+	    mapDevice.put(mac, dev);
+	    log.debug("Device updated: device mac {}", mac);
+	}
+
+	@Override
+	public void addOnosDeviceListener(IOnosDeviceListener listener) {
+		deviceListeners.add(listener);
+	}
+
+	@Override
+	public void deleteOnosDeviceListener(IOnosDeviceListener listener) {
+		deviceListeners.remove(listener);
+	}
+}
