void queueRouteErrorMessage(
      String unreachableNodeAddress, int unreachableSequenceNumber, ArrayList<String> precusors) {
    for (String destinationAdderss : precusors) {
      RouteError rrer =
          new RouteError(unreachableNodeAddress, unreachableSequenceNumber, destinationAdderss);

      sender.queueRoutingMessage(rrer);
    }
  }
 void queueRetryRouteRequest(
     String destinationAddress, int destinationSequenceNumber, int retriesLeft) {
   RouteRequest rreq =
       new RouteRequest(
           node.getCurrentSequenceNumber(),
           node.getCurrentBroadcastID(),
           destinationAddress,
           destinationSequenceNumber,
           retriesLeft);
   sender.queueRoutingMessage(rreq);
   // debugResending(rreq);
 }
  private boolean createOrUpdatePathTo(
      String destinationAddress, int destinationSequenceNumber, String nextHop, int hopCount) {

    try {

      return routingTable.updateRouteTo(
          destinationAddress, destinationSequenceNumber, nextHop, hopCount);
    } catch (InvalidRouteException e) {
      e.printStackTrace();
      sender.onNewNodeReachable(destinationAddress);
      return true;
    } catch (NoSuchRouteException e) {
      // e.printStackTrace();
      if (routingTable.createForwardRouteEntry(
          destinationAddress, destinationSequenceNumber, nextHop, hopCount)) {
        sender.onNewNodeReachable(destinationAddress);
        return true;
      }
    }
    return false;
  }
  private void receiveRREQ(RouteRequest routeRequest) {
    if (BuildConfig.DEBUG) {
      Debug.debugMessage(routeRequest, getMyAddresses(), true, false);
    }

    createOrUpdatePathTo(
        routeRequest.getPreviousHop(),
        Constants.UNKNOWN_SEQUENCE_NUMBER,
        routeRequest.getPreviousHop(),
        1);

    if (routingTable.routeRequestExist(routeRequest)) {
      return;
    }

    routingTable.addRouteRequest(routeRequest, false);

    routeRequest.incrementHopCount();

    createOrUpdatePathTo(
        routeRequest.getSourceAddress(),
        routeRequest.getSourceSequenceNumber(),
        routeRequest.getPreviousHop(),
        routeRequest.getHopCount());

    RouteReply rrep = null;
    try {
      rrep = sendRREP(routeRequest);
    } catch (InvalidRouteException e) {
      routeRequest.setDestinationSequenceNumber(
          Math.max(e.getLastSequenceNumber(), routeRequest.getDestinationSequenceNumber()));
    } catch (NoSuchRouteException e) {
    } finally {
      if (rrep != null) {
        sender.queueRoutingMessage(rrep);
      } else {
        sender.queueRoutingMessage(routeRequest);
      }
    }
  }
  @Override
  public void routeMessage(String destinationAddress, JSONObject message) throws RoutingException {
    List<String> myAddresses = null;
    if (BuildConfig.DEBUG) {
      myAddresses = new ArrayList<String>();
      myAddresses.add("Prop Node");
    }

    UserDataMessage dataMessage = new UserDataMessage(message);
    dataMessage.setDestinationAddress(destinationAddress);

    if (IRouter.destinationIsBroacast(destinationAddress)) {
      dataMessage.setNextHop(destinationAddress);
    }

    sender.queueMyDataMessage(dataMessage);
  }
 void queueRouteErrorMessage(
     String unreachableNodeAddress, int unreachableSequenceNumber, String destinationAddress) {
   RouteError rrer =
       new RouteError(unreachableNodeAddress, unreachableSequenceNumber, destinationAddress);
   sender.queueRoutingMessage(rrer);
 }
 public void onRouteEstablishmentFailure(String destinationAddress) {
   sender.onRouteEstablishmentFailure(destinationAddress);
   notifier.notifyAboutDestinationUnreachable(destinationAddress);
 }