Ejemplo n.º 1
0
        /// <summary>
        /// Decode input as a control parameters in NDN-TLV and set the fields of the
        /// controlResponse object.
        /// </summary>
        ///
        /// <param name="controlResponse"></param>
        /// <param name="input"></param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException">For invalid encoding</exception>
        public override void decodeControlResponse(ControlResponse controlResponse,
				ByteBuffer input, bool copy)
        {
            TlvDecoder decoder = new TlvDecoder(input);
            int endOffset = decoder
                    .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.NfdCommand_ControlResponse);

            controlResponse.setStatusCode((int) decoder
                    .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.NfdCommand_StatusCode));
            // Set copy false since we just immediately get a string.
            Blob statusText = new Blob(
                    decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.NfdCommand_StatusText), false);
            controlResponse.setStatusText(statusText.toString());

            // Decode the body.
            if (decoder
                    .peekType(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_ControlParameters, endOffset)) {
                controlResponse.setBodyAsControlParameters(new ControlParameters());
                // Decode into the existing ControlParameters to avoid copying.
                decodeControlParameters(
                        controlResponse.getBodyAsControlParameters(), decoder, copy);
            } else
                controlResponse.setBodyAsControlParameters(null);

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Decode the name as NDN-TLV and set the fields in name.
        /// </summary>
        ///
        /// <param name="name">The name object whose fields are set.</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). If you are not decoding in order to verify, you can ignore this returned value.</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). If you are not decoding in order to verify, you can ignore this returned value.</param>
        /// <param name="decoder">The decoder with the input to decode.</param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException"></exception>
        private static void decodeName(Name name, int[] signedPortionBeginOffset,
				int[] signedPortionEndOffset, TlvDecoder decoder, bool copy)
        {
            name.clear();

            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Name);

            signedPortionBeginOffset[0] = decoder.getOffset();
            // In case there are no components, set signedPortionEndOffset arbitrarily.
            signedPortionEndOffset[0] = signedPortionBeginOffset[0];

            while (decoder.getOffset() < endOffset) {
                signedPortionEndOffset[0] = decoder.getOffset();
                name.append(decodeNameComponent(decoder, copy));
            }

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 3
0
        private static void decodeMetaInfo(MetaInfo metaInfo, TlvDecoder decoder,
				bool copy)
        {
            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.MetaInfo);

            // The ContentType enum is set up with the correct integer for each
            // NDN-TLV ContentType.
            int type = (int) decoder.readOptionalNonNegativeIntegerTlv(
                    net.named_data.jndn.encoding.tlv.Tlv.ContentType, endOffset);
            if (type < 0 || type == net.named_data.jndn.ContentType.BLOB.getNumericType())
                // Default to BLOB if the value is omitted.
                metaInfo.setType(net.named_data.jndn.ContentType.BLOB);
            else if (type == net.named_data.jndn.ContentType.LINK.getNumericType())
                metaInfo.setType(net.named_data.jndn.ContentType.LINK);
            else if (type == net.named_data.jndn.ContentType.KEY.getNumericType())
                metaInfo.setType(net.named_data.jndn.ContentType.KEY);
            else if (type == net.named_data.jndn.ContentType.NACK.getNumericType())
                metaInfo.setType(net.named_data.jndn.ContentType.NACK);
            else {
                // Unrecognized content type.
                metaInfo.setType(net.named_data.jndn.ContentType.OTHER_CODE);
                metaInfo.setOtherTypeCode(type);
            }

            metaInfo.setFreshnessPeriod(decoder.readOptionalNonNegativeIntegerTlv(
                    net.named_data.jndn.encoding.tlv.Tlv.FreshnessPeriod, endOffset));
            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.FinalBlockId, endOffset)) {
                int finalBlockIdEndOffset = decoder
                        .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.FinalBlockId);
                metaInfo.setFinalBlockId(decodeNameComponent(decoder, copy));
                decoder.finishNestedTlvs(finalBlockIdEndOffset);
            } else
                metaInfo.setFinalBlockId(null);

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 4
0
        private static void decodeKeyLocator(int expectedType,
				KeyLocator keyLocator, TlvDecoder decoder, bool copy)
        {
            int endOffset = decoder.readNestedTlvsStart(expectedType);

            keyLocator.clear();

            if (decoder.getOffset() == endOffset)
                // The KeyLocator is omitted, so leave the fields as none.
                return;

            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Name, endOffset)) {
                // KeyLocator is a Name.
                keyLocator.setType(net.named_data.jndn.KeyLocatorType.KEYNAME);
                decodeName(keyLocator.getKeyName(), new int[1], new int[1],
                        decoder, copy);
            } else if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.KeyLocatorDigest, endOffset)) {
                // KeyLocator is a KeyLocatorDigest.
                keyLocator.setType(net.named_data.jndn.KeyLocatorType.KEY_LOCATOR_DIGEST);
                keyLocator.setKeyData(new Blob(decoder
                        .readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.KeyLocatorDigest), copy));
            } else
                throw new EncodingException(
                        "decodeKeyLocator: Unrecognized key locator type");

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Continue scanning input starting from offset_ to find the element end.
        /// If the end of the element which started at offset 0 is found, this returns
        /// true and getOffset() is the length of the element.  Otherwise, this returns
        /// false which means you should read more into input and call again.
        /// </summary>
        ///
        /// <param name="input">You have to pass in input each time because the buffer could be reallocated.</param>
        /// <returns>true if found the element end, false if not.</returns>
        public bool findElementEnd(ByteBuffer input)
        {
            if (gotElementEnd_)
                // Someone is calling when we already got the end.
                return true;

            TlvDecoder decoder = new TlvDecoder(input);

            while (true) {
                if (offset_ >= input.limit())
                    // All the cases assume we have some input. Return and wait for more.
                    return false;

                if (state_ == TlvStructureDecoder.READ_TYPE) {
                    int firstOctet = (int) input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet < 253)
                        // The value is simple, so we can skip straight to reading the length.
                        state_ = TlvStructureDecoder.READ_LENGTH;
                    else {
                        // Set up to skip the type bytes.
                        if (firstOctet == 253)
                            nBytesToRead_ = 2;
                        else if (firstOctet == 254)
                            nBytesToRead_ = 4;
                        else
                            // value == 255.
                            nBytesToRead_ = 8;

                        state_ = TlvStructureDecoder.READ_TYPE_BYTES;
                    }
                } else if (state_ == TlvStructureDecoder.READ_TYPE_BYTES) {
                    int nRemainingBytes = input.limit() - offset_;
                    if (nRemainingBytes < nBytesToRead_) {
                        // Need more.
                        offset_ += nRemainingBytes;
                        nBytesToRead_ -= nRemainingBytes;
                        return false;
                    }

                    // Got the type bytes. Move on to read the length.
                    offset_ += nBytesToRead_;
                    state_ = TlvStructureDecoder.READ_LENGTH;
                } else if (state_ == TlvStructureDecoder.READ_LENGTH) {
                    int firstOctet_0 = (int) input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet_0 < 253) {
                        // The value is simple, so we can skip straight to reading
                        //  the value bytes.
                        nBytesToRead_ = firstOctet_0;
                        if (nBytesToRead_ == 0) {
                            // No value bytes to read. We're finished.
                            gotElementEnd_ = true;
                            return true;
                        }

                        state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                    } else {
                        // We need to read the bytes in the extended encoding of
                        //  the length.
                        if (firstOctet_0 == 253)
                            nBytesToRead_ = 2;
                        else if (firstOctet_0 == 254)
                            nBytesToRead_ = 4;
                        else
                            // value == 255.
                            nBytesToRead_ = 8;

                        // We need to use firstOctet in the next state.
                        firstOctet_ = firstOctet_0;
                        state_ = TlvStructureDecoder.READ_LENGTH_BYTES;
                    }
                } else if (state_ == TlvStructureDecoder.READ_LENGTH_BYTES) {
                    int nRemainingBytes_1 = input.limit() - offset_;
                    if (!useHeaderBuffer_ && nRemainingBytes_1 >= nBytesToRead_) {
                        // We don't have to use the headerBuffer. Set nBytesToRead.
                        decoder.seek(offset_);

                        nBytesToRead_ = decoder.readExtendedVarNumber(firstOctet_);
                        // Update offset_ to the decoder's offset after reading.
                        offset_ = decoder.getOffset();
                    } else {
                        useHeaderBuffer_ = true;

                        int nNeededBytes = nBytesToRead_ - headerBuffer_.position();
                        if (nNeededBytes > nRemainingBytes_1) {
                            // We can't get all of the header bytes from this input.
                            // Save in headerBuffer.
                            if (headerBuffer_.position() + nRemainingBytes_1 > headerBuffer_
                                    .limit())
                                // We don't expect this to happen.
                                throw new Exception(
                                        "Cannot store more header bytes than the size of headerBuffer");
                            ByteBuffer remainingInput = input.duplicate();
                            remainingInput.position(offset_);
                            headerBuffer_.put(remainingInput);
                            offset_ += nRemainingBytes_1;

                            return false;
                        }

                        // Copy the remaining bytes into headerBuffer, read the
                        //   length and set nBytesToRead.
                        if (headerBuffer_.position() + nNeededBytes > headerBuffer_
                                .limit())
                            // We don't expect this to happen.
                            throw new Exception(
                                    "Cannot store more header bytes than the size of headerBuffer");
                        ByteBuffer remainingLengthBytes = input.duplicate();
                        remainingLengthBytes.position(offset_);
                        remainingLengthBytes.limit(offset_ + nNeededBytes);
                        headerBuffer_.put(remainingLengthBytes);
                        offset_ += nNeededBytes;

                        // Use a local decoder just for the headerBuffer.
                        headerBuffer_.flip();
                        TlvDecoder bufferDecoder = new TlvDecoder(headerBuffer_);
                        // Replace nBytesToRead with the length of the value.
                        nBytesToRead_ = bufferDecoder
                                .readExtendedVarNumber(firstOctet_);
                    }

                    if (nBytesToRead_ == 0) {
                        // No value bytes to read. We're finished.
                        gotElementEnd_ = true;
                        return true;
                    }

                    // Get ready to read the value bytes.
                    state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                } else if (state_ == TlvStructureDecoder.READ_VALUE_BYTES) {
                    int nRemainingBytes_2 = input.limit() - offset_;
                    if (nRemainingBytes_2 < nBytesToRead_) {
                        // Need more.
                        offset_ += nRemainingBytes_2;
                        nBytesToRead_ -= nRemainingBytes_2;
                        return false;
                    }

                    // Got the bytes. We're finished.
                    offset_ += nBytesToRead_;
                    gotElementEnd_ = true;
                    return true;
                } else
                    // We don't expect this to happen.
                    throw new Exception("findElementEnd: unrecognized state");
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Decode the input as an NDN-TLV RepetitiveInterval.
        /// </summary>
        ///
        /// <param name="decoder">The decoder with the input to decode.</param>
        /// <returns>A new RepetitiveInterval with the decoded result.</returns>
        private static RepetitiveInterval decodeRepetitiveInterval(
				TlvDecoder decoder)
        {
            int endOffset = decoder
                    .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_RepetitiveInterval);

            // Use Blob to convert UTF8 to a string.
            double startDate = fromIsoString(new Blob(
                    decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_StartDate), true).toString());
            double endDate = fromIsoString(new Blob(
                    decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_EndDate), true).toString());
            int startHour = (int) decoder
                    .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_IntervalStartHour);
            int endHour = (int) decoder
                    .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_IntervalEndHour);
            int nRepeats = (int) decoder
                    .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_NRepeats);

            int repeatUnitCode = (int) decoder
                    .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_RepeatUnit);
            RepetitiveInterval.RepeatUnit repeatUnit;
            if (repeatUnitCode == net.named_data.jndn.encoding.tlv.Tlv.Encrypt_RepeatUnit_NONE)
                repeatUnit = net.named_data.jndn.encrypt.RepetitiveInterval.RepeatUnit.NONE;
            else if (repeatUnitCode == net.named_data.jndn.encoding.tlv.Tlv.Encrypt_RepeatUnit_DAY)
                repeatUnit = net.named_data.jndn.encrypt.RepetitiveInterval.RepeatUnit.DAY;
            else if (repeatUnitCode == net.named_data.jndn.encoding.tlv.Tlv.Encrypt_RepeatUnit_MONTH)
                repeatUnit = net.named_data.jndn.encrypt.RepetitiveInterval.RepeatUnit.MONTH;
            else if (repeatUnitCode == net.named_data.jndn.encoding.tlv.Tlv.Encrypt_RepeatUnit_YEAR)
                repeatUnit = net.named_data.jndn.encrypt.RepetitiveInterval.RepeatUnit.YEAR;
            else
                throw new EncodingException(
                        "Unrecognized RepetitiveInterval RepeatUnit code: "
                                + repeatUnitCode);

            decoder.finishNestedTlvs(endOffset);
            return new RepetitiveInterval(startDate, endDate, startHour, endHour,
                    nRepeats, repeatUnit);
        }
