/** * This private function is called by ndn_TlvEncoder_writeNestedTlv to write the TLVs in the body of the Data value. * @param context This is the DataValueContext struct pointer which was passed to writeTlv. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeDataValue(const void *context, struct ndn_TlvEncoder *encoder) { const struct DataValueContext *dataValueContext = (const struct DataValueContext *)context; const struct ndn_Data *data = dataValueContext->data; ndn_Error error; size_t dummyBeginOffset, dummyEndOffset; *dataValueContext->signedPortionBeginOffset = encoder->offset; if ((error = ndn_encodeTlvName (&data->name, &dummyBeginOffset, &dummyEndOffset, encoder))) return error; if ((error = ndn_TlvEncoder_writeNestedTlv(encoder, ndn_Tlv_MetaInfo, encodeMetaInfoValue, &data->metaInfo, 0))) return error; if ((error = ndn_TlvEncoder_writeBlobTlv(encoder, ndn_Tlv_Content, &data->content))) return error; if ((error = ndn_encodeTlvSignatureInfo(&data->signature, encoder))) return error; *dataValueContext->signedPortionEndOffset = encoder->offset; if ((error = ndn_TlvEncoder_writeBlobTlv(encoder, ndn_Tlv_SignatureValue, &data->signature.signature))) return error; return NDN_ERROR_success; }
void writeBlobTlv(unsigned int type, struct ndn_Blob *value) { ndn_Error error; if ((error = ndn_TlvEncoder_writeBlobTlv(this, type, value))) throw std::runtime_error(ndn_getErrorString(error)); }
ndn_Error ndn_encodeTlvName (const struct ndn_Name *name, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset, struct ndn_TlvEncoder *encoder) { size_t nameValueLength = 0; size_t i; ndn_Error error; for (i = 0; i < name->nComponents; ++i) nameValueLength += ndn_TlvEncoder_sizeOfBlobTlv(ndn_Tlv_NameComponent, &name->components[i].value); if ((error = ndn_TlvEncoder_writeTypeAndLength(encoder, ndn_Tlv_Name, nameValueLength))) return error; *signedPortionBeginOffset = encoder->offset; if (name->nComponents == 0) // There is no "final component", so set signedPortionEndOffset arbitrarily. *signedPortionEndOffset = *signedPortionBeginOffset; else { for (i = 0; i < name->nComponents; ++i) { if (i == name->nComponents - 1) // We will begin the final component. *signedPortionEndOffset = encoder->offset; if ((error = ndn_TlvEncoder_writeBlobTlv (encoder, ndn_Tlv_NameComponent, &name->components[i].value))) return error; } } return NDN_ERROR_success; }
ndn_Error ndn_encodeTlvNameComponent (const struct ndn_NameComponent *component, struct ndn_TlvEncoder *encoder) { unsigned int type = ndn_NameComponent_isImplicitSha256Digest(component) ? ndn_Tlv_ImplicitSha256DigestComponent : ndn_Tlv_NameComponent; return ndn_TlvEncoder_writeBlobTlv(encoder, type, &component->value); }
ndn_Error ndn_Tlv0_2WireFormat_encodeSignatureValue (const struct ndn_Signature *signature, struct ndn_DynamicUInt8Array *output, size_t *encodingLength) { ndn_Error error; struct ndn_TlvEncoder encoder; ndn_TlvEncoder_initialize(&encoder, output); error = ndn_TlvEncoder_writeBlobTlv (&encoder, ndn_Tlv_SignatureValue, &signature->signature); *encodingLength = encoder.offset; return error; }
ndn_Error ndn_encodeTlvNameComponent (const struct ndn_NameComponent *component, struct ndn_TlvEncoder *encoder) { unsigned int type; if (component->type == ndn_NameComponentType_OTHER_CODE) { if (component->otherTypeCode < 0) return NDN_ERROR_Name_component_otherTypeCode_must_be_non_negative; type = (unsigned int)component->otherTypeCode; } else // The enum values are the same as the TLV type codes. type = (unsigned int)component->type; return ndn_TlvEncoder_writeBlobTlv(encoder, type, &component->value); }
/** * This private function is called by ndn_TlvEncoder_writeNestedTlv to write the TLVs * in the body of the ControlResponse value. * @param context This is the ndn_ControlResponse struct pointer which * was passed to writeTlv. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeControlResponseValue(const void *context, struct ndn_TlvEncoder *encoder) { struct ndn_ControlResponse *controlResponse = (struct ndn_ControlResponse *)context; ndn_Error error; struct ndn_ForwardingFlags defaultFlags; if ((error = ndn_TlvEncoder_writeNonNegativeIntegerTlv (encoder, ndn_Tlv_NfdCommand_StatusCode, controlResponse->statusCode))) return error; if ((error = ndn_TlvEncoder_writeBlobTlv (encoder, ndn_Tlv_NfdCommand_StatusText, &controlResponse->statusText))) return error; if (controlResponse->hasBodyAsControlParameters) { if ((error = ndn_encodeTlvControlParameters (&controlResponse->bodyAsControlParameters, encoder))) return error; } return NDN_ERROR_success; }
/** * This private function is called by ndn_TlvEncoder_writeTlv to write the TLVs in the body of the MetaInfo value. * @param context This is the ndn_MetaInfo struct pointer which was passed to writeTlv. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeMetaInfoValue(const void *context, struct ndn_TlvEncoder *encoder) { struct ndn_MetaInfo *metaInfo = (struct ndn_MetaInfo *)context; ndn_Error error; if (!((int)metaInfo->type < 0 || metaInfo->type == ndn_ContentType_BLOB)) { // Not the default, so we need to encode the type. if (metaInfo->type == ndn_ContentType_LINK || metaInfo->type == ndn_ContentType_KEY) { // The ContentType enum is set up with the correct integer for each NDN-TLV ContentType. if ((error = ndn_TlvEncoder_writeNonNegativeIntegerTlv (encoder, ndn_Tlv_ContentType, metaInfo->type))) return error; } else return NDN_ERROR_unrecognized_ndn_ContentType; } if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlvFromDouble (encoder, ndn_Tlv_FreshnessPeriod, metaInfo->freshnessPeriod))) return error; if (metaInfo->finalBlockId.value.value && metaInfo->finalBlockId.value.length > 0) { // The FinalBlockId has an inner NameComponent. if ((error = ndn_TlvEncoder_writeTypeAndLength (encoder, ndn_Tlv_FinalBlockId, ndn_TlvEncoder_sizeOfBlobTlv (ndn_Tlv_NameComponent, &metaInfo->finalBlockId.value)))) return error; if ((error = ndn_TlvEncoder_writeBlobTlv (encoder, ndn_Tlv_NameComponent, &metaInfo->finalBlockId.value))) return error; } return NDN_ERROR_success; }
ndn_Error ndn_encodeTlvKeyLocatorValue(const void *context, struct ndn_TlvEncoder *encoder) { struct ndn_KeyLocator *keyLocator = (struct ndn_KeyLocator *)context; ndn_Error error; if ((int)keyLocator->type < 0) return NDN_ERROR_success; if (keyLocator->type == ndn_KeyLocatorType_KEYNAME) { size_t dummyBeginOffset, dummyEndOffset; if ((error = ndn_encodeTlvName (&keyLocator->keyName, &dummyBeginOffset, &dummyEndOffset, encoder))) return error; } else if (keyLocator->type == ndn_KeyLocatorType_KEY_LOCATOR_DIGEST && keyLocator->keyData.length > 0) { if ((error = ndn_TlvEncoder_writeBlobTlv(encoder, ndn_Tlv_KeyLocatorDigest, &keyLocator->keyData))) return error; } else return NDN_ERROR_unrecognized_ndn_KeyLocatorType; return NDN_ERROR_success; }
/** * This private function is called by ndn_TlvEncoder_writeNestedTlv to write the TLVs in the body of the Interest value. * @param context This is the InterestValueContext struct pointer which was passed to writeTlv. * @param encoder the ndn_TlvEncoder which is calling this. * @return 0 for success, else an error code. */ static ndn_Error encodeInterestValue(const void *context, struct ndn_TlvEncoder *encoder) { const struct InterestValueContext *interestValueContext = (const struct InterestValueContext *)context; const struct ndn_Interest *interest = interestValueContext->interest; ndn_Error error; uint8_t nonceBuffer[4]; struct ndn_Blob nonceBlob; if ((error = ndn_encodeTlvName (&interest->name, interestValueContext->signedPortionBeginOffset, interestValueContext->signedPortionEndOffset, encoder))) return error; // For Selectors, set omitZeroLength true. if ((error = ndn_TlvEncoder_writeNestedTlv(encoder, ndn_Tlv_Selectors, encodeSelectorsValue, interest, 1))) return error; // Encode the Nonce as 4 bytes. nonceBlob.length = sizeof(nonceBuffer); if (interest->nonce.length == 0) { // Generate a random nonce. if ((error = ndn_generateRandomBytes(nonceBuffer, sizeof(nonceBuffer)))) return error; nonceBlob.value = nonceBuffer; } else if (interest->nonce.length < 4) { // TLV encoding requires 4 bytes, so pad out to 4 using random bytes. ndn_memcpy(nonceBuffer, interest->nonce.value, interest->nonce.length); if ((error = ndn_generateRandomBytes (nonceBuffer + interest->nonce.length, sizeof(nonceBuffer) - interest->nonce.length))) return error; nonceBlob.value = nonceBuffer; } else // TLV encoding requires 4 bytes, so truncate to 4. nonceBlob.value = interest->nonce.value; if ((error = ndn_TlvEncoder_writeBlobTlv(encoder, ndn_Tlv_Nonce, &nonceBlob))) return error; if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlvFromDouble (encoder, ndn_Tlv_InterestLifetime, interest->interestLifetimeMilliseconds))) return error; if (interest->forwardingHintWireEncoding.value && interest->forwardingHintWireEncoding.length > 0) { if (interest->selectedDelegationIndex >= 0) return NDN_ERROR_An_Interest_may_not_have_a_selected_delegation_when_encoding_a_forwarding_hint; if (interest->linkWireEncoding.value) return NDN_ERROR_An_Interest_may_not_have_a_link_object_when_encoding_a_forwarding_hint; // Add the encoded sequence of delegations as is. if ((error = ndn_TlvEncoder_writeBlobTlv (encoder, ndn_Tlv_ForwardingHint, &interest->forwardingHintWireEncoding))) return error; } if (interest->linkWireEncoding.value) { // Encode the entire link as is. if ((error = ndn_TlvEncoder_writeArray (encoder, interest->linkWireEncoding.value, interest->linkWireEncoding.length))) return error; } if ((error = ndn_TlvEncoder_writeOptionalNonNegativeIntegerTlv (encoder, ndn_Tlv_SelectedDelegation, interest->selectedDelegationIndex))) return error; return NDN_ERROR_success; }