/** * Delivery bundle process forward the bundle to BundleDaemon * * @param bundle Bundle to process. */ @Override public void deliver_bundle(Bundle bundle) { int payload_len = bundle.payload().length(); Logger.getInstance() .debug(TAG, String.format("%d byte ping from %s", payload_len, bundle.source().str())); Bundle reply = new Bundle(location_t.MEMORY); reply.source().assign(endpoint_); reply.dest().assign(bundle.source()); reply.replyto().assign(EndpointID.NULL_EID()); reply.custodian().assign(EndpointID.NULL_EID()); reply.set_expiration(bundle.expiration()); reply.payload().set_length(payload_len); reply.payload().write_data(bundle.payload(), 0, payload_len, 0); BundleDaemon.getInstance().post_at_head(new BundleDeliveredEvent(bundle, this)); BundleDaemon.getInstance() .post_at_head(new BundleReceivedEvent(reply, event_source_t.EVENTSRC_ADMIN)); }
/** Main loop in Discovery */ public void run() { Logger.getInstance().debug(TAG, "discovery thread running"); IByteBuffer buf = new SerializableByteBuffer(1024); while (true) { if (shutdown_) break; /* Send section */ try { int min_diff = INT_MAX; Iterator<Announce> i = list_.iterator(); while (i.hasNext()) { IPAnnounce announce = (IPAnnounce) i.next(); int remaining = announce.interval_remaining(); if (remaining == 0) { try { // Logger.getInstance().debug(TAG, // "announce ready for sending"); hdr = announce.format_advertisement(buf, 1024); buf.put(hdr.cl_type()); buf.put(hdr.interval()); buf.putShort(hdr.length()); byte[] ip_address = new byte[] {0, 0, 0, 0}; buf.put(ip_address); buf.putShort(hdr.inet_port()); buf.putShort(hdr.name_len()); byte[] name = hdr.sender_name().getBytes(); buf.put(name); int l = hdr.length(); data = new byte[l]; int z; for (z = 0; z < l; z++) { data[z] = buf.get(z); } DatagramPacket pack = new DatagramPacket( data, data.length, InetAddress.getByName("255.255.255.255"), port_); socket_.send(pack); min_diff = announce.interval(); } catch (Exception e) { Logger.getInstance().error(TAG, "error sending the packet " + e.getMessage()); } } else { // Logger.getInstance().debug(TAG, // "Could not send discovery request"); if (remaining < min_diff) { min_diff = announce.interval_remaining(); } } } } catch (Exception e) { e.printStackTrace(); } /* receive section */ try { buf.rewind(); byte[] Rdata = new byte[1024]; DatagramPacket packet = new DatagramPacket(Rdata, Rdata.length); socket_.receive(packet); Logger.getInstance().debug("B4", "Received beacon: " + packet.getAddress()); // String s = new String(packet.getData(), 0, // packet.getLength()); // Logger.getInstance().debug(TAG, "Received response " + s); EndpointID remote_eid = new EndpointID(); String nexthop = ""; // For now byte[] b = packet.getData(); ByteBuffer bb = ByteBuffer.wrap(b); hdr = new DiscoveryHeader(); hdr = new DiscoveryHeader(); hdr.set_cl_type(bb.get()); hdr.set_interval(bb.get()); hdr.set_length(bb.getShort()); byte[] addr = new byte[4]; bb.get(addr); hdr.set_inet_addr(InetAddress.getByAddress(addr)); hdr.set_inet_port(bb.getShort()); short name_len = bb.getShort(); hdr.set_name_len(name_len); byte[] name = new byte[name_len]; bb.get(name); String sender_name = new String(name); hdr.set_sender_name(sender_name); remote_eid = new EndpointID(hdr.sender_name()); // if(hdr.inet_addr().toString().equals("0.0.0.0")) nexthop = packet.getAddress().toString() + ":" + hdr.inet_port(); // else // nexthop = hdr.inet_addr().toString()+":"+hdr.inet_port(); String Type = IPDiscovery.type_to_str(cl_type_t.get(hdr.cl_type())); BundleDaemon BD = BundleDaemon.getInstance(); if (remote_eid.equals(BD.local_eid())) { // Logger.getInstance().debug(TAG, // "ignoring beacon from self" + remote_eid); } else { // distribute to all beacons registered for this CL type handle_neighbor_discovered(Type, nexthop, remote_eid); } Logger.getInstance().debug("B4", "beacon: " + remote_eid); } catch (Exception e) { Logger.getInstance().info(TAG, "Fail receiving the UDP datagram " + e.getMessage()); } } }
/** "Constructor-like function to create a new custody signal bundle." [DTN2] */ public static Bundle create_custody_signal( final Bundle orig_bundle, final EndpointID source_eid, boolean succeeded, BundleProtocol.custody_signal_reason_t reason) { Bundle bundle = new Bundle(location_t.MEMORY); bundle.source().assign(source_eid); if (orig_bundle.custodian().equals(EndpointID.NULL_EID())) { Logger.getInstance() .error( TAG, String.format( "create_custody_signal(for bundle id %d): " + "custody signal cannot be generated due to custodian is null eid", orig_bundle.bundleid())); } bundle.dest().assign(orig_bundle.custodian()); bundle.replyto().assign(EndpointID.NULL_EID()); bundle.custodian().assign(EndpointID.NULL_EID()); bundle.set_is_admin(true); bundle.set_expiration(orig_bundle.expiration()); int sdnv_encoding_len = 0; int signal_len = 0; // "format of custody signals: // // 1 byte admin payload type and flags // 1 byte status code // SDNV [Fragment Offset (if present)] // SDNV [Fragment Length (if present)] // SDNVx2 Time of custody signal // SDNVx2 Copy of bundle X's Creation Timestamp // SDNV Length of X's source endpoint ID // vari Source endpoint ID of bundle X // // first calculate the length // // the non-optional, fixed-length fields above:" [DTN2] signal_len = 1 + 1; // "the 2 SDNV fragment fields:" [DTN2] if (orig_bundle.is_fragment()) { signal_len += SDNV.encoding_len(orig_bundle.frag_offset()); signal_len += SDNV.encoding_len(orig_bundle.orig_length()); } // "Time field, set to the current time:" [DTN2] DTNTime now = new DTNTime(); signal_len += DTNTime.SDNV_encoding_len(now); // "The bundle's creation timestamp:" [DTN2] signal_len += BundleTimestamp.SDNV_encoding_len(orig_bundle.creation_ts()); // the Source Endpoint ID length and value signal_len += SDNV.encoding_len(orig_bundle.source().length()) + orig_bundle.source().length(); // // "We got all the data ready, now format the buffer" [DTN2] // IByteBuffer bp = new SerializableByteBuffer(signal_len); int len = signal_len; bp.rewind(); // "Admin Payload Type and flags" [DTN2] byte type_and_flags_byte = (byte) (BundleProtocol.admin_record_type_t.ADMIN_CUSTODY_SIGNAL.getCode() << 4); if (orig_bundle.is_fragment()) { type_and_flags_byte |= BundleProtocol.admin_record_flags_t.ADMIN_IS_FRAGMENT.getCode(); } bp.put(type_and_flags_byte); len--; // Status_Flag_Byte consists of Success flag and reason code byte status_flag_byte = (byte) ((succeeded ? 1 : 0) << 7 | (reason.getCode() & 0x7f)); bp.put(status_flag_byte); len--; // "The 2 Fragment Fields" [DTN2] if (orig_bundle.is_fragment()) { sdnv_encoding_len = SDNV.encode(orig_bundle.frag_offset(), bp, len); assert (sdnv_encoding_len > 0); len -= sdnv_encoding_len; sdnv_encoding_len = SDNV.encode(orig_bundle.orig_length(), bp, len); assert (sdnv_encoding_len > 0); len -= sdnv_encoding_len; } // DTNTime which is a time of signal field sdnv_encoding_len = DTNTime.SDNV_encoding_len(now); assert (sdnv_encoding_len > 0); DTNTime.encodeSDNV(now, bp); len -= sdnv_encoding_len; // "Copy of bundle X's Creation Timestamp" [DTN2] sdnv_encoding_len = BundleTimestamp.SDNV_encoding_len(orig_bundle.creation_ts()); assert (sdnv_encoding_len > 0); BundleTimestamp.encodeSDNV(orig_bundle.creation_ts(), bp); len -= sdnv_encoding_len; // "The Endpoint ID length and data" [DTN2] sdnv_encoding_len = SDNV.encode(orig_bundle.source().length(), bp, len); assert (sdnv_encoding_len > 0); len -= sdnv_encoding_len; assert (len == orig_bundle.source().length()); bp.put(orig_bundle.source().byte_array()); // // "Finished generating the payload" [DTN2] // bp.rewind(); bundle.payload().set_data(bp, signal_len); return bundle; }