ForwardRouteTable.java :  » UnTagged » adhoc-on-android » adhoc » aodv » routes » Android Open Source

Android Open Source » UnTagged » adhoc on android 
adhoc on android » adhoc » aodv » routes » ForwardRouteTable.java
package adhoc.aodv.routes;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;

import adhoc.aodv.Receiver;
import adhoc.aodv.exception.NoSuchRouteException;
import adhoc.aodv.exception.RouteNotValidException;
import adhoc.aodv.pdu.RERR;
import adhoc.etc.Debug;

public class ForwardRouteTable {

  private HashMap<Integer, ForwardRouteEntry> entries;
  private LinkedList<ForwardRouteEntry> sortedEntries;
  private final Object tableLock = new Integer(0);

  public ForwardRouteTable() {
    // contains known routes
    entries = new HashMap<Integer, ForwardRouteEntry>();

    // containing the known routes, sorted such that the route with the
    // least 'aliveTimeLeft' is head
    sortedEntries = new LinkedList<ForwardRouteEntry>();
  }

  /**
   * Adds the given entry to the forwardRoute table
   * @param forwardRouteEntry the entry to be stored
   * @return returns true if the route were added successfully. A successful add requires that no matching entry exists in the table
   */
  public boolean addForwardRouteEntry(ForwardRouteEntry forwardRouteEntry) {
    synchronized (tableLock) {
      if(!entries.containsKey(forwardRouteEntry.getDestinationAddress())) {
        entries.put(forwardRouteEntry.getDestinationAddress(), forwardRouteEntry);
        sortedEntries.addLast(forwardRouteEntry);
        Debug.print("ForwardRouteTable: Adding new forward route entry for dest: "+forwardRouteEntry.getDestinationAddress());
        Debug.print(this.toString());
        return true;
      }
      return false;
    }
  }
  
  /**
   * 
   * @param destAddress the destination address which to search for in the table
   * @return returns false if the route does not exist
   */
  public boolean removeEntry(int destAddress){
    synchronized (tableLock) {
      RouteEntry entry = entries.remove(destAddress);
      if (entry != null) {
        sortedEntries.remove(entry);
        Debug.print("ForwardRouteTable: removing forward route entry for dest: "+destAddress);
        Debug.print(this.toString());
        return true;
      }
      return false;
    }
  }
  
  public boolean updateForwardRouteEntry(ForwardRouteEntry entry) throws NoSuchRouteException{
    synchronized (tableLock) {
      if(removeEntry(entry.getDestinationAddress())
          && addForwardRouteEntry(entry)){
        Debug.print("updateForwardRouteEntry: Updating route for dest: "+entry.getDestinationAddress() );
        return true;
      }
    }
    throw new NoSuchRouteException();
  }
  
  /**
   * Method used to known the last known information about a routes 'freshness'
   * @param destinationAddress the given destination which to search for in the table
   * @return returns the destination sequence number of the forward entry
   * @throws NoSuchRouteException is thrown if no such exists
   */
  public int getLastKnownDestSeqNumber(int destinationAddress) throws NoSuchRouteException{
    RouteEntry entry = entries.get(destinationAddress);
    if(entry != null){
      return entry.getDestinationSequenceNumber();
    }
    throw new NoSuchRouteException();
  }
  
  public ArrayList<Integer> getPrecursors(int destinationAddress){
    synchronized (tableLock) {
      ForwardRouteEntry entry = entries.get(destinationAddress);
      if(entry != null){
        return entry.getPrecursors();
      }
      return new ArrayList<Integer>();
    }
  } 
  
  /**
   * Makes a forward route valid, updates it sequence number if necessary and resets the AliveTimeLeft
   * @param destinationAddress used to determine which forward route to set valid
   * @param newDestinationSeqNumber this destSeqNum is only set in the entry if it is greater that the existing destSeqNum
   * @throws NoSuchRouteException thrown if no table information is known about the destination
   */
  public void setValid(int destinationAddress, int destinationSeqNumber, boolean validValue) throws NoSuchRouteException {
    ForwardRouteEntry entry = entries.get(destinationAddress);
    if(entry != null){
      entry.setValid(validValue);
      entry.resetAliveTimeLeft();
      synchronized (tableLock) {
        sortedEntries.remove(entry);
        sortedEntries.addLast(entry);
      }
      entry.setSeqNum(  Receiver.getMaximumSeqNum(  destinationSeqNumber,
                              entry.getDestinationSequenceNumber()  )  );
      return;
    }
    throw new NoSuchRouteException();
  }

