/// <summary> /// Decode input as an interest in NDN-TLV and set the fields of the interest /// object. /// </summary> /// /// <param name="interest">The Interest object whose fields are updated.</param> /// <param name="input"></param> /// <param name="signedPortionBeginOffset">name component and ends just before the final name component (which is assumed to be a signature for a signed interest).</param> /// <param name="signedPortionEndOffset">name component and ends just before the final name component (which is assumed to be a signature for a signed interest).</param> /// <param name="copy">unchanged while the Blob values are used.</param> /// <exception cref="EncodingException">For invalid encoding.</exception> public override void decodeInterest(Interest interest, ByteBuffer input, int[] signedPortionBeginOffset, int[] signedPortionEndOffset, bool copy) { TlvDecoder decoder = new TlvDecoder(input); int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Interest); decodeName(interest.getName(), signedPortionBeginOffset, signedPortionEndOffset, decoder, copy); if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Selectors, endOffset)) decodeSelectors(interest, decoder, copy); // Require a Nonce, but don't force it to be 4 bytes. ByteBuffer nonce = decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Nonce); interest.setInterestLifetimeMilliseconds(decoder .readOptionalNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.InterestLifetime, endOffset)); if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Data, endOffset)) { // Get the bytes of the Link TLV. int linkBeginOffset = decoder.getOffset(); int linkEndOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Data); decoder.seek(linkEndOffset); interest.setLinkWireEncoding( new Blob(decoder.getSlice(linkBeginOffset, linkEndOffset), copy), this); } else interest.unsetLink(); interest.setSelectedDelegationIndex((int) decoder .readOptionalNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SelectedDelegation, endOffset)); if (interest.getSelectedDelegationIndex() >= 0 && !interest.hasLink()) throw new EncodingException( "Interest has a selected delegation, but no link object"); // Set the nonce last because setting other interest fields clears it. interest.setNonce(new Blob(nonce, copy)); decoder.finishNestedTlvs(endOffset); }
/// <summary> /// Send the Interest through the transport, read the entire response and call /// onData, onTimeout or onNetworkNack as described below. /// </summary> /// /// <param name="pendingInterestId"></param> /// <param name="interestCopy">to use.</param> /// <param name="onData">expressInterest and data is the received Data object.</param> /// <param name="onTimeout">interest given to expressInterest. If onTimeout is null, this does not use it.</param> /// <param name="onNetworkNack">onNetworkNack.onNetworkNack(interest, networkNack) and does not call onTimeout. However, if a network Nack is received and onNetworkNack is null, do nothing and wait for the interest to time out.</param> /// <param name="wireFormat">A WireFormat object used to encode the message.</param> /// <param name="face"></param> /// <exception cref="IOException">For I/O error in sending the interest.</exception> /// <exception cref="System.Exception">If the encoded interest size exceeds getMaxNdnPacketSize().</exception> public void expressInterest(long pendingInterestId, Interest interestCopy, OnData onData, OnTimeout onTimeout, OnNetworkNack onNetworkNack, WireFormat wireFormat, Face face) { // Set the nonce in our copy of the Interest so it is saved in the PIT. interestCopy.setNonce(nonceTemplate_); interestCopy.refreshNonce(); if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.CONNECT_COMPLETE) { // We are connected. Simply send the interest without synchronizing. expressInterestHelper(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack, wireFormat, face); return; } lock (onConnectedCallbacks_) { // TODO: Properly check if we are already connected to the expected host. if (!transport_.isAsync()) { // The simple case: Just do a blocking connect and express. transport_.connect(connectionInfo_, this, null); expressInterestHelper(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack, wireFormat, face); // Make future calls to expressInterest send directly to the Transport. connectStatus_ = net.named_data.jndn.Node.ConnectStatus.CONNECT_COMPLETE; return; } // Handle the async case. if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.UNCONNECTED) { connectStatus_ = net.named_data.jndn.Node.ConnectStatus.CONNECT_REQUESTED; // expressInterestHelper will be called by onConnected. ILOG.J2CsMapping.Collections.Collections.Add(onConnectedCallbacks_, new Node.Anonymous_C3(this, interestCopy, onData, wireFormat, onTimeout, pendingInterestId, face, onNetworkNack)); IRunnable onConnected = new Node.Anonymous_C2(this); transport_.connect(connectionInfo_, this, onConnected); } else if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.CONNECT_REQUESTED) { // Still connecting. add to the interests to express by onConnected. ILOG.J2CsMapping.Collections.Collections.Add(onConnectedCallbacks_, new Node.Anonymous_C1(this, onData, pendingInterestId, wireFormat, face, onNetworkNack, interestCopy, onTimeout)); } else if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.CONNECT_COMPLETE) { // We have to repeat this check for CONNECT_COMPLETE in case the // onConnected callback was called while we were waiting to enter this // synchronized block. expressInterestHelper(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack, wireFormat, face); } else { // Don't expect this to happen. throw new Exception("Node: Unrecognized _connectStatus " + connectStatus_); } } }
/// <summary> /// Send the Interest through the transport, read the entire response and call /// onData, onTimeout or onNetworkNack as described below. /// </summary> /// /// <param name="pendingInterestId"></param> /// <param name="interestCopy">to use.</param> /// <param name="onData">expressInterest and data is the received Data object.</param> /// <param name="onTimeout">interest given to expressInterest. If onTimeout is null, this does not use it.</param> /// <param name="onNetworkNack">onNetworkNack.onNetworkNack(interest, networkNack) and does not call onTimeout. However, if a network Nack is received and onNetworkNack is null, do nothing and wait for the interest to time out.</param> /// <param name="wireFormat">A WireFormat object used to encode the message.</param> /// <param name="face"></param> /// <exception cref="IOException">For I/O error in sending the interest.</exception> /// <exception cref="System.Exception">If the encoded interest size exceeds getMaxNdnPacketSize().</exception> public void expressInterest(long pendingInterestId, Interest interestCopy, OnData onData, OnTimeout onTimeout, OnNetworkNack onNetworkNack, WireFormat wireFormat, Face face) { // Set the nonce in our copy of the Interest so it is saved in the PIT. interestCopy.setNonce(nonceTemplate_); interestCopy.refreshNonce(); if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.CONNECT_COMPLETE) { // We are connected. Simply send the interest without synchronizing. expressInterestHelper(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack, wireFormat, face); return; } lock (onConnectedCallbacks_) { // TODO: Properly check if we are already connected to the expected host. if (!transport_.isAsync()) { // The simple case: Just do a blocking connect and express. transport_.connect(connectionInfo_, this, null); expressInterestHelper(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack, wireFormat, face); // Make future calls to expressInterest send directly to the Transport. connectStatus_ = net.named_data.jndn.Node.ConnectStatus.CONNECT_COMPLETE; return; } // Handle the async case. if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.UNCONNECTED) { connectStatus_ = net.named_data.jndn.Node.ConnectStatus.CONNECT_REQUESTED; // expressInterestHelper will be called by onConnected. ILOG.J2CsMapping.Collections.Collections.Add(onConnectedCallbacks_,new Node.Anonymous_C3 (this, interestCopy, onNetworkNack, face, onTimeout, pendingInterestId, wireFormat, onData)); IRunnable onConnected = new Node.Anonymous_C2 (this); transport_.connect(connectionInfo_, this, onConnected); } else if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.CONNECT_REQUESTED) { // Still connecting. add to the interests to express by onConnected. ILOG.J2CsMapping.Collections.Collections.Add(onConnectedCallbacks_,new Node.Anonymous_C1 (this, interestCopy, onData, onTimeout, onNetworkNack, wireFormat, face, pendingInterestId)); } else if (connectStatus_ == net.named_data.jndn.Node.ConnectStatus.CONNECT_COMPLETE) // We have to repeat this check for CONNECT_COMPLETE in case the // onConnected callback was called while we were waiting to enter this // synchronized block. expressInterestHelper(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack, wireFormat, face); else // Don't expect this to happen. throw new Exception("Node: Unrecognized _connectStatus " + connectStatus_); } }