diff --git a/src/core/DTNHost.java b/src/core/DTNHost.java index 258be0450..d471572d6 100644 --- a/src/core/DTNHost.java +++ b/src/core/DTNHost.java @@ -537,5 +537,29 @@ public boolean equals(DTNHost otherHost) { public int compareTo(DTNHost h) { return this.getAddress() - h.getAddress(); } + /** + * @return the angle in degrees[0-360) between the current host and h + * @param h the Host + */ + public double getAngleofHost(DTNHost h){ + double dy = (h.getLocation().getY() - this.getLocation().getY()); + double dx = (h.getLocation().getX() - this.getLocation().getX()); + if(dx == 0){ + if (dy > 0) { + return 90; + } + else{ + return 270; + } + } + else{ + double inDeg = (float)(Math.atan2(dy,dx)*180)/(float)Math.PI; + if( inDeg < 0){ + return 2*180 + inDeg; + } + return inDeg; + } + + } } diff --git a/src/core/Message.java b/src/core/Message.java index d037b890b..c1a7792c7 100644 --- a/src/core/Message.java +++ b/src/core/Message.java @@ -18,6 +18,10 @@ public class Message implements Comparable { public static final int INFINITE_TTL = -1; private DTNHost from; private DTNHost to; + /** Type of the message*/ + private int msgType; + /**No of Local hops*/ + private int localHops; /** Identifier of the message */ private String id; /** Size of the message (bytes) */ @@ -359,5 +363,29 @@ public String getAppID() { public void setAppID(String appID) { this.appID = appID; } + /** + * @return the msgType + */ + public int getMsgType(){ + return this.msgType; + } + /** + * @param mType the msgType to set + */ + public void setMsgType(int mType){ + this.msgType = mType; + } + /** + * @return the localHops + */ + public int getLocalHops(){ + return this.localHops; + } + /** + * @param nh the localhops to set + */ + public void setLocalHops(int nh){ + this.localHops = nh; + } } diff --git a/src/routing/GreedyGeoRouter.java b/src/routing/GreedyGeoRouter.java new file mode 100644 index 000000000..fece70754 --- /dev/null +++ b/src/routing/GreedyGeoRouter.java @@ -0,0 +1,233 @@ +/* +Author : Satya Vasanth Reddy +*/ +package routing; + +import java.lang.Math; +import core.Settings; +import java.lang.*; +import java.util.*; +import core.Application; +import core.Connection; +import core.DTNHost; +import core.Message; +import core.MessageListener; +import core.SettingsError; +import core.SimClock; +import core.SimError; +import java.util.AbstractMap.SimpleEntry; + +public class GreedyGeoRouter extends ActiveRouter { + public static final int PROXIMITY_THRESHOLD = 15; + //This is the collection of DTNHosts in each of the six sectors around the router + private Map> > sectorMap; + + public GreedyGeoRouter(Settings s) { + super(s); + } + + protected GreedyGeoRouter(GreedyGeoRouter r) { + super(r); + this.sectorMap = new HashMap> >(); + } + + @Override + public void update() { + + super.update(); + if (exchangeDeliverableMessages() != null) { + return; // started a transfer, don't try others (yet) + } + //Update the Sector Map + updateSectorMap(); + List messages = + new ArrayList(this.getMessageCollection()); + if(messages.size()>0) + { + startProtocol(messages); + } + } + + + @Override + public GreedyGeoRouter replicate() { + return new GreedyGeoRouter(this); + } + /** + *Returns the Eucledian distance between two hosts + *@param Host1 + *@param Host2 + */ + public double getDistance(DTNHost h1,DTNHost h2){ + double dx = h1.getLocation().getX() - h2.getLocation().getX(); + double dy = h1.getLocation().getY() - h2.getLocation().getY(); + return Math.sqrt(dx*dx + dy*dy); + } + /** + *Returns the sector number of Host2 in clock-wise direction relative to the Host + *@param Host2 + */ + public int getSector(DTNHost h2){ + DTNHost h1 = getHost(); + return (int)(h1.getAngleofHost(h2)/60); + } + + public void updateSectorMap(){ + sectorMap = new HashMap> >(); + DTNHost to; + int sector; + DTNHost h = getHost(); + + for (Connection con : getConnections()) { + + to = con.getOtherNode(getHost()); + sector = getSector(to); + if (!sectorMap.containsKey(sector)){ + sectorMap.put(sector, new HashSet>()); + } + sectorMap.get(sector).add(new AbstractMap.SimpleEntry(to, con)); + } + + } + /** + *Returns the AbstractMap.SimpleEntry of Host and Connection information closer to the destination in a given sector + *@param Destination Host + *@param sector number of the destination relative to current host + *@param The distance between current host and destination + */ + public AbstractMap.SimpleEntry getACloserHostFromSector(DTNHost destination, int sector, int maxD){ + //System.out.println("getACloserHostFromSector: sector "+sector+", destination "+destination.getAddress()); + Collection> sectorList = sectorMap.get(sector); + DTNHost h ; + Connection con ; + if(sectorList==null){ + return null; + } + for(AbstractMap.SimpleEntry entry : sectorList){ + h = entry.getKey(); + con = entry.getValue(); + if(getDistance(h, destination) <= maxD){ + return entry; + } + } + return null; + } + /** + *Returns the AbstractMap.SimpleEntry of Host and Connection information closer to the destination. + *@param Destination Host + */ + + public AbstractMap.SimpleEntry getACloserHost(DTNHost destination){ + int sector = getSector(destination); + int sl,sr; + int maxD = (int)getDistance(getHost(), destination); + AbstractMap.SimpleEntry retVal; + //System.out.println("getACloserHost "+maxD); + for(int i=0;i<3;i++){ + sl = (sector + i)%6; + sr = (sector +6 - i)%6; + retVal = getACloserHostFromSector(destination, sl, maxD); + if(retVal != null){ + return retVal; + } + if(sl != sr){ + retVal = getACloserHostFromSector(destination, sr, maxD); + if(retVal != null){ + return retVal; + } + } + } + return null; + } + /** + *Returns if the destination has a connection with the current host + *@param Destination Host + */ + + public Connection isDestinationConnected(DTNHost d){ + DTNHost n; + //System.out.println("isDestinationConnected "+d.getAddress()); + for (Connection con : getConnections()) { + n = con.getOtherNode(getHost()); + if (d.compareTo(n) == 0){ + //System.out.println("DTNHost is connected"); + return con; + } + } + return null; + } + /** + *Returns if the destination is closer to the current host + *@param Destination Host + */ + public boolean isDestinationClose(DTNHost d){ + if (getDistance(this.getHost(), d) <= PROXIMITY_THRESHOLD){ + //System.out.println("Yes"); + //System.out.println("isDestinationClose ?"+this.getHost().getAddress()+" "+d.getAddress()); + + return true; + } + //System.out.println("No"); + return false; + } + /** + *Broadcasts the message to all its connections + *@param Message to be broadcasted + *@param Message mode + */ + public void localBroadCastMessage(Message m, int mode){ + m.setMsgType(mode); + DTNHost to; + //todo + for (Connection con : getConnections()) { + to = con.getOtherNode(getHost()); + //System.out.println("localBroadcast Message "+m.getId()+" "+m.getTo().getAddress()+" "+m.getFrom().getAddress()+" "+this.getHost().getAddress()+" "+to.getAddress()); + + startTransfer(m,con); + } + return; + } + + /** + *Sends the message to the destination host depending on the type of the message and the mode + *@param Message ID + *@param Destination Host + */ + + @Override + public void sendMessage(String id, DTNHost to) { + Message m = getMessage(id); + Connection con; + if((con=isDestinationConnected(to))!=null){ + startTransfer(m, con); + return; + } + int h; + if(m.getMsgType() == 1){ + h = m.getLocalHops(); + if (h==1){ + return; + } + m.setLocalHops(h-1); + localBroadCastMessage(m, 1); + return; + } + if(isDestinationClose(to)){ + m.setLocalHops(2); + localBroadCastMessage(m, 1); + return; + } + AbstractMap.SimpleEntry tup = getACloserHost(to); + if(tup == null){ + + return; + } + startTransfer(m, tup.getValue()); + } + + public void startProtocol(List messages){ + for(Message m : messages){ + sendMessage(m.getId(),m.getTo()); + } + } +}