  /**
   * 
   * @param nodeAddress
   * @return RouteEntry
   * @throws NoSuchRouteException thrown if no table information is known about the destination
   * @throws RouteNotValidException thrown if a route were found, but is marked as invalid
   */
  public ForwardRouteEntry getForwardRouteEntry(int destinationAddress) throws NoSuchRouteException, RouteNotValidException {
    ForwardRouteEntry entry = entries.get(destinationAddress);
    if (entry != null) {
      entry.resetAliveTimeLeft();
      synchronized (tableLock) {  
        sortedEntries.remove(entry);
        sortedEntries.addLast(entry);
      }
      if (!(entry).isValid()) {
        throw new RouteNotValidException();
      }
      return entry;
    }
    throw new NoSuchRouteException();
  }
  
  /**
   * Method for knowing if the table (sorted list) contain any entries
   * @return true if the sortedlist is empty
   */
  public boolean isEmpty(){
    return sortedEntries.isEmpty();  
  }
  
  /**
   * 
   * @return returns the route entry with the minimum time to live before expire  
   * @throws NoSuchRouteException is thrown if no such exists
   */
  public RouteEntry getNextRouteToExpire() throws NoSuchRouteException{
    RouteEntry route = null;
    route = sortedEntries.peek();  
    if(route != null){
      return route;
    }
    throw new NoSuchRouteException();
  }
  
  /**
   * Searches the table for routes which match on the 'nextHopAddress'.
   * The destination node of the matching entries is then used in a RERR pdu for later processing.
   * The state of matching route entries is set to invalid
   * @param brokenNodeAddress is the destination node which can not be reached any more
   * @return ArrayList<RERR> returns an ArrayList of RERR messages
   */
  public ArrayList<RERR> findBrokenRoutes(int brokenNodeAddress){
    ArrayList<RERR> brokenRoutes = new ArrayList<RERR>(); 
    LinkedList<ForwardRouteEntry> currentEntries = new LinkedList<ForwardRouteEntry>();
    synchronized (tableLock) {
      for(ForwardRouteEntry entry: sortedEntries){
        currentEntries.add(entry);
      }
      
      for(ForwardRouteEntry entry : currentEntries){
        if(entry.getNextHop() == brokenNodeAddress){
          RERR rerr = new RERR(entry.getDestinationAddress(), entry.getDestinationSequenceNumber(), entry.getPrecursors());
          brokenRoutes.add(rerr);
          try {
            setValid(entry.getDestinationAddress(), entry.getDestinationSequenceNumber(), false);
          } catch (NoSuchRouteException e) {
            Debug.print("RouteTableManager: NoSuchRouteException where thrown in findBrokenRoutes");
          }
        }
      }
    }
    return brokenRoutes;
  }
  
  /**
   * only used for debugging
   */
  public String toString(){
    synchronized (tableLock) {
      if(entries.size() != sortedEntries.size()){
        Debug.print("ForwardRouteTable: FATAL ERROR - inconsistensy in this table");
      }
      if(entries.isEmpty()){
        return "Forward Table is empty\n";
      }
      String returnString = "---------------------\n"+
                  "|Forward Route Table:\n"+
                  "---------------------";
      for(ForwardRouteEntry f :entries.values()){
        returnString += "\n"+"|Dest: "+f.getDestinationAddress()+" destSeqN: "+f.getDestinationSequenceNumber()+" nextHop: "+f.getNextHop()+" hopCount: "+f.getHopCount()+" isValid: "+f.isValid()+" TTL: "+(f.getAliveTimeLeft()-System.currentTimeMillis())+" precursors: ";
        for(int p  : f.getPrecursors()){
          returnString += p+" ";
        }
      }  
      return returnString+"\n---------------------\n";
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.