Ejemplo n.º 7
0
        private static void decodeValidityPeriod(ValidityPeriod validityPeriod,
				TlvDecoder decoder)
        {
            int endOffset = decoder
                    .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.ValidityPeriod_ValidityPeriod);

            validityPeriod.clear();

            // Set copy false since we just immediately get the string.
            Blob isoString = new Blob(
                    decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.ValidityPeriod_NotBefore), false);
            double notBefore = net.named_data.jndn.encrypt.Schedule.fromIsoString("" + isoString);
            isoString = new Blob(decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.ValidityPeriod_NotAfter),
                    false);
            double notAfter = net.named_data.jndn.encrypt.Schedule.fromIsoString("" + isoString);

            validityPeriod.setPeriod(notBefore, notAfter);

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 8
0
        private static void decodeSelectors(Interest interest, TlvDecoder decoder,
				bool copy)
        {
            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Selectors);

            interest.setMinSuffixComponents((int) decoder
                    .readOptionalNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.MinSuffixComponents,
                            endOffset));
            interest.setMaxSuffixComponents((int) decoder
                    .readOptionalNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.MaxSuffixComponents,
                            endOffset));

            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.PublisherPublicKeyLocator, endOffset))
                decodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.PublisherPublicKeyLocator,
                        interest.getKeyLocator(), decoder, copy);
            else
                interest.getKeyLocator().clear();

            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Exclude, endOffset))
                decodeExclude(interest.getExclude(), decoder, copy);
            else
                interest.getExclude().clear();

            interest.setChildSelector((int) decoder
                    .readOptionalNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.ChildSelector, endOffset));
            interest.setMustBeFresh(decoder.readBooleanTlv(net.named_data.jndn.encoding.tlv.Tlv.MustBeFresh,
                    endOffset));

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Decode input as a name in NDN-TLV and set the fields of the Name object.
 /// </summary>
 ///
 /// <param name="name">The Name object whose fields are updated.</param>
 /// <param name="input">The input buffer to decode.  This reads from position() to limit(), but does not change the position.</param>
 /// <param name="copy">unchanged while the Blob values are used.</param>
 /// <exception cref="EncodingException">For invalid encoding.</exception>
 public override void decodeName(Name name, ByteBuffer input, bool copy)
 {
     TlvDecoder decoder = new TlvDecoder(input);
     decodeName(name, new int[1], new int[1], decoder, copy);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Decode input as an NDN-TLV LpPacket and set the fields of the lpPacket object.
        /// </summary>
        ///
        /// <param name="lpPacket">The LpPacket object whose fields are updated.</param>
        /// <param name="input"></param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException">For invalid encoding.</exception>
        public override void decodeLpPacket(LpPacket lpPacket, ByteBuffer input, bool copy)
        {
            lpPacket.clear();

            TlvDecoder decoder = new TlvDecoder(input);
            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.LpPacket_LpPacket);

            while (decoder.getOffset() < endOffset) {
                // Imitate TlvDecoder.readTypeAndLength.
                int fieldType = decoder.readVarNumber();
                int fieldLength = decoder.readVarNumber();
                int fieldEndOffset = decoder.getOffset() + fieldLength;
                if (fieldEndOffset > input.limit())
                    throw new EncodingException(
                            "TLV length exceeds the buffer length");

                if (fieldType == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_Fragment) {
                    // Set the fragment to the bytes of the TLV value.
                    lpPacket.setFragmentWireEncoding(new Blob(decoder.getSlice(
                            decoder.getOffset(), fieldEndOffset), copy));
                    decoder.seek(fieldEndOffset);

                    // The fragment is supposed to be the last field.
                    break;
                } else if (fieldType == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_Nack) {
                    NetworkNack networkNack = new NetworkNack();
                    int code = (int) decoder.readOptionalNonNegativeIntegerTlv(
                            net.named_data.jndn.encoding.tlv.Tlv.LpPacket_NackReason, fieldEndOffset);
                    // The enum numeric values are the same as this wire format, so use as is.
                    if (code < 0
                            || code == net.named_data.jndn.NetworkNack.Reason.NONE.getNumericType())
                        // This includes an omitted NackReason.
                        networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.NONE);
                    else if (code == net.named_data.jndn.NetworkNack.Reason.CONGESTION.getNumericType())
                        networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.CONGESTION);
                    else if (code == net.named_data.jndn.NetworkNack.Reason.DUPLICATE.getNumericType())
                        networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.DUPLICATE);
                    else if (code == net.named_data.jndn.NetworkNack.Reason.NO_ROUTE.getNumericType())
                        networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.NO_ROUTE);
                    else {
                        // Unrecognized reason.
                        networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.OTHER_CODE);
                        networkNack.setOtherReasonCode(code);
                    }

                    lpPacket.addHeaderField(networkNack);
                } else if (fieldType == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_IncomingFaceId) {
                    IncomingFaceId incomingFaceId = new IncomingFaceId();
                    incomingFaceId.setFaceId(decoder
                            .readNonNegativeInteger(fieldLength));
                    lpPacket.addHeaderField(incomingFaceId);
                } else {
                    // Unrecognized field type. The conditions for ignoring are here:
                    // http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
                    bool canIgnore = (fieldType >= net.named_data.jndn.encoding.tlv.Tlv.LpPacket_IGNORE_MIN
                            && fieldType <= net.named_data.jndn.encoding.tlv.Tlv.LpPacket_IGNORE_MAX && (fieldType & 0x01) == 1);
                    if (!canIgnore)
                        throw new EncodingException(
                                "Did not get the expected TLV type");

                    // Ignore.
                    decoder.seek(fieldEndOffset);
                }

                decoder.finishNestedTlvs(fieldEndOffset);
            }

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 11
0
        /// <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);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Decode input as a EncryptedContent in NDN-TLV and set the fields of the
        /// encryptedContent object.
        /// </summary>
        ///
        /// <param name="encryptedContent"></param>
        /// <param name="input"></param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException">For invalid encoding</exception>
        public override void decodeEncryptedContent(EncryptedContent encryptedContent,
				ByteBuffer input, bool copy)
        {
            TlvDecoder decoder = new TlvDecoder(input);
            int endOffset = decoder
                    .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_EncryptedContent);

            Tlv0_2WireFormat.decodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator,
                    encryptedContent.getKeyLocator(), decoder, copy);

            int algorithmType = (int) decoder
                    .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_EncryptionAlgorithm);
            if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesEcb.getNumericType())
                encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesEcb);
            else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc.getNumericType())
                encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc);
            else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs.getNumericType())
                encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs);
            else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep.getNumericType())
                encryptedContent.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep);
            else
                throw new EncodingException(
                        "Unrecognized EncryptionAlgorithm code " + algorithmType);

            encryptedContent.setInitialVector(new Blob(decoder.readOptionalBlobTlv(
                    net.named_data.jndn.encoding.tlv.Tlv.Encrypt_InitialVector, endOffset), copy));
            encryptedContent.setPayload(new Blob(decoder
                    .readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_EncryptedPayload), copy));

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Decode input as a sequence of NDN-TLV Delegation and set the fields of the
        /// delegationSet object. Note that the sequence of Delegation does not have an
        /// outer TLV type and length because it is intended to use the type and length
        /// of a Data packet's Content. This ignores any elements after the sequence
        /// of Delegation and before input.limit().
        /// </summary>
        ///
        /// <param name="delegationSet">The DelegationSet object whose fields are updated.</param>
        /// <param name="input"></param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException">For invalid encoding.</exception>
        public override void decodeDelegationSet(DelegationSet delegationSet,
				ByteBuffer input, bool copy)
        {
            TlvDecoder decoder = new TlvDecoder(input);
            int endOffset = input.limit();

            delegationSet.clear();
            while (decoder.getOffset() < endOffset) {
                decoder.readTypeAndLength(net.named_data.jndn.encoding.tlv.Tlv.Link_Delegation);
                int preference = (int) decoder
                        .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.Link_Preference);
                Name name = new Name();
                decodeName(name, new int[1], new int[1], decoder, copy);

                // Add unsorted to preserve the order so that Interest selected delegation
                // index will work.
                delegationSet.addUnsorted(preference, name);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Decode input as a data packet in NDN-TLV and set the fields in the data
        /// object.
        /// </summary>
        ///
        /// <param name="data">The Data object whose fields are updated.</param>
        /// <param name="input"></param>
        /// <param name="signedPortionBeginOffset">If you are not decoding in order to verify, you can call decodeData(data, input) to ignore this returned value.</param>
        /// <param name="signedPortionEndOffset">not decoding in order to verify, you can call decodeData(data, input) to ignore this returned value.</param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException">For invalid encoding.</exception>
        public override void decodeData(Data data, ByteBuffer input,
				int[] signedPortionBeginOffset, int[] signedPortionEndOffset,
				bool copy)
        {
            TlvDecoder decoder = new TlvDecoder(input);

            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Data);
            signedPortionBeginOffset[0] = decoder.getOffset();

            decodeName(data.getName(), new int[1], new int[1], decoder, copy);
            decodeMetaInfo(data.getMetaInfo(), decoder, copy);
            data.setContent(new Blob(decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Content), copy));
            decodeSignatureInfo(data, decoder, copy);

            signedPortionEndOffset[0] = decoder.getOffset();
            data.getSignature().setSignature(
                    new Blob(decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureValue), copy));

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// An internal method to encode signature as the appropriate form of
        /// SignatureInfo in NDN-TLV.
        /// </summary>
        ///
        /// <param name="signature">An object of a subclass of Signature to encode.</param>
        /// <param name="encoder">The TlvEncoder to receive the encoding.</param>
        private void encodeSignatureInfo(Signature signature, TlvEncoder encoder)
        {
            if (signature  is  GenericSignature) {
                // Handle GenericSignature separately since it has the entire encoding.
                Blob encoding = ((GenericSignature) signature)
                        .getSignatureInfoEncoding();

                // Do a test decoding to sanity check that it is valid TLV.
                try {
                    TlvDecoder decoder = new TlvDecoder(encoding.buf());
                    int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.SignatureInfo);
                    decoder.readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType);
                    decoder.finishNestedTlvs(endOffset);
                } catch (EncodingException ex) {
                    throw new Exception(
                            "The GenericSignature encoding is not a valid NDN-TLV SignatureInfo: "
                                    + ex.Message);
                }

                encoder.writeBuffer(encoding.buf());
                return;
            }

            int saveLength = encoder.getLength();

            // Encode backwards.
            if (signature  is  Sha256WithRsaSignature) {
                if (((Sha256WithRsaSignature) signature).getValidityPeriod()
                        .hasPeriod())
                    encodeValidityPeriod(
                            ((Sha256WithRsaSignature) signature)
                                    .getValidityPeriod(),
                            encoder);
                encodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator,
                        ((Sha256WithRsaSignature) signature).getKeyLocator(),
                        encoder);
                encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType,
                        net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureSha256WithRsa);
            } else if (signature  is  Sha256WithEcdsaSignature) {
                if (((Sha256WithEcdsaSignature) signature).getValidityPeriod()
                        .hasPeriod())
                    encodeValidityPeriod(
                            ((Sha256WithEcdsaSignature) signature)
                                    .getValidityPeriod(),
                            encoder);
                encodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator,
                        ((Sha256WithEcdsaSignature) signature).getKeyLocator(),
                        encoder);
                encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType,
                        net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureSha256WithEcdsa);
            } else if (signature  is  HmacWithSha256Signature) {
                encodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator,
                        ((HmacWithSha256Signature) signature).getKeyLocator(),
                        encoder);
                encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType,
                        net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureHmacWithSha256);
            } else if (signature  is  DigestSha256Signature)
                encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType,
                        net.named_data.jndn.encoding.tlv.Tlv.SignatureType_DigestSha256);
            else
                throw new Exception(
                        "encodeSignatureInfo: Unrecognized Signature object type");

            encoder.writeTypeAndLength(net.named_data.jndn.encoding.tlv.Tlv.SignatureInfo, encoder.getLength()
                    - saveLength);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Decode signatureInfo as an NDN-TLV signature info and signatureValue as the
        /// related NDN-TLV SignatureValue, and return a new object which is a subclass
        /// of Signature.
        /// </summary>
        ///
        /// <param name="signatureInfo"></param>
        /// <param name="signatureValue"></param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <returns>A new object which is a subclass of Signature.</returns>
        /// <exception cref="EncodingException">For invalid encoding.</exception>
        public override Signature decodeSignatureInfoAndValue(ByteBuffer signatureInfo,
				ByteBuffer signatureValue, bool copy)
        {
            // Use a SignatureHolder to imitate a Data object for _decodeSignatureInfo.
            Tlv0_2WireFormat.SimpleSignatureHolder  signatureHolder = new Tlv0_2WireFormat.SimpleSignatureHolder ();
            TlvDecoder decoder = new TlvDecoder(signatureInfo);
            decodeSignatureInfo(signatureHolder, decoder, copy);

            decoder = new TlvDecoder(signatureValue);
            signatureHolder.getSignature().setSignature(
                    new Blob(decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureValue), copy));

            return signatureHolder.getSignature();
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Decode the name component as NDN-TLV and return the component. This handles
        /// different component types such as ImplicitSha256DigestComponent.
        /// </summary>
        ///
        /// <param name="decoder">The decoder with the input to decode.</param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <returns>A new Name.Component.</returns>
        /// <exception cref="EncodingException"></exception>
        private static Name.Component decodeNameComponent(TlvDecoder decoder,
				bool copy)
        {
            int savePosition = decoder.getOffset();
            int type = decoder.readVarNumber();
            // Restore the position.
            decoder.seek(savePosition);

            Blob value_ren = new Blob(decoder.readBlobTlv(type), copy);
            if (type == net.named_data.jndn.encoding.tlv.Tlv.ImplicitSha256DigestComponent)
                return net.named_data.jndn.Name.Component.fromImplicitSha256Digest(value_ren);
            else
                return new Name.Component(value_ren);
        }
