static ndn_Error decodeMetaInfo(struct ndn_MetaInfo *metaInfo, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; int gotExpectedType; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_MetaInfo, &endOffset))) return error; int type; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv (decoder, ndn_Tlv_ContentType, endOffset, &type))) return error; if (type < 0 || type == ndn_ContentType_BLOB) // Default to BLOB if the value is omitted. metaInfo->type = ndn_ContentType_BLOB; else if (type == ndn_ContentType_LINK || type == ndn_ContentType_KEY || type == ndn_ContentType_NACK) // The ContentType enum is set up with the correct integer for each NDN-TLV ContentType. metaInfo->type = type; else { // Unrecognized content type. metaInfo->type = ndn_ContentType_OTHER_CODE; metaInfo->otherTypeCode = type; } if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlvAsDouble (decoder, ndn_Tlv_FreshnessPeriod, endOffset, &metaInfo->freshnessPeriod))) return error; if ((error = ndn_TlvDecoder_peekType (decoder, ndn_Tlv_FinalBlockId, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { size_t finalBlockIdEndOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_FinalBlockId, &finalBlockIdEndOffset))) return error; if ((error = ndn_decodeTlvNameComponent(&metaInfo->finalBlockId, decoder))) return error; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, finalBlockIdEndOffset))) return error; } else ndn_NameComponent_initialize(&metaInfo->finalBlockId, 0, 0); // Set fields not used by NDN-TLV to none. metaInfo->timestampMilliseconds = -1; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_decodeTlvData (struct ndn_Data *data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; size_t dummyBeginOffset, dummyEndOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_Data, &endOffset))) return error; *signedPortionBeginOffset = decoder->offset; if ((error = ndn_decodeTlvName (&data->name, &dummyBeginOffset, &dummyEndOffset, decoder))) return error; if ((error = decodeMetaInfo(&data->metaInfo, decoder))) return error; if ((error = ndn_TlvDecoder_readBlobTlv(decoder, ndn_Tlv_Content, &data->content))) return error; if ((error = ndn_decodeTlvSignatureInfo(&data->signature, decoder))) return error; *signedPortionEndOffset = decoder->offset; if ((error = ndn_TlvDecoder_readBlobTlv(decoder, ndn_Tlv_SignatureValue, &data->signature.signature))) return error; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_decodeTlvName (struct ndn_Name *name, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_Name, &endOffset))) return error; *signedPortionBeginOffset = decoder->offset; // In case there are no components, set signedPortionEndOffset arbitrarily. *signedPortionEndOffset = *signedPortionBeginOffset; name->nComponents = 0; while (decoder->offset < endOffset) { *signedPortionEndOffset = decoder->offset; // First append an empty component, then decode into it. if ((error = ndn_Name_appendComponent(name, 0, 0))) return error; if ((error = ndn_decodeTlvNameComponent (&name->components[name->nComponents - 1], decoder))) return error; } if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_decodeTlvDelegationSet_Delegation (struct ndn_DelegationSet_Delegation *delegation, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; size_t dummyBeginOffset, dummyEndOffset; uint64_t unsignedPreference; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_Link_Delegation, &endOffset))) return error; if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv (decoder, ndn_Tlv_Link_Preference, &unsignedPreference))) return error; delegation->preference = (int)unsignedPreference; if ((error = ndn_decodeTlvName (&delegation->name, &dummyBeginOffset, &dummyEndOffset, decoder))) return error; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_decodeTlvName (struct ndn_Name *name, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_Name, &endOffset))) return error; *signedPortionBeginOffset = decoder->offset; // In case there are no components, set signedPortionEndOffset arbitrarily. *signedPortionEndOffset = *signedPortionBeginOffset; name->nComponents = 0; while (decoder->offset < endOffset) { struct ndn_Blob component; *signedPortionEndOffset = decoder->offset; if ((error = ndn_TlvDecoder_readBlobTlv(decoder, ndn_Tlv_NameComponent, &component))) return error; if ((error = ndn_Name_appendBlob(name, &component))) return error; } if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
static ndn_Error decodeMetaInfo(struct ndn_MetaInfo *metaInfo, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; int gotExpectedType; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_MetaInfo, &endOffset))) return error; // The ContentType enum is set up with the correct integer for each NDN-TLV ContentType. if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv (decoder, ndn_Tlv_ContentType, endOffset, (int *)&metaInfo->type))) return error; if ((int)metaInfo->type < 0) // Set to the actual value for the default. metaInfo->type = ndn_ContentType_BLOB; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlvAsDouble (decoder, ndn_Tlv_FreshnessPeriod, endOffset, &metaInfo->freshnessPeriod))) return error; if ((error = ndn_TlvDecoder_peekType (decoder, ndn_Tlv_FinalBlockId, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { size_t finalBlockIdEndOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_FinalBlockId, &finalBlockIdEndOffset))) return error; if ((error = ndn_TlvDecoder_readBlobTlv (decoder, ndn_Tlv_NameComponent, &metaInfo->finalBlockId.value))) return error; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, finalBlockIdEndOffset))) return error; } else ndn_NameComponent_initialize(&metaInfo->finalBlockId, 0, 0); // Set fields not used by NDN-TLV to none. metaInfo->timestampMilliseconds = -1; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_decodeTlvSignatureInfo (struct ndn_Signature *signatureInfo, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t beginOffset; size_t endOffset; uint64_t signatureType; int gotExpectedType; ndn_Signature_clear(signatureInfo); beginOffset = decoder->offset; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_SignatureInfo, &endOffset))) return error; if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv (decoder, ndn_Tlv_SignatureType, &signatureType))) return error; if (signatureType == ndn_Tlv_SignatureType_SignatureSha256WithRsa || signatureType == ndn_Tlv_SignatureType_SignatureSha256WithEcdsa || signatureType == ndn_Tlv_SignatureType_SignatureHmacWithSha256) { // Assume that the ndn_SignatureType enum has the same values as the TLV // signature types. signatureInfo->type = signatureType; if ((error = ndn_decodeTlvKeyLocator (ndn_Tlv_KeyLocator, &signatureInfo->keyLocator, decoder))) return error; if ((error = ndn_TlvDecoder_peekType (decoder, ndn_Tlv_ValidityPeriod_ValidityPeriod, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { if ((error = decodeValidityPeriod(&signatureInfo->validityPeriod, decoder))) return error; } } else if (signatureType == ndn_Tlv_SignatureType_DigestSha256) signatureInfo->type = ndn_SignatureType_DigestSha256Signature; else { signatureInfo->type = ndn_SignatureType_Generic; signatureInfo->genericTypeCode = signatureType; // Get the bytes of the SignatureInfo TLV. if ((error = ndn_TlvDecoder_getSlice (decoder, beginOffset, endOffset, &signatureInfo->signatureInfoEncoding))) return error; } if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
static ndn_Error decodeSelectors(struct ndn_Interest *interest, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; int gotExpectedType; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_Selectors, &endOffset))) return error; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv (decoder, ndn_Tlv_MinSuffixComponents, endOffset, &interest->minSuffixComponents))) return error; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv (decoder, ndn_Tlv_MaxSuffixComponents, endOffset, &interest->maxSuffixComponents))) return error; if ((error = ndn_TlvDecoder_peekType (decoder, ndn_Tlv_PublisherPublicKeyLocator, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { if ((error = ndn_decodeTlvKeyLocator (ndn_Tlv_PublisherPublicKeyLocator, &interest->keyLocator, decoder))) return error; } else // Clear the key locator. ndn_KeyLocator_initialize(&interest->keyLocator, interest->keyLocator.keyName.components, interest->keyLocator.keyName.maxComponents); if ((error = ndn_TlvDecoder_peekType(decoder, ndn_Tlv_Exclude, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { if ((error = decodeExclude(&interest->exclude, decoder))) return error; } else interest->exclude.nEntries = 0; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv (decoder, ndn_Tlv_ChildSelector, endOffset, &interest->childSelector))) return error; if ((error = ndn_TlvDecoder_readBooleanTlv (decoder, ndn_Tlv_MustBeFresh, endOffset, &interest->mustBeFresh))) return error; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_decodeTlvKeyLocator (unsigned int expectedType, struct ndn_KeyLocator *keyLocator, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; int gotExpectedType; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, expectedType, &endOffset))) return error; ndn_KeyLocator_initialize (keyLocator, keyLocator->keyName.components, keyLocator->keyName.maxComponents); if (decoder->offset == endOffset) // The KeyLocator is omitted, so leave the fields as none. return NDN_ERROR_success; if ((error = ndn_TlvDecoder_peekType(decoder, ndn_Tlv_Name, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { size_t dummyBeginOffset, dummyEndOffset; // KeyLocator is a Name. if ((error = ndn_decodeTlvName (&keyLocator->keyName, &dummyBeginOffset, &dummyEndOffset, decoder))) return error; keyLocator->type = ndn_KeyLocatorType_KEYNAME; } else { if ((error = ndn_TlvDecoder_peekType(decoder, ndn_Tlv_KeyLocatorDigest, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { // KeyLocator is a KeyLocatorDigest. keyLocator->type = ndn_KeyLocatorType_KEY_LOCATOR_DIGEST; if ((error = ndn_TlvDecoder_readBlobTlv(decoder, ndn_Tlv_KeyLocatorDigest, &keyLocator->keyData))) return error; } else return NDN_ERROR_decodeKeyLocator_unrecognized_key_locator_type; } if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
static ndn_Error decodeValidityPeriod (struct ndn_ValidityPeriod *validityPeriod, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; // Expect a 15-character ISO string like "20131018T184139". const size_t isoStringMaxLength = 15; char isoString[isoStringMaxLength + 1]; struct ndn_Blob isoStringBlob; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_ValidityPeriod_ValidityPeriod, &endOffset))) return error; ndn_ValidityPeriod_clear(validityPeriod); // Decode notBefore as an ISO string. if ((error = ndn_TlvDecoder_readBlobTlv (decoder, ndn_Tlv_ValidityPeriod_NotBefore, &isoStringBlob))) return error; if (isoStringBlob.length > isoStringMaxLength) return NDN_ERROR_Calendar_time_value_out_of_range; ndn_memcpy((uint8_t *)isoString, isoStringBlob.value, isoStringBlob.length); isoString[isoStringBlob.length] = 0; if ((error = ndn_fromIsoString(isoString, &validityPeriod->notBefore))) return error; // Decode notAfter as an ISO string. if ((error = ndn_TlvDecoder_readBlobTlv (decoder, ndn_Tlv_ValidityPeriod_NotAfter, &isoStringBlob))) return error; if (isoStringBlob.length > isoStringMaxLength) return NDN_ERROR_Calendar_time_value_out_of_range; ndn_memcpy((uint8_t *)isoString, isoStringBlob.value, isoStringBlob.length); isoString[isoStringBlob.length] = 0; if ((error = ndn_fromIsoString(isoString, &validityPeriod->notAfter))) return error; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
static ndn_Error decodeExclude(struct ndn_Exclude *exclude, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_Exclude, &endOffset))) return error; exclude->nEntries = 0; while (decoder->offset < endOffset) { int gotExpectedTag; if ((error = ndn_TlvDecoder_peekType (decoder, ndn_Tlv_Any, endOffset, &gotExpectedTag))) return error; if (gotExpectedTag) { // Read past the Any TLV. int dummyValue; if ((error = ndn_TlvDecoder_readBooleanTlv (decoder, ndn_Tlv_Any, endOffset, &dummyValue))) return error; if ((error = ndn_Exclude_appendAny(exclude))) return error; } else { // First append an empty component, then decode into it. if ((error = ndn_Exclude_appendComponent(exclude, 0, 0))) return error; if ((error = ndn_decodeTlvNameComponent (&exclude->entries[exclude->nEntries - 1].component, decoder))) return error; exclude->entries[exclude->nEntries - 1].type = ndn_Exclude_COMPONENT; } } if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_decodeTlvControlResponse (struct ndn_ControlResponse *controlResponse, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; int gotExpectedType; uint64_t statusCode; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_NfdCommand_ControlResponse, &endOffset))) return error; if ((error = ndn_TlvDecoder_readNonNegativeIntegerTlv (decoder, ndn_Tlv_NfdCommand_StatusCode, &statusCode))) return error; controlResponse->statusCode = (int)statusCode; if ((error = ndn_TlvDecoder_readBlobTlv (decoder, ndn_Tlv_NfdCommand_StatusText, &controlResponse->statusText))) return error; // Decode the body. if ((error = ndn_TlvDecoder_peekType (decoder, ndn_Tlv_ControlParameters_ControlParameters, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { controlResponse->hasBodyAsControlParameters = 1; if ((error = ndn_decodeTlvControlParameters (&controlResponse->bodyAsControlParameters, decoder))) return error; } else controlResponse->hasBodyAsControlParameters = 0; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
ndn_Error ndn_encodeTlvSignatureInfo (const struct ndn_Signature *signatureInfo, struct ndn_TlvEncoder *encoder) { if (signatureInfo->type == ndn_SignatureType_Generic) { // Handle a Generic signature separately since it has the entire encoding. const struct ndn_Blob *encoding = &signatureInfo->signatureInfoEncoding; ndn_Error error; size_t endOffset; uint64_t signatureType; // Do a test decoding to sanity check that it is valid TLV. struct ndn_TlvDecoder decoder; ndn_TlvDecoder_initialize(&decoder, encoding->value, encoding->length); error = ndn_TlvDecoder_readNestedTlvsStart (&decoder, ndn_Tlv_SignatureInfo, &endOffset); if (!error) error = ndn_TlvDecoder_readNonNegativeIntegerTlv (&decoder, ndn_Tlv_SignatureType, &signatureType); if (!error) error = ndn_TlvDecoder_finishNestedTlvs(&decoder, endOffset); if (error) return NDN_ERROR_The_Generic_signature_encoding_is_not_a_valid_NDN_TLV_SignatureInfo; return ndn_TlvEncoder_writeArray(encoder, encoding->value, encoding->length); } if (signatureInfo->type == ndn_SignatureType_Sha256WithRsaSignature || signatureInfo->type == ndn_SignatureType_Sha256WithEcdsaSignature || signatureInfo->type == ndn_SignatureType_HmacWithSha256Signature) return ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_SignatureInfo, encodeSignatureWithKeyLocatorAndValidityPeriodValue, signatureInfo, 0); else if (signatureInfo->type == ndn_SignatureType_DigestSha256Signature) return ndn_TlvEncoder_writeNestedTlv (encoder, ndn_Tlv_SignatureInfo, encodeDigestSha256Value, signatureInfo, 0); else return NDN_ERROR_encodeSignatureInfo_unrecognized_SignatureType; }
ndn_Error ndn_decodeTlvLpPacket (struct ndn_LpPacket *lpPacket, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; ndn_LpPacket_clear(lpPacket); if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_LpPacket_LpPacket, &endOffset))) return error; while (decoder->offset < endOffset) { // Imitate ndn_TlvDecoder_readTypeAndLength. uint64_t fieldTypeVarNumber; int fieldType; uint64_t fieldLength; size_t fieldEndOffset; if ((error = ndn_TlvDecoder_readVarNumber(decoder, &fieldTypeVarNumber))) return error; fieldType = (int)fieldTypeVarNumber; if ((error = ndn_TlvDecoder_readVarNumber(decoder, &fieldLength))) return error; fieldEndOffset = decoder->offset + (size_t)fieldLength; if (fieldEndOffset > decoder->inputLength) return NDN_ERROR_TLV_length_exceeds_buffer_length; if (fieldType == ndn_Tlv_LpPacket_Fragment) { // Set the fragment to the bytes of the TLV value. if ((error = ndn_TlvDecoder_getSlice (decoder, decoder->offset, fieldEndOffset, &lpPacket->fragmentWireEncoding))) return error; ndn_TlvDecoder_seek(decoder, fieldEndOffset); // The fragment is supposed to be the last field. break; } else if (fieldType == ndn_Tlv_LpPacket_Nack) { struct ndn_NetworkNack *networkNack; int code; if ((error = ndn_NetworkNack_add(lpPacket, &networkNack))) return error; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv (decoder, ndn_Tlv_LpPacket_NackReason, fieldEndOffset, &code))) return error; // The enum numeric values are the same as this wire format, so use as is. if (code < 0 || code == ndn_NetworkNackReason_NONE) // This includes an omitted NackReason. networkNack->reason = ndn_NetworkNackReason_NONE; else if (code == ndn_NetworkNackReason_CONGESTION || code == ndn_NetworkNackReason_DUPLICATE || code == ndn_NetworkNackReason_NO_ROUTE) networkNack->reason = code; else { // Unrecognized reason. networkNack->reason = ndn_NetworkNackReason_OTHER_CODE; networkNack->otherReasonCode = code; } } else if (fieldType == ndn_Tlv_LpPacket_IncomingFaceId) { struct ndn_IncomingFaceId *incomingFaceId; if ((error = ndn_IncomingFaceId_add(lpPacket, &incomingFaceId))) return error; if ((error = ndn_TlvDecoder_readNonNegativeInteger (decoder, fieldLength, &incomingFaceId->faceId))) return error; } else { // Unrecognized field type. The conditions for ignoring are here: // http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2 int canIgnore = (fieldType >= ndn_Tlv_LpPacket_IGNORE_MIN && fieldType <= ndn_Tlv_LpPacket_IGNORE_MAX && (fieldType & 0x01) == 1); if (!canIgnore) return NDN_ERROR_did_not_get_the_expected_TLV_type; // Ignore. ndn_TlvDecoder_seek(decoder, fieldEndOffset); } if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, fieldEndOffset))) return error; } if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
static ndn_Error ndn_decodeTlvInterestV03 (struct ndn_Interest *interest, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; int canBePrefix, mustBeFresh; struct ndn_Blob dummyBlob; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_Interest, &endOffset))) return error; if ((error = ndn_decodeTlvName (&interest->name, signedPortionBeginOffset, signedPortionEndOffset, decoder))) return error; if ((error = ndn_TlvDecoder_readBooleanTlv (decoder, ndn_Tlv_CanBePrefix, endOffset, &canBePrefix))) return error; ndn_Interest_setCanBePrefix(interest, canBePrefix); if ((error = ndn_TlvDecoder_readBooleanTlv (decoder, ndn_Tlv_MustBeFresh, endOffset, &mustBeFresh))) return error; ndn_Interest_setMustBeFresh(interest, mustBeFresh); // Get the encoded sequence of delegations as is. if ((error = ndn_TlvDecoder_readOptionalBlobTlv (decoder, ndn_Tlv_ForwardingHint, endOffset, &interest->forwardingHintWireEncoding))) return error; if ((error = ndn_TlvDecoder_readOptionalBlobTlv (decoder, ndn_Tlv_Nonce, endOffset, &interest->nonce))) return error; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlvAsDouble (decoder, ndn_Tlv_InterestLifetime, endOffset, &interest->interestLifetimeMilliseconds))) return error; // Clear the unused fields. interest->minSuffixComponents = -1; ndn_KeyLocator_initialize (&interest->keyLocator, interest->keyLocator.keyName.components, interest->keyLocator.keyName.maxComponents); interest->exclude.nEntries = 0; interest->childSelector = -1; ndn_Blob_initialize(&interest->linkWireEncoding, 0, 0); interest->selectedDelegationIndex = -1; // Ignore the HopLimit and Parameters. if ((error = ndn_TlvDecoder_readOptionalBlobTlv (decoder, ndn_Tlv_HopLimit, endOffset, &dummyBlob))) return error; if ((error = ndn_TlvDecoder_readOptionalBlobTlv (decoder, ndn_Tlv_Parameters, endOffset, &dummyBlob))) return error; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }
static ndn_Error ndn_decodeTlvInterestV02 (struct ndn_Interest *interest, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvDecoder *decoder) { ndn_Error error; size_t endOffset; int gotExpectedType; if ((error = ndn_TlvDecoder_readNestedTlvsStart(decoder, ndn_Tlv_Interest, &endOffset))) return error; if ((error = ndn_decodeTlvName (&interest->name, signedPortionBeginOffset, signedPortionEndOffset, decoder))) return error; if ((error = ndn_TlvDecoder_peekType(decoder, ndn_Tlv_Selectors, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { if ((error = decodeSelectors(interest, decoder))) return error; } else { // Set selectors to none. interest->minSuffixComponents = -1; interest->maxSuffixComponents = -1; ndn_KeyLocator_initialize (&interest->keyLocator, interest->keyLocator.keyName.components, interest->keyLocator.keyName.maxComponents); interest->exclude.nEntries = 0; interest->childSelector = -1; interest->mustBeFresh = 0; } // Require a Nonce, but don't force it to be 4 bytes. if ((error = ndn_TlvDecoder_readBlobTlv(decoder, ndn_Tlv_Nonce, &interest->nonce))) return error; if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlvAsDouble (decoder, ndn_Tlv_InterestLifetime, endOffset, &interest->interestLifetimeMilliseconds))) return error; // Get the encoded sequence of delegations as is. if ((error = ndn_TlvDecoder_readOptionalBlobTlv (decoder, ndn_Tlv_ForwardingHint, endOffset, &interest->forwardingHintWireEncoding))) return error; if ((error = ndn_TlvDecoder_peekType(decoder, ndn_Tlv_Data, endOffset, &gotExpectedType))) return error; if (gotExpectedType) { // Get the bytes of the Link TLV. size_t linkBeginOffset = decoder->offset; size_t linkEndOffset; if ((error = ndn_TlvDecoder_readNestedTlvsStart (decoder, ndn_Tlv_Data, &linkEndOffset))) return error; ndn_TlvDecoder_seek(decoder, linkEndOffset); if ((error = ndn_TlvDecoder_getSlice (decoder, linkBeginOffset, linkEndOffset, &interest->linkWireEncoding))) return error; } else ndn_Blob_initialize(&interest->linkWireEncoding, 0, 0); if ((error = ndn_TlvDecoder_readOptionalNonNegativeIntegerTlv (decoder, ndn_Tlv_SelectedDelegation, endOffset, &interest->selectedDelegationIndex))) return error; if (interest->selectedDelegationIndex >= 0 && !interest->linkWireEncoding.value) return NDN_ERROR_Interest_has_a_selected_delegation_but_no_link_object; if ((error = ndn_TlvDecoder_finishNestedTlvs(decoder, endOffset))) return error; return NDN_ERROR_success; }