/** * Helper function for rerouting * * @param link */ void reroute_bundles(final Link link) { assert !link.isdeleted() : "TableBasedRouter : reroute_bundles, link is deleted"; // "if the reroute timer fires, the link should be down and there // should be at least one bundle queued on it." [DTN2] if (link.state() != Link.state_t.UNAVAILABLE) { Log.w( TAG, String.format( "reroute timer fired but link %s state is %s, not UNAVAILABLE", link, link.state().toString())); return; } Log.d( TAG, String.format( "reroute timer fired -- cancelling %s bundles on link %s", link.queue().size(), link.toString())); link.queue().get_lock().lock(); try { while (!link.queue().empty()) { Bundle bundle = link.queue().front(); actions_.cancel_bundle(bundle, link); assert !bundle.is_queued_on(link.queue()) : "TableBasedRouter : reroute_bundles, bundle is not queued on link"; } // "there should never have been any in flight since the link is // unavailable" [DTN2] assert link.inflight().empty() : "TableBasedRouter : reroute_bundles, link on flight list is not empty"; } finally { link.queue().get_lock().unlock(); } }
/** "Try to forward a bundle to a next hop route." [DTN2] */ protected boolean fwd_to_nexthop(Bundle bundle, RouteEntry route) { Link link = route.link(); // "if the link is available and not open, open it" [DTN2] if (link.isNotUnavailable() && (!link.isopen()) && (!link.isopening())) { Log.d(TAG, String.format("opening %s because a message is intended for it", link.name())); actions_.open_link(link); } // "if the link is open and has space in the queue, then queue the // bundle for transmission there" [DTN2] if (link.isopen() && !link.queue_is_full()) { Log.d(TAG, String.format("queuing %d on %s", bundle.bundleid(), link.name())); actions_.queue_bundle(bundle, link, route.action(), route.custody_spec()); return true; } // "otherwise we can't send the bundle now, so put it on the link's // deferred list and log reason why we can't forward it" [DTN2] DeferredList deferred = deferred_list(link); if (!bundle.is_queued_on(deferred.list())) { ForwardingInfo info = new ForwardingInfo( ForwardingInfo.state_t.NONE, route.action(), link.name_str(), 0xffffffff, link.remote_eid(), route.custody_spec()); deferred.add(bundle, info); } else { Log.w( TAG, String.format( "bundle %d already exists on deferred list of link %s", bundle.bundleid(), link.name())); } if (!link.isNotUnavailable()) { Log.d( TAG, String.format( "can't forward bundle %d to %s because link not available", bundle.bundleid(), link.name())); } else if (!link.isopen()) { Log.d( TAG, String.format( TAG, "can't forward bundle %d to %s because link not open", bundle.bundleid(), link.name())); } else if (link.queue_is_full()) { Log.d( TAG, String.format( TAG, "can't forward bundle %d to %s because link queue is full", bundle.bundleid(), link.name())); } else { Log.d(TAG, String.format(TAG, "can't forward %d to %s", bundle.bundleid(), link.name())); } return false; }