Ejemplo n.º 18
0
        private static void decodeControlParameters(
				ControlParameters controlParameters, TlvDecoder decoder,
				bool copy)
        {
            controlParameters.clear();

            int endOffset = decoder
                    .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_ControlParameters);

            // decode name
            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Name, endOffset)) {
                Name name = new Name();
                decodeName(name, new int[1], new int[1], decoder, copy);
                controlParameters.setName(name);
            }

            // decode face ID
            controlParameters.setFaceId((int) decoder
                    .readOptionalNonNegativeIntegerTlv(
                            net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_FaceId, endOffset));

            // decode URI
            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Uri, endOffset)) {
                // Set copy false since we just immediately get the string.
                Blob uri = new Blob(decoder.readOptionalBlobTlv(
                        net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Uri, endOffset), false);
                controlParameters.setUri("" + uri);
            }

            // decode integers
            controlParameters.setLocalControlFeature((int) decoder
                    .readOptionalNonNegativeIntegerTlv(
                            net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_LocalControlFeature, endOffset));
            controlParameters.setOrigin((int) decoder
                    .readOptionalNonNegativeIntegerTlv(
                            net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Origin, endOffset));
            controlParameters.setCost((int) decoder
                    .readOptionalNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Cost,
                            endOffset));

            // set forwarding flags
            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Flags, endOffset)) {
                ForwardingFlags flags = new ForwardingFlags();
                flags.setNfdForwardingFlags((int) decoder
                        .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Flags));
                controlParameters.setForwardingFlags(flags);
            }

            // decode strategy
            if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Strategy, endOffset)) {
                int strategyEndOffset = decoder
                        .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_Strategy);
                decodeName(controlParameters.getStrategy(), new int[1], new int[1],
                        decoder, copy);
                decoder.finishNestedTlvs(strategyEndOffset);
            }

            // decode expiration period
            controlParameters.setExpirationPeriod(decoder
                    .readOptionalNonNegativeIntegerTlv(
                            net.named_data.jndn.encoding.tlv.Tlv.ControlParameters_ExpirationPeriod, endOffset));

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 19
0
        private static void decodeSignatureInfo(SignatureHolder signatureHolder,
				TlvDecoder decoder, bool copy)
        {
            int beginOffset = decoder.getOffset();
            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.SignatureInfo);

            int signatureType = (int) decoder
                    .readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType);
            if (signatureType == net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureSha256WithRsa) {
                signatureHolder.setSignature(new Sha256WithRsaSignature());
                // Modify the holder's signature object because if we create an object
                //   and set it, then the holder will have to copy all the fields.
                Sha256WithRsaSignature signatureInfo = (Sha256WithRsaSignature) signatureHolder
                        .getSignature();
                decodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator, signatureInfo.getKeyLocator(),
                        decoder, copy);
                if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.ValidityPeriod_ValidityPeriod, endOffset))
                    decodeValidityPeriod(signatureInfo.getValidityPeriod(), decoder);
            } else if (signatureType == net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureSha256WithEcdsa) {
                signatureHolder.setSignature(new Sha256WithEcdsaSignature());
                Sha256WithEcdsaSignature signatureInfo_0 = (Sha256WithEcdsaSignature) signatureHolder
                        .getSignature();
                decodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator, signatureInfo_0.getKeyLocator(),
                        decoder, copy);
                if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.ValidityPeriod_ValidityPeriod, endOffset))
                    decodeValidityPeriod(signatureInfo_0.getValidityPeriod(), decoder);
            } else if (signatureType == net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureHmacWithSha256) {
                signatureHolder.setSignature(new HmacWithSha256Signature());
                HmacWithSha256Signature signatureInfo_1 = (HmacWithSha256Signature) signatureHolder
                        .getSignature();
                decodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator, signatureInfo_1.getKeyLocator(),
                        decoder, copy);
            } else if (signatureType == net.named_data.jndn.encoding.tlv.Tlv.SignatureType_DigestSha256)
                signatureHolder.setSignature(new DigestSha256Signature());
            else {
                signatureHolder.setSignature(new GenericSignature());
                GenericSignature signatureInfo_2 = (GenericSignature) signatureHolder
                        .getSignature();

                // Get the bytes of the SignatureInfo TLV.
                signatureInfo_2.setSignatureInfoEncoding(
                        new Blob(decoder.getSlice(beginOffset, endOffset), copy),
                        signatureType);
            }

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Decode input as a control parameters in NDN-TLV and set the fields of the
        /// controlParameters object.
        /// </summary>
        ///
        /// <param name="controlParameters"></param>
        /// <param name="input"></param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException">For invalid encoding</exception>
        public override void decodeControlParameters(ControlParameters controlParameters,
				ByteBuffer input, bool copy)
        {
            TlvDecoder decoder = new TlvDecoder(input);
            decodeControlParameters(controlParameters, decoder, copy);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Decode the input and update this Schedule object.
        /// </summary>
        ///
        /// <param name="input"></param>
        /// <exception cref="EncodingException">For invalid encoding.</exception>
        public void wireDecode(ByteBuffer input)
        {
            // For now, don't use WireFormat and hardcode to use TLV since the encoding
            // doesn't go out over the wire, only into the local SQL database.
            TlvDecoder decoder = new TlvDecoder(input);

            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_Schedule);

            // Decode the whiteIntervalList.
              		ILOG.J2CsMapping.Collections.Collections.Clear(whiteIntervalList_);
            int listEndOffset = decoder
                    .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_WhiteIntervalList);
            while (decoder.getOffset() < listEndOffset)
                ILOG.J2CsMapping.Collections.Collections.Add(whiteIntervalList_,decodeRepetitiveInterval(decoder));
            decoder.finishNestedTlvs(listEndOffset);

            // Decode the blackIntervalList.
            ILOG.J2CsMapping.Collections.Collections.Clear(blackIntervalList_);
            listEndOffset = decoder
                    .readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Encrypt_BlackIntervalList);
            while (decoder.getOffset() < listEndOffset)
                ILOG.J2CsMapping.Collections.Collections.Add(blackIntervalList_,decodeRepetitiveInterval(decoder));
            decoder.finishNestedTlvs(listEndOffset);

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 22
0
        private static void decodeExclude(Exclude exclude, TlvDecoder decoder,
				bool copy)
        {
            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Exclude);

            exclude.clear();
            while (decoder.getOffset() < endOffset) {
                if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Any, endOffset)) {
                    // Read past the Any TLV.
                    decoder.readBooleanTlv(net.named_data.jndn.encoding.tlv.Tlv.Any, endOffset);
                    exclude.appendAny();
                } else
                    exclude.appendComponent(decodeNameComponent(decoder, copy));
            }

            decoder.finishNestedTlvs(endOffset);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Continue scanning input starting from offset_ to find the element end.
        /// If the end of the element which started at offset 0 is found, this returns
        /// true and getOffset() is the length of the element.  Otherwise, this returns
        /// false which means you should read more into input and call again.
        /// </summary>
        ///
        /// <param name="input">You have to pass in input each time because the buffer could be reallocated.</param>
        /// <returns>true if found the element end, false if not.</returns>
        public bool findElementEnd(ByteBuffer input)
        {
            if (gotElementEnd_)
            {
                // Someone is calling when we already got the end.
                return(true);
            }

            TlvDecoder decoder = new TlvDecoder(input);

            while (true)
            {
                if (offset_ >= input.limit())
                {
                    // All the cases assume we have some input. Return and wait for more.
                    return(false);
                }

                if (state_ == TlvStructureDecoder.READ_TYPE)
                {
                    int firstOctet = (int)input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet < 253)
                    {
                        // The value is simple, so we can skip straight to reading the length.
                        state_ = TlvStructureDecoder.READ_LENGTH;
                    }
                    else
                    {
                        // Set up to skip the type bytes.
                        if (firstOctet == 253)
                        {
                            nBytesToRead_ = 2;
                        }
                        else if (firstOctet == 254)
                        {
                            nBytesToRead_ = 4;
                        }
                        else
                        {
                            // value == 255.
                            nBytesToRead_ = 8;
                        }

                        state_ = TlvStructureDecoder.READ_TYPE_BYTES;
                    }
                }
                else if (state_ == TlvStructureDecoder.READ_TYPE_BYTES)
                {
                    int nRemainingBytes = input.limit() - offset_;
                    if (nRemainingBytes < nBytesToRead_)
                    {
                        // Need more.
                        offset_       += nRemainingBytes;
                        nBytesToRead_ -= nRemainingBytes;
                        return(false);
                    }

                    // Got the type bytes. Move on to read the length.
                    offset_ += nBytesToRead_;
                    state_   = TlvStructureDecoder.READ_LENGTH;
                }
                else if (state_ == TlvStructureDecoder.READ_LENGTH)
                {
                    int firstOctet_0 = (int)input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet_0 < 253)
                    {
                        // The value is simple, so we can skip straight to reading
                        //  the value bytes.
                        nBytesToRead_ = firstOctet_0;
                        if (nBytesToRead_ == 0)
                        {
                            // No value bytes to read. We're finished.
                            gotElementEnd_ = true;
                            return(true);
                        }

                        state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                    }
                    else
                    {
                        // We need to read the bytes in the extended encoding of
                        //  the length.
                        if (firstOctet_0 == 253)
                        {
                            nBytesToRead_ = 2;
                        }
                        else if (firstOctet_0 == 254)
                        {
                            nBytesToRead_ = 4;
                        }
                        else
                        {
                            // value == 255.
                            nBytesToRead_ = 8;
                        }

                        // We need to use firstOctet in the next state.
                        firstOctet_ = firstOctet_0;
                        state_      = TlvStructureDecoder.READ_LENGTH_BYTES;
                    }
                }
                else if (state_ == TlvStructureDecoder.READ_LENGTH_BYTES)
                {
                    int nRemainingBytes_1 = input.limit() - offset_;
                    if (!useHeaderBuffer_ && nRemainingBytes_1 >= nBytesToRead_)
                    {
                        // We don't have to use the headerBuffer. Set nBytesToRead.
                        decoder.seek(offset_);

                        nBytesToRead_ = decoder.readExtendedVarNumber(firstOctet_);
                        // Update offset_ to the decoder's offset after reading.
                        offset_ = decoder.getOffset();
                    }
                    else
                    {
                        useHeaderBuffer_ = true;

                        int nNeededBytes = nBytesToRead_ - headerBuffer_.position();
                        if (nNeededBytes > nRemainingBytes_1)
                        {
                            // We can't get all of the header bytes from this input.
                            // Save in headerBuffer.
                            if (headerBuffer_.position() + nRemainingBytes_1 > headerBuffer_
                                .limit())
                            {
                                // We don't expect this to happen.
                                throw new Exception(
                                          "Cannot store more header bytes than the size of headerBuffer");
                            }
                            ByteBuffer remainingInput = input.duplicate();
                            remainingInput.position(offset_);
                            headerBuffer_.put(remainingInput);
                            offset_ += nRemainingBytes_1;

                            return(false);
                        }

                        // Copy the remaining bytes into headerBuffer, read the
                        //   length and set nBytesToRead.
                        if (headerBuffer_.position() + nNeededBytes > headerBuffer_
                            .limit())
                        {
                            // We don't expect this to happen.
                            throw new Exception(
                                      "Cannot store more header bytes than the size of headerBuffer");
                        }
                        ByteBuffer remainingLengthBytes = input.duplicate();
                        remainingLengthBytes.position(offset_);
                        remainingLengthBytes.limit(offset_ + nNeededBytes);
                        headerBuffer_.put(remainingLengthBytes);
                        offset_ += nNeededBytes;

                        // Use a local decoder just for the headerBuffer.
                        headerBuffer_.flip();
                        TlvDecoder bufferDecoder = new TlvDecoder(headerBuffer_);
                        // Replace nBytesToRead with the length of the value.
                        nBytesToRead_ = bufferDecoder
                                        .readExtendedVarNumber(firstOctet_);
                    }

                    if (nBytesToRead_ == 0)
                    {
                        // No value bytes to read. We're finished.
                        gotElementEnd_ = true;
                        return(true);
                    }

                    // Get ready to read the value bytes.
                    state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                }
                else if (state_ == TlvStructureDecoder.READ_VALUE_BYTES)
                {
                    int nRemainingBytes_2 = input.limit() - offset_;
                    if (nRemainingBytes_2 < nBytesToRead_)
                    {
                        // Need more.
                        offset_       += nRemainingBytes_2;
                        nBytesToRead_ -= nRemainingBytes_2;
                        return(false);
                    }

                    // Got the bytes. We're finished.
                    offset_       += nBytesToRead_;
                    gotElementEnd_ = true;
                    return(true);
                }
                else
                {
                    // We don't expect this to happen.
                    throw new Exception("findElementEnd: unrecognized state");
                }
            }
        }
Ejemplo n.º 24
0
        public void onReceivedElement(ByteBuffer element)
        {
            LpPacket lpPacket = null;
            if (element.get(0) == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_LpPacket) {
                // Decode the LpPacket and replace element with the fragment.
                lpPacket = new LpPacket();
                // Set copy false so that the fragment is a slice which will be copied below.
                // The header fields are all integers and don't need to be copied.
                net.named_data.jndn.encoding.TlvWireFormat.get().decodeLpPacket(lpPacket, element, false);
                element = lpPacket.getFragmentWireEncoding().buf();
            }

            // First, decode as Interest or Data.
            Interest interest = null;
            Data data = null;
            if (element.get(0) == net.named_data.jndn.encoding.tlv.Tlv.Interest || element.get(0) == net.named_data.jndn.encoding.tlv.Tlv.Data) {
                TlvDecoder decoder = new TlvDecoder(element);
                if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Interest, element.remaining())) {
                    interest = new Interest();
                    interest.wireDecode(element, net.named_data.jndn.encoding.TlvWireFormat.get());

                    if (lpPacket != null)
                        interest.setLpPacket(lpPacket);
                } else if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Data, element.remaining())) {
                    data = new Data();
                    data.wireDecode(element, net.named_data.jndn.encoding.TlvWireFormat.get());

                    if (lpPacket != null)
                        data.setLpPacket(lpPacket);
                }
            }

            if (lpPacket != null) {
                // We have decoded the fragment, so remove the wire encoding to save memory.
                lpPacket.setFragmentWireEncoding(new Blob());

                NetworkNack networkNack = net.named_data.jndn.NetworkNack.getFirstHeader(lpPacket);
                if (networkNack != null) {
                    if (interest == null)
                        // We got a Nack but not for an Interest, so drop the packet.
                        return;

                    ArrayList<PendingInterestTable.Entry> pitEntries = new ArrayList<PendingInterestTable.Entry>();
                    pendingInterestTable_.extractEntriesForNackInterest(interest,
                            pitEntries);
                    for (int i = 0; i < pitEntries.Count; ++i) {
                        PendingInterestTable.Entry pendingInterest = pitEntries[i];
                        try {
                            pendingInterest.getOnNetworkNack().onNetworkNack(
                                    pendingInterest.getInterest(), networkNack);
                        } catch (Exception ex) {
                            logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onNack", ex);
                        }
                    }

                    // We have processed the network Nack packet.
                    return;
                }
            }

            // Now process as Interest or Data.
            if (interest != null) {
                // Quickly lock and get all interest filter callbacks which match.
                ArrayList matchedFilters = new ArrayList();
                interestFilterTable_.getMatchedFilters(interest, matchedFilters);

                // The lock on interestFilterTable_ is released, so call the callbacks.
                for (int i_0 = 0; i_0 < matchedFilters.Count; ++i_0) {
                    InterestFilterTable.Entry entry = (InterestFilterTable.Entry) matchedFilters[i_0];
                    try {
                        entry.getOnInterest().onInterest(
                                entry.getFilter().getPrefix(), interest,
                                entry.getFace(), entry.getInterestFilterId(),
                                entry.getFilter());
                    } catch (Exception ex_1) {
                        logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterest", ex_1);
                    }
                }
            } else if (data != null) {
                ArrayList<PendingInterestTable.Entry> pitEntries_2 = new ArrayList<PendingInterestTable.Entry>();
                pendingInterestTable_.extractEntriesForExpressedInterest(data,
                        pitEntries_2);
                for (int i_3 = 0; i_3 < pitEntries_2.Count; ++i_3) {
                    PendingInterestTable.Entry pendingInterest_4 = pitEntries_2[i_3];
                    try {
                        pendingInterest_4.getOnData().onData(
                                pendingInterest_4.getInterest(), data);
                    } catch (Exception ex_5) {
                        logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onData", ex_5);
                    }
                }
            }